void TaskBase::Run() { assert(_running == FALSE); _running = TRUE; char date[64]; time_t now = time(NULL) + S3_EXPIRES_TIMEOFFSET; strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now)); add_header("Date", date); _date = date; RunImp(); std::string auth_code = compose_auth_header(http_method(), _amz_data, uri(), _date, _content_type); add_header("Authorization", auth_code); singleton_ex<multi_http>::get_instance()->add_request(this); }
static void parse_request( void ) { char req[] = "GET /mah0x211/libhttp HTTP/1.1\r\n" "Host: github.com\r\n" "Connection: keep-alive\r\n" "Keep-Alive: 115\r\n" "Cache-Control: max-age=0\r\n" "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n" "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36\r\n" "Accept-Encoding: gzip, deflate, sdch\r\n" "Accept-Language: ja,en-US;q=0.8,en;q=0.6\r\n" "Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7\r\n" "Cookie: __utma=xxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.x; _octo=XXX.X.XXXXXXXX.XXXXXXXXXX; logged_in=XX; _ga=XXX.X.XXXXXXXXX.XXXXXXXXXX\r\n" "\r\n"; size_t len = sizeof( req ) + 1; uint64_t i = 0; int rc = 0; float start = 0, end = 0, elapsed = 0; uint16_t maxurilen = UINT16_MAX; uint16_t maxhdrlen = UINT16_MAX; uint8_t nheader = 20; http_t *r = http_alloc( nheader ); start = (float)clock()/CLOCKS_PER_SEC; for( i = 0; i < NLOOP; i++ ){ rc = http_req_parse( r, req, len, maxurilen, maxhdrlen ); assert( rc == HTTP_SUCCESS ); assert( http_method(r) == HTTP_MGET ); assert( http_version(r) == HTTP_V11 ); assert( r->nheader == 10 ); //keys( r, req ); http_init( r ); } end = (float)clock()/CLOCKS_PER_SEC; elapsed = end - start; http_free( r ); printf("\tElapsed %f seconds.\n", elapsed ); printf("\t%0.9f -> %f req/sec.\n", elapsed / NLOOP, 1.00000 / ( elapsed / NLOOP ) ); }
static inline int parse_request( lua_State *L, lhttp_t *h, char *buf, size_t len ) { http_t *r = h->r; int rc = 0; luaL_checktype( L, 2, LUA_TTABLE ); luaL_checktype( L, 3, LUA_TTABLE ); rc = http_req_parse( r, buf, len, h->maxurilen, h->maxhdrlen ); if( rc == HTTP_SUCCESS ) { uint8_t i = 0; uint8_t nheader = r->nheader; uintptr_t key = 0; uint16_t klen = 0; uintptr_t val = 0; uint16_t vlen = 0; // export to table lua_settop( L, 3 ); // add to header table for(; i < nheader; i++ ){ http_getheader_at( r, &key, &klen, &val, &vlen, i ); lstate_strll2tbl( L, buf + key, klen, buf + val, vlen ); } lua_pop( L, 1 ); lstate_num2tbl( L, "version", http_version( r ) ); lstate_num2tbl( L, "method", http_method( r ) ); lstate_strl2tbl( L, "uri", buf + r->msg, r->msglen ); // initialize http_init( r ); } // add status lua_pushinteger( L, rc ); return 1; }
void *http_process(void *args) { int32 fd; struct http_request *req; int8 *cp = NULL; int8 *line = NULL; int8 *method = NULL; int8 *url = NULL; int8 *protocol = NULL; struct timeval timo; int32 optval = 1; int32 rc, rc_r, rc_s; int32 r = 0; if (NULL == args) return NULL; req = (struct http_request *)args; fd = req->fd; req->buff = malloc(BUFFSIZ); req->buff_size = BUFFSIZ; if (NULL == req->buff) { HTTPD_ERR("get_request_line malloc %d fail\n", BUFFSIZ); free(args); return NULL; } memset(req->buff, 0, BUFFSIZ); rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)); if (rc < 0) HTTPD_ERR("setsockopt error rc=%d errno=%d %s\n", rc, errno, strerror(errno)); timo.tv_sec = HTTPD_TIMO; timo.tv_usec = 0; rc_r = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timo, sizeof(timo)); rc_s = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timo, sizeof(timo)); if (rc_r < 0 || rc_s < 0) HTTPD_ERR("setsockopt error fd=%d rc=%d rc_r=%d rc_s=%d errno=%d %s\n", fd, rc, rc_r, rc_s, errno, strerror(errno)); /* GET / HTTP/1.1 */ method = get_request_line(req); if (method == NULL) goto close_task; url = parse_reqline(fd, method); if (url == NULL) goto close_task; protocol = parse_reqline(fd, url); if (protocol == NULL) goto close_task; req->method = http_method(method); if (req->method == M_OPTIONS) { send_error(fd, 204, "No Content", NULL, "Method OPTIONS."); goto close_task; } if (req->method == M_UNKNOWN) { send_error(fd, 400, "Bad Request", NULL, "Method Not Support."); goto close_task; } decode_url(req, url); HTTPD_INFO("method[%s] protocol[%s] url[%s] path[%s] query[%s]!\n", method, protocol, url, req->path, req->query ? : ""); while ((line = get_request_line(req)) != NULL) { if (line[0] == '\0') break; if (strncasecmp(line, "Upgrade:", 8) == 0) { cp = &line[8]; cp += strspn(cp, " \t"); if (strncasecmp(cp, "websocket", 9) == 0) req->is_websocket = 1; } else if (strncasecmp(line, "Connection:", 11) == 0) { cp = &line[11]; cp += strspn(cp, " \t"); /* Firefox: [Connection: keep-alive, Upgrade] */ if (strcasestr(cp, "Upgrade") != NULL) req->is_connection_upgrade = 1; } else if (strncasecmp(line, "Sec-WebSocket-Key:", 18) == 0) { cp = &line[18]; cp += strspn(cp, " \t"); req->sec_websocket_key = cp; } else if (strncasecmp(line, "Origin:", 7) == 0) { cp = &line[7]; cp += strspn(cp, " \t"); req->origin = cp; } else if (strncasecmp(line, "Sec-WebSocket-Version:", 22) == 0) { cp = &line[22]; cp += strspn(cp, " \t"); req->sec_websocket_version = atoi(cp); } else if (strncasecmp(line, "Content-Length:", 15) == 0) { cp = &line[15]; cp += strspn(cp, " \t"); req->content_length = atol(cp); if ((BUFFSIZ < req->content_length + MAX_HEADER_LEN) && (req->buff_size != req->content_length + MAX_HEADER_LEN) + 1) { re_alloc_buff(req); memset(req->buff + BUFFSIZ, 0, req->buff_size - BUFFSIZ); } } else if (strncasecmp(line, "Content-Type:", 13) == 0) { cp = &line[13]; cp += strspn(cp, " \t"); req->content_type = cp; } else if (strncasecmp(line, "Host:", 5) == 0) { cp = &line[5]; cp += strspn(cp, " \t"); req->host = cp; } } HTTPD_INFO("Left %d bytes HTTP data with Content-Length: %ld req->sz[%d] req->pos[%d]\n", req->sz - req->pos, req->content_length, req->sz, req->pos); if (line == NULL || req->path[0] != '/') send_error(fd, 400, "Bad Request", NULL, "Bad Request!"); if ((0 != req->content_length) && (req->sz != req->hd_sz + req->content_length)) { while ((r = http_read(req->fd, req->buff + req->sz, req->buff_size - req->sz)) > 0) { req->sz += r; if (req->sz == req->hd_sz + req->content_length) break; } } if (req->is_websocket) ws_process(req); else { uint32 i = 0; int8 *file = NULL; int8 *path = req->path; int8 *pTmp = path; int8 prefix[PREFIX_LEN] = {0}; int8 new_link[MAX_URL + 8] = {0}; rmm_cfg_get_rest_prefix(prefix, PREFIX_LEN); /*snprintf(new_link, (MAX_URL + 8), "%s%s", prefix, "/rack");*/ snprintf_s_s(new_link, (MAX_URL + 8), "%s", prefix); /*TODO: move to correct place */ get_json_pointer(req); /* remove redundant '/' */ for (; *(path+i) != '\0'; i++) { if ((*(path+i) == '/') && (*(path+i+1) == '/')) continue; *pTmp++ = *(path+i); } *pTmp = '\0'; if ((path[1] == '\0') || (strncasecmp(path, new_link, strnlen_s(new_link, sizeof(new_link)-1)) == 0)) file = NULL; else file = path; if (file != NULL) send_file(req->fd, file); else rest_process(req); } close_task: close(fd); if (NULL != req->buff) { free(req->buff); req->buff = NULL; } HTTPD_INFO("\nrest_req_thread[%lld] exit, fd[%d], errno:%d %s\n", (uint64)(req->tid_rest_req), fd, errno, strerror(errno)); free(args); pthread_detach(pthread_self()); return NULL; }
ssize_t http_post (int fd, Http_destination *dest, size_t length) { return http_method (fd, dest, HTTP_POST, (ssize_t)length); }
ssize_t http_get (int fd, Http_destination *dest) { return http_method (fd, dest, HTTP_GET, -1); }