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(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);
}