关闭

CEPH RGW处理请求过程

标签: cephrgw
1550人阅读 评论(1) 收藏 举报
分类:

Rgw处理请求过程

Rest api:
Put  /{bucket}  HTTP/1.1
x-amz-acl: public-read-write
Authorization: AWS {access}:{hash-of-header-and-secret}

这里依civetweb来提供rest服务来介绍,一个请求的处理过程。
回调函数的注册:
在civetweb中注册了用于处理请求的回调函数,在文件/rgw/rgw_main.cc中:

Class RGWMongooseFrontend::run(){
。。。
struct mg_callbacks cb;
    memset((void *)&cb, 0, sizeof(cb));
    cb.begin_request = civetweb_callback;
    cb.log_message = rgw_civetweb_log_callback;
    cb.log_access = rgw_civetweb_log_access_callback;
    ctx = mg_start(&cb, &env, (const char **)&options);
。。。
}

回调函数civetweb_callback()也定义在rgw_main.cc文件中:

static int civetweb_callback(struct mg_connection *conn) {
//提取request信息
  struct mg_request_info *req_info = mg_get_request_info(conn);
  RGWProcessEnv *pe = static_cast<RGWProcessEnv *>(req_info->user_data);
  RGWRados *store = pe->store;
  RGWREST *rest = pe->rest;
  OpsLogSocket *olog = pe->olog;
//构建rgw内部表示的request对象,即RGWRequest。
  RGWRequest *req = new RGWRequest(store->get_new_req_id());
  RGWMongoose client_io(conn, pe->port);
//进入request的处理流程
  int ret = process_request(store, rest, req, &client_io, olog);
  if (ret < 0) {
    /* we don't really care about return code */
    dout(20) << "process_request() returned " << ret << dendl;
  }

  delete req;

// Mark as processed
  return 1;
}

一个请求进入之后主要的处理流程都在process_request中:

static int process_request(RGWRados *store, RGWREST *rest, RGWRequest *req, RGWClientIO *client_io, OpsLogSocket *olog)

{
  int ret = 0;
// 初始化客户端,主要是从request info中取出请求头来,初始化client_io.env(RGWMongoose client_io(conn, pe->port);)
  client_io->init(g_ceph_context);
//初始化请求开始时间,及获取系统时间设置req中的时间变量ts
  req->log_init();

  dout(1) << "====== starting new request req=" << hex << req << dec << " =====" << dendl;
  //更新性能计数器,累加请求一次。
  perfcounter->inc(l_rgw_req);
//初始化执行环境,获取client_io的env来初始化,rgw_env)
  RGWEnv& rgw_env = client_io->get_env();
//存储用于完成完成请求的所有信息(Store all the state necessary to complete and respond to an HTTP request)
  struct req_state rstate(g_ceph_context, &rgw_env);

  struct req_state *s = &rstate;
//初始化rados上下文
  RGWObjectCtx rados_ctx(store, s);//rados_ctx.store=store;rados_ctx.user_ctx=s
  s->obj_ctx = &rados_ctx;
//初始化存储
  s->req_id = store->unique_id(req->id);
  s->trans_id = store->unique_trans_id(req->id);
//记录日志
  req->log_format(s, "initializing for trans_id = %s", s->trans_id.c_str());

  //初始化RGWOp *op
  RGWOp *op = NULL;
  int init_error = 0;
  bool should_log = false;
  RGWRESTMgr *mgr; //声明RGWRESTMgr对象

  //根据请求的url来选择对应的manager和该manager中的handler,(具体过程间handler的获取见[RGW处理请求中获取handler过程 ](http://blog.csdn.net/litianze99/article/details/49892753))
  RGWHandler *handler = rest->get_handler(store, s, client_io, &mgr, &init_error);
  if (init_error != 0) {
    abort_early(s, NULL, init_error);
    goto done;
  }

  should_log = mgr->get_logging();

  req->log(s, "getting op");
  op = handler->get_op(store);
  if (!op) {
    abort_early(s, NULL, -ERR_METHOD_NOT_ALLOWED);
    goto done;
  }
  req->op = op;
//检查请求中带的签名与本地服务端计算出的签名是否一致,判断请求是否合法详细过程见[ RGW中的请求的认证过程 ](http://blog.csdn.net/litianze99/article/details/49892813)
  req->log(s, "authorizing");
  ret = handler->authorize();
  if (ret < 0) {
    dout(10) << "failed to authorize request" << dendl;
    abort_early(s, op, ret);
    goto done;
  }
//判断用户是否被禁用,如果是则退出。
  if (s->user.suspended) {
    dout(10) << "user is suspended, uid=" << s->user.user_id << dendl;
    abort_early(s, op, -ERR_USER_SUSPENDED);
    goto done;
  }
  req->log(s, "reading permissions");
  ret = handler->read_permissions(op);
  if (ret < 0) {
    abort_early(s, op, ret);
    goto done;
  }

  req->log(s, "init op");

  ret = op->init_processing();
  if (ret < 0) {
    abort_early(s, op, ret);
    goto done;
  }

  req->log(s, "verifying op mask");
//验证op mask
  ret = op->verify_op_mask();
  if (ret < 0) {
    abort_early(s, op, ret);
    goto done;
  }

  req->log(s, "verifying op permissions");
  ret = op->verify_permission();
  if (ret < 0) {
    if (s->system_request) {
      dout(2) << "overriding permissions due to system operation" << dendl;
    } else {
      abort_early(s, op, ret);
      goto done;
    }
  }

  req->log(s, "verifying op params");
//验证op params
  ret = op->verify_params();
  if (ret < 0) {
    abort_early(s, op, ret);
    goto done;
  }

  req->log(s, "executing");
  op->pre_exec();
  //开始执行具体请求的操作
  op->execute();
  op->complete();
done:
//结束客户端请求
  int r = client_io->complete_request();
  if (r < 0) {
    dout(0) << "ERROR: client_io->complete_request() returned " << r << dendl;
  }
  if (should_log) {
    rgw_log_op(store, s, (op ? op->name() : "unknown"), olog);
  }

  int http_ret = s->err.http_ret;

  req->log_format(s, "http status=%d", http_ret);

  if (handler)
//回收op对象
handler->put_op(op);
  //回收handler对象
  rest->put_handler(handler);

  dout(1) << "====== req done req=" << hex << req << dec << " http_status=" << http_ret << " ======" << dendl;

  return (ret < 0 ? ret : s->err.ret);
}
1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:79057次
    • 积分:1784
    • 等级:
    • 排名:千里之外
    • 原创:101篇
    • 转载:3篇
    • 译文:2篇
    • 评论:9条
    文章分类
    最新评论