/** * @brief get_request_thr get the request's thread * * @param request the evhtp request * * @return the thread dealing with the request */ static evthr_t * get_request_thr(evhtp_request_t *request) { evhtp_connection_t * htpconn; evthr_t * thread; htpconn = evhtp_request_get_connection(request); thread = htpconn->thread; return thread; }
static void test_ownership(evhtp_request_t * request, void * arg) { evhtp_connection_t * conn = evhtp_request_get_connection(request); evbev_t * bev = evhtp_connection_take_ownership(conn); bufferevent_enable(bev, EV_READ); bufferevent_setcb(bev, _owned_readcb, NULL, _owned_eventcb, NULL); }
// get the thread that is handling the current request evthr_t* getRequestThread(evhtp_request_t * request) { evhtp_connection_t * htpconn; htpconn = evhtp_request_get_connection(request); if (htpconn) { evthr_t * thread; thread = htpconn->thread; return thread; } else { return nullptr; } }
static evhtp_res pause_request_fini(evhtp_request_t * request, void * arg) { struct pauser * pause = (struct pauser *)arg; printf("pause_request_fini() req=%p, c=%p status_code=%d::%s\n", request, evhtp_request_get_connection(request), evhtp_request_get_status_code(request), evhtp_request_get_status_code_str(request)); evhtp_safe_free(pause->timer_ev, event_free); evhtp_safe_free(pause->tv, free); evhtp_safe_free(pause, free); return EVHTP_RES_OK; }
static void wshtp_handler_cb(evhtp_request_t *req, void *data) { evhtp_connection_t *conn = evhtp_request_get_connection(req); wshtp_server_t *server = (wshtp_server_t*)data; wshtp_conn_t *_conn = (wshtp_conn_t*)avlmap_find(server->conns, (intptr_t)conn); wshtp_conn_set_request(_conn, req); if (req->method == htp_method_GET) { int ret = do_ws_handshake(req); if (ret == EVHTP_RES_SWITCH_PROTO) { _conn->is_websocket = true; evbev_t * bev = evhtp_connection_take_ownership(conn); evhtp_connection_set_bev(conn, bev); conn->owner = 1; bufferevent_enable(bev, EV_READ); bufferevent_setcb(bev, ws_read_cb, NULL, ws_event_cb, _conn); } else if (ret != EVHTP_RES_OK) { return; } _conn->method = WSHTP_ON_GET; } else if (req->method == htp_method_POST) { _conn->method = WSHTP_ON_POST; } else if (req->method == htp_method_PUT) { _conn->method = WSHTP_ON_PUT; } else if (req->method == htp_method_DELETE) { _conn->method = WSHTP_ON_DELETE; } if (_conn->is_open == false) { wshtp_hooks_call(server, WSHTP_ON_OPEN, _conn); _conn->is_open = true; } if (_conn->is_websocket == false && _conn->method) { wshtp_hooks_call(server, _conn->method, _conn); } }
/** * @brief get_request_cb The callback function of get a image request. * * @param req The request with a list of params and the md5 of image. * @param arg It is not useful. */ void get_request_cb(evhtp_request_t *req, void *arg) { char *md5 = NULL, *fmt = NULL, *type = NULL; zimg_req_t *zimg_req = NULL; char *buff = NULL; size_t len; evhtp_connection_t *ev_conn = evhtp_request_get_connection(req); struct sockaddr *saddr = ev_conn->saddr; struct sockaddr_in *ss = (struct sockaddr_in *)saddr; char address[16]; const char *xff_address = evhtp_header_find(req->headers_in, "X-Forwarded-For"); if(xff_address) { inet_aton(xff_address, &ss->sin_addr); } strncpy(address, inet_ntoa(ss->sin_addr), 16); int req_method = evhtp_request_get_method(req); if(req_method >= 16) req_method = 16; LOG_PRINT(LOG_DEBUG, "Method: %d", req_method); if(strcmp(method_strmap[req_method], "POST") == 0) { LOG_PRINT(LOG_DEBUG, "POST Request."); post_request_cb(req, NULL); return; } else if(strcmp(method_strmap[req_method], "GET") != 0) { LOG_PRINT(LOG_DEBUG, "Request Method Not Support."); LOG_PRINT(LOG_INFO, "%s refuse method", address); goto err; } if(settings.down_access != NULL) { int acs = zimg_access_inet(settings.down_access, ss->sin_addr.s_addr); LOG_PRINT(LOG_DEBUG, "access check: %d", acs); if(acs == ZIMG_FORBIDDEN) { LOG_PRINT(LOG_DEBUG, "check access: ip[%s] forbidden!", address); LOG_PRINT(LOG_INFO, "%s refuse get forbidden", address); goto forbidden; } else if(acs == ZIMG_ERROR) { LOG_PRINT(LOG_DEBUG, "check access: check ip[%s] failed!", address); LOG_PRINT(LOG_ERROR, "%s fail get access", address); goto err; } } const char *uri; uri = req->uri->path->full; if(strlen(uri) == 1 && uri[0] == '/') { LOG_PRINT(LOG_DEBUG, "Root Request."); int fd = -1; struct stat st; if((fd = open(settings.root_path, O_RDONLY)) == -1) { LOG_PRINT(LOG_DEBUG, "Root_page Open Failed. Return Default Page."); evbuffer_add_printf(req->buffer_out, "<html>\n<body>\n<h1>\nWelcome To zimg World!</h1>\n</body>\n</html>\n"); } else { if (fstat(fd, &st) < 0) { /* Make sure the length still matches, now that we * opened the file :/ */ LOG_PRINT(LOG_DEBUG, "Root_page Length fstat Failed. Return Default Page."); evbuffer_add_printf(req->buffer_out, "<html>\n<body>\n<h1>\nWelcome To zimg World!</h1>\n</body>\n</html>\n"); } else { evbuffer_add_file(req->buffer_out, fd, 0, st.st_size); } } //evbuffer_add_printf(req->buffer_out, "<html>\n </html>\n"); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1)); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0)); evhtp_send_reply(req, EVHTP_RES_OK); LOG_PRINT(LOG_DEBUG, "============get_request_cb() DONE!==============="); LOG_PRINT(LOG_INFO, "%s succ root page", address); goto done; } if(strstr(uri, "favicon.ico")) { LOG_PRINT(LOG_DEBUG, "favicon.ico Request, Denied."); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1)); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0)); zimg_headers_add(req, settings.headers); evhtp_send_reply(req, EVHTP_RES_OK); goto done; } LOG_PRINT(LOG_DEBUG, "Got a GET request for <%s>", uri); /* Don't allow any ".."s in the path, to avoid exposing stuff outside * of the docroot. This test is both overzealous and underzealous: * it forbids aceptable paths like "/this/one..here", but it doesn't * do anything to prevent symlink following." */ if (strstr(uri, "..")) { LOG_PRINT(LOG_DEBUG, "attempt to upper dir!"); LOG_PRINT(LOG_INFO, "%s refuse directory", address); goto forbidden; } size_t md5_len = strlen(uri) + 1; md5 = (char *)malloc(md5_len); if(md5 == NULL) { LOG_PRINT(LOG_DEBUG, "md5 malloc failed!"); LOG_PRINT(LOG_ERROR, "%s fail malloc", address); goto err; } if(uri[0] == '/') str_lcpy(md5, uri+1, md5_len); else str_lcpy(md5, uri, md5_len); LOG_PRINT(LOG_DEBUG, "md5 of request is <%s>", md5); if(is_md5(md5) == -1) { LOG_PRINT(LOG_DEBUG, "Url is Not a zimg Request."); LOG_PRINT(LOG_INFO, "%s refuse url illegal", address); goto err; } /* This holds the content we're sending. */ evthr_t *thread = get_request_thr(req); thr_arg_t *thr_arg = (thr_arg_t *)evthr_get_aux(thread); int width, height, proportion, gray, x, y, rotate, quality, sv; width = 0; height = 0; proportion = 1; gray = 0; x = -1; y = -1; rotate = 0; quality = 0; sv = 0; evhtp_kvs_t *params; params = req->uri->query; if(params != NULL) { if(settings.disable_args != 1) { const char *str_w = evhtp_kv_find(params, "w"); const char *str_h = evhtp_kv_find(params, "h"); width = (str_w) ? atoi(str_w) : 0; height = (str_h) ? atoi(str_h) : 0; const char *str_p = evhtp_kv_find(params, "p"); proportion = (str_p) ? atoi(str_p) : 1; const char *str_g = evhtp_kv_find(params, "g"); gray = (str_g) ? atoi(str_g) : 0; const char *str_x = evhtp_kv_find(params, "x"); const char *str_y = evhtp_kv_find(params, "y"); x = (str_x) ? atoi(str_x) : -1; y = (str_y) ? atoi(str_y) : -1; if(x != -1 || y != -1) { proportion = 1; } const char *str_r = evhtp_kv_find(params, "r"); rotate = (str_r) ? atoi(str_r) : 0; const char *str_q = evhtp_kv_find(params, "q"); quality = (str_q) ? atoi(str_q) : 0; const char *str_f = evhtp_kv_find(params, "f"); if(str_f) { size_t fmt_len = strlen(str_f) + 1; fmt = (char *)malloc(fmt_len); if(fmt != NULL) str_lcpy(fmt, str_f, fmt_len); LOG_PRINT(LOG_DEBUG, "fmt = %s", fmt); } } if(settings.disable_type != 1) { const char *str_t = evhtp_kv_find(params, "t"); if(str_t) { size_t type_len = strlen(str_t) + 1; type = (char *)malloc(type_len); if(type != NULL) str_lcpy(type, str_t, type_len); LOG_PRINT(LOG_DEBUG, "type = %s", type); } } } else { sv = 1; } quality = (quality != 0 ? quality : settings.quality); zimg_req = (zimg_req_t *)malloc(sizeof(zimg_req_t)); if(zimg_req == NULL) { LOG_PRINT(LOG_DEBUG, "zimg_req malloc failed!"); LOG_PRINT(LOG_ERROR, "%s fail malloc", address); goto err; } zimg_req -> md5 = md5; zimg_req -> type = type; zimg_req -> width = width; zimg_req -> height = height; zimg_req -> proportion = proportion; zimg_req -> gray = gray; zimg_req -> x = x; zimg_req -> y = y; zimg_req -> rotate = rotate; zimg_req -> quality = quality; zimg_req -> fmt = (fmt != NULL ? fmt : settings.format); zimg_req -> sv = sv; zimg_req -> thr_arg = thr_arg; int get_img_rst = -1; get_img_rst = settings.get_img(zimg_req, req); if(get_img_rst == -1) { LOG_PRINT(LOG_DEBUG, "zimg Requset Get Image[MD5: %s] Failed!", zimg_req->md5); if(type) LOG_PRINT(LOG_ERROR, "%s fail pic:%s t:%s", address, md5, type); else LOG_PRINT(LOG_ERROR, "%s fail pic:%s w:%d h:%d p:%d g:%d x:%d y:%d r:%d q:%d f:%s", address, md5, width, height, proportion, gray, x, y, rotate, quality, zimg_req->fmt); goto err; } if(get_img_rst == 2) { LOG_PRINT(LOG_DEBUG, "Etag Matched Return 304 EVHTP_RES_NOTMOD."); if(type) LOG_PRINT(LOG_INFO, "%s succ 304 pic:%s t:%s", address, md5, type); else LOG_PRINT(LOG_INFO, "%s succ 304 pic:%s w:%d h:%d p:%d g:%d x:%d y:%d r:%d q:%d f:%s", address, md5, width, height, proportion, gray, x, y, rotate, quality, zimg_req->fmt); evhtp_send_reply(req, EVHTP_RES_NOTMOD); goto done; } len = evbuffer_get_length(req->buffer_out); LOG_PRINT(LOG_DEBUG, "get buffer length: %d", len); LOG_PRINT(LOG_DEBUG, "Got the File!"); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1)); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "image/jpeg", 0, 0)); zimg_headers_add(req, settings.headers); evhtp_send_reply(req, EVHTP_RES_OK); if(type) LOG_PRINT(LOG_INFO, "%s succ pic:%s t:%s size:%d", address, md5, type, len); else LOG_PRINT(LOG_INFO, "%s succ pic:%s w:%d h:%d p:%d g:%d x:%d y:%d r:%d q:%d f:%s size:%d", address, md5, width, height, proportion, gray, x, y, rotate, quality, zimg_req->fmt, len); LOG_PRINT(LOG_DEBUG, "============get_request_cb() DONE!==============="); goto done; forbidden: evbuffer_add_printf(req->buffer_out, "<html><body><h1>403 Forbidden!</h1></body></html>"); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1)); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0)); evhtp_send_reply(req, EVHTP_RES_FORBIDDEN); LOG_PRINT(LOG_DEBUG, "============get_request_cb() FORBIDDEN!==============="); goto done; err: evbuffer_add_printf(req->buffer_out, "<html><body><h1>404 Not Found!</h1></body></html>"); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1)); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0)); evhtp_send_reply(req, EVHTP_RES_NOTFOUND); LOG_PRINT(LOG_DEBUG, "============get_request_cb() ERROR!==============="); done: free(fmt); free(md5); free(type); free(zimg_req); free(buff); }
/** * @brief post_request_cb The callback function of a POST request to upload a image. * * @param req The request with image buffer. * @param arg It is not useful. */ void post_request_cb(evhtp_request_t *req, void *arg) { int post_size = 0; char *buff = NULL; int err_no = 0; int ret_json = 1; evhtp_connection_t *ev_conn = evhtp_request_get_connection(req); struct sockaddr *saddr = ev_conn->saddr; struct sockaddr_in *ss = (struct sockaddr_in *)saddr; char address[16]; const char *xff_address = evhtp_header_find(req->headers_in, "X-Forwarded-For"); if(xff_address) { inet_aton(xff_address, &ss->sin_addr); } strncpy(address, inet_ntoa(ss->sin_addr), 16); int req_method = evhtp_request_get_method(req); if(req_method >= 16) req_method = 16; LOG_PRINT(LOG_DEBUG, "Method: %d", req_method); if(strcmp(method_strmap[req_method], "POST") != 0) { LOG_PRINT(LOG_DEBUG, "Request Method Not Support."); LOG_PRINT(LOG_INFO, "%s refuse post method", address); err_no = 2; goto err; } if(settings.up_access != NULL) { int acs = zimg_access_inet(settings.up_access, ss->sin_addr.s_addr); LOG_PRINT(LOG_DEBUG, "access check: %d", acs); if(acs == ZIMG_FORBIDDEN) { LOG_PRINT(LOG_DEBUG, "check access: ip[%s] forbidden!", address); LOG_PRINT(LOG_INFO, "%s refuse post forbidden", address); err_no = 3; goto forbidden; } else if(acs == ZIMG_ERROR) { LOG_PRINT(LOG_DEBUG, "check access: check ip[%s] failed!", address); LOG_PRINT(LOG_ERROR, "%s fail post access %s", address); err_no = 0; goto err; } } const char *content_len = evhtp_header_find(req->headers_in, "Content-Length"); if(!content_len) { LOG_PRINT(LOG_DEBUG, "Get Content-Length error!"); LOG_PRINT(LOG_ERROR, "%s fail post content-length", address); err_no = 5; goto err; } post_size = atoi(content_len); if(post_size <= 0) { LOG_PRINT(LOG_DEBUG, "Image Size is Zero!"); LOG_PRINT(LOG_ERROR, "%s fail post empty", address); err_no = 5; goto err; } if(post_size > settings.max_size) { LOG_PRINT(LOG_DEBUG, "Image Size Too Large!"); LOG_PRINT(LOG_ERROR, "%s fail post large", address); err_no = 7; goto err; } const char *content_type = evhtp_header_find(req->headers_in, "Content-Type"); if(!content_type) { LOG_PRINT(LOG_DEBUG, "Get Content-Type error!"); LOG_PRINT(LOG_ERROR, "%s fail post content-type", address); err_no = 6; goto err; } evbuf_t *buf; buf = req->buffer_in; buff = (char *)malloc(post_size); if(buff == NULL) { LOG_PRINT(LOG_DEBUG, "buff malloc failed!"); LOG_PRINT(LOG_ERROR, "%s fail malloc buff", address); err_no = 0; goto err; } int rmblen, evblen; if(evbuffer_get_length(buf) <= 0) { LOG_PRINT(LOG_DEBUG, "Empty Request!"); LOG_PRINT(LOG_ERROR, "%s fail post empty", address); err_no = 4; goto err; } while((evblen = evbuffer_get_length(buf)) > 0) { LOG_PRINT(LOG_DEBUG, "evblen = %d", evblen); rmblen = evbuffer_remove(buf, buff, evblen); LOG_PRINT(LOG_DEBUG, "rmblen = %d", rmblen); if(rmblen < 0) { LOG_PRINT(LOG_DEBUG, "evbuffer_remove failed!"); LOG_PRINT(LOG_ERROR, "%s fail post parse", address); err_no = 4; goto err; } } if(strstr(content_type, "multipart/form-data") == NULL) { err_no = binary_parse(req, content_type, address, buff, post_size); } else { ret_json = 0; err_no = multipart_parse(req, content_type, address, buff, post_size); } if(err_no != -1) { goto err; } evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1)); evhtp_send_reply(req, EVHTP_RES_OK); LOG_PRINT(LOG_DEBUG, "============post_request_cb() DONE!==============="); goto done; forbidden: json_return(req, err_no, NULL, 0); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1)); evhtp_send_reply(req, EVHTP_RES_OK); LOG_PRINT(LOG_DEBUG, "============post_request_cb() FORBIDDEN!==============="); goto done; err: if(ret_json == 0) { evbuffer_add_printf(req->buffer_out, "<h1>Upload Failed!</h1></body></html>"); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0)); } else { json_return(req, err_no, NULL, 0); } evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1)); evhtp_send_reply(req, EVHTP_RES_OK); LOG_PRINT(LOG_DEBUG, "============post_request_cb() ERROR!==============="); done: free(buff); }
/** * @brief admin_request_cb the callback function of admin requests * * @param req the evhtp request * @param arg the arg of request */ void admin_request_cb(evhtp_request_t *req, void *arg) { char md5[33]; evhtp_connection_t *ev_conn = evhtp_request_get_connection(req); struct sockaddr *saddr = ev_conn->saddr; struct sockaddr_in *ss = (struct sockaddr_in *)saddr; char address[16]; const char *xff_address = evhtp_header_find(req->headers_in, "X-Forwarded-For"); if(xff_address) { inet_aton(xff_address, &ss->sin_addr); } strncpy(address, inet_ntoa(ss->sin_addr), 16); int req_method = evhtp_request_get_method(req); if(req_method >= 16) req_method = 16; LOG_PRINT(LOG_DEBUG, "Method: %d", req_method); if(strcmp(method_strmap[req_method], "POST") == 0) { LOG_PRINT(LOG_DEBUG, "POST Request."); post_request_cb(req, NULL); return; } else if(strcmp(method_strmap[req_method], "GET") != 0) { LOG_PRINT(LOG_DEBUG, "Request Method Not Support."); LOG_PRINT(LOG_INFO, "%s refuse method", address); goto err; } if(settings.admin_access != NULL) { int acs = zimg_access_inet(settings.admin_access, ss->sin_addr.s_addr); LOG_PRINT(LOG_DEBUG, "access check: %d", acs); if(acs == ZIMG_FORBIDDEN) { LOG_PRINT(LOG_DEBUG, "check access: ip[%s] forbidden!", address); LOG_PRINT(LOG_INFO, "%s refuse admin forbidden", address); goto forbidden; } else if(acs == ZIMG_ERROR) { LOG_PRINT(LOG_DEBUG, "check access: check ip[%s] failed!", address); LOG_PRINT(LOG_ERROR, "%s fail admin access", address); goto err; } } const char *uri; uri = req->uri->path->full; if(strstr(uri, "favicon.ico")) { LOG_PRINT(LOG_DEBUG, "favicon.ico Request, Denied."); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1)); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0)); zimg_headers_add(req, settings.headers); evhtp_send_reply(req, EVHTP_RES_OK); return; } LOG_PRINT(LOG_DEBUG, "Got a Admin request for <%s>", uri); int t; evhtp_kvs_t *params; params = req->uri->query; if(!params) { LOG_PRINT(LOG_DEBUG, "Admin Root Request."); int fd = -1; struct stat st; //TODO: use admin_path if((fd = open(settings.admin_path, O_RDONLY)) == -1) { LOG_PRINT(LOG_DEBUG, "Admin_page Open Failed. Return Default Page."); evbuffer_add_printf(req->buffer_out, "<html>\n<body>\n<h1>\nWelcome To zimg Admin!</h1>\n</body>\n</html>\n"); } else { if (fstat(fd, &st) < 0) { /* Make sure the length still matches, now that we * opened the file :/ */ LOG_PRINT(LOG_DEBUG, "Root_page Length fstat Failed. Return Default Page."); evbuffer_add_printf(req->buffer_out, "<html>\n<body>\n<h1>\nWelcome To zimg Admin!</h1>\n</body>\n</html>\n"); } else { evbuffer_add_file(req->buffer_out, fd, 0, st.st_size); } } //evbuffer_add_printf(req->buffer_out, "<html>\n </html>\n"); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1)); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0)); evhtp_send_reply(req, EVHTP_RES_OK); LOG_PRINT(LOG_DEBUG, "============admin_request_cb() DONE!==============="); LOG_PRINT(LOG_INFO, "%s succ admin root page", address); return; } else { const char *str_md5, *str_t; str_md5 = evhtp_kv_find(params, "md5"); if(str_md5 == NULL) { LOG_PRINT(LOG_DEBUG, "md5() = NULL return"); goto err; } str_lcpy(md5, str_md5, sizeof(md5)); if(is_md5(md5) == -1) { LOG_PRINT(LOG_DEBUG, "Admin Request MD5 Error."); LOG_PRINT(LOG_INFO, "%s refuse admin url illegal", address); goto err; } str_t = evhtp_kv_find(params, "t"); LOG_PRINT(LOG_DEBUG, "md5() = %s; t() = %s;", str_md5, str_t); t = (str_t) ? atoi(str_t) : 0; } evthr_t *thread = get_request_thr(req); thr_arg_t *thr_arg = (thr_arg_t *)evthr_get_aux(thread); int admin_img_rst = -1; admin_img_rst = settings.admin_img(req, thr_arg, md5, t); if(admin_img_rst == -1) { evbuffer_add_printf(req->buffer_out, "<html><body><h1>Admin Command Failed!</h1> \ <p>MD5: %s</p> \ <p>Command Type: %d</p> \ <p>Command Failed.</p> \ </body></html>", md5, t); LOG_PRINT(LOG_ERROR, "%s fail admin pic:%s t:%d", address, md5, t); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0)); }
struct request_mngr_s * create_request_mngr_from_evhtp_request_with_arg(evhtp_request_t *req, void *arg, const char *context) { struct request_mngr_s *request_mngr; if (!req) return NULL; /* Request administration object */ request_mngr = calloc(sizeof(struct request_mngr_s), 1); if (request_mngr == NULL) { syslog(LOG_ERR, "[%s][pid:%lu][threadid:%lu]" "[msg=Error: out of memory]", context, (uint64_t)getpid(), pthread_self() ); return NULL; } request_mngr->mf_sock = malloc(sizeof(mf_sock_address_t)); if (request_mngr->mf_sock == NULL) { syslog(LOG_ERR, "[%s][pid:%lu][threadid:%lu]" "[msg=Error: out of memory]", context, (uint64_t)getpid(), pthread_self() ); return NULL; } /* Request administration */ request_mngr->paused = NO; request_mngr->evhtp_req = req; request_mngr->conn = req ? evhtp_request_get_connection(req) : NULL; request_mngr->evhtp_thr = request_mngr->evhtp_req ? get_request_thr(request_mngr->evhtp_req) : NULL; request_mngr->service = arg ? (struct tq_service_s *)arg : NULL; request_mngr->listener = request_mngr->service ? request_mngr->service->parent_listener : NULL; request_mngr->app = request_mngr->listener ? request_mngr->listener->app_thr : NULL; request_mngr->pthr = pthread_self(); request_mngr->pid = (uint64_t)getpid(); request_mngr->accept_type = mimetype_normalizer_int(request_mngr->evhtp_req, "Accept"); request_mngr->accept_header = mimetype_normalizer_str(request_mngr->accept_type); request_mngr->content_type = mimetype_normalizer_int(request_mngr->evhtp_req, "Content-Type"); request_mngr->contenttype_header = mimetype_normalizer_str(request_mngr->content_type); request_mngr->xacml_req = NULL; request_mngr->xacml_res = NULL; request_mngr->mf_sock->sa = request_mngr->conn->saddr; if (request_mngr->mf_sock->sa_stor->ss_family == AF_INET6) { request_mngr->sin_port = request_mngr->mf_sock ? ntohs(request_mngr->mf_sock->sa_in6->sin6_port) : 0; } else { request_mngr->sin_port = request_mngr->mf_sock ? ntohs(request_mngr->mf_sock->sa_in->sin_port) : 0; } /* Normalizing flawed input for human readable strings */ if (request_mngr->accept_header == NULL) request_mngr->accept_header = "<empty Accept>"; if (request_mngr->contenttype_header == NULL) request_mngr->contenttype_header = "<empty Content-Type>"; /* Copy the IP address */ request_mngr->sin_ip_addr = calloc(GA_HTTP_IP_ADDRESS_LEN, 1); if (request_mngr->sin_ip_addr == NULL) { syslog(LOG_ERR, "[%s][pid:%lu][threadid:%lu]" "[error=out of memory]", context, request_mngr->pid, request_mngr->pthr); goto cleanup; } /* Extract the source IP */ if (request_mngr->mf_sock->sa_stor->ss_family == AF_INET6) { evutil_inet_ntop(request_mngr->mf_sock->sa_stor->ss_family, &(request_mngr->mf_sock->sa_in6->sin6_addr), request_mngr->sin_ip_addr, GA_HTTP_IP_ADDRESS_LEN); } else { evutil_inet_ntop(request_mngr->mf_sock->sa_stor->ss_family, &(request_mngr->mf_sock->sa_in->sin_addr), request_mngr->sin_ip_addr, GA_HTTP_IP_ADDRESS_LEN); } return request_mngr; cleanup: delete_request_mngr(request_mngr); return NULL; }