int main(void) { char req[] = "Post /test?name=value&name2=value2 HTTP/1.1\r\n" "Content-Length: 12345\r\n" "Host: www.example.com \r\n" "Pragma: no-cache\r\n" "Accept-Encoding: text/plain\r\n" "\r\nTHIS_IS_THE_BODY"; int len = strlen(req); printf("Body: %s\n", http_parse_body(req, len)); printf("Method: %d (%s)\n", http_parse_method(req), http_method_str[http_parse_method(req)]); printf("URI: '%s' (path is '%s')\n", http_parse_uri(req), http_parse_path(http_parse_uri(req))); printf("Pragma: '%s'\n", http_parse_header_field(req, len, "Pragma")); printf("Content-length: '%s'\n", http_parse_header_field(req, len, "Content-length")); printf("Accept-Encoding: '%s'\n", http_parse_header_field(req, len, "Accept-Encoding")); printf("Host: '%s'\n", http_parse_header_field(req, len, "Host")); printf("Body: %s\n", http_parse_body(req, len)); printf("Method: %d (%s)\n", http_parse_method(req), http_method_str[http_parse_method(req)]); printf("URI: '%s' (path is '%s')\n", http_parse_uri(req), http_parse_path(http_parse_uri(req))); printf("Pragma: '%s'\n", http_parse_header_field(req, len, "Pragma")); printf("Content-length: '%s'\n", http_parse_header_field(req, len, "Content-length")); printf("Accept-Encoding: '%s'\n", http_parse_header_field(req, len, "Accept-Encoding")); printf("Host: '%s'\n", http_parse_header_field(req, len, "Host")); return 0; }
int do_http_parse_test(http_t *p_http, char *buf , int len) { local_t* local = http_get_local_t(p_http); int head_len = 0,ret = 0; if (local->state == 4){ ret=http_parse_body(buf,len,p_http); } head_len = s_http_parse(buf,len,p_http); if (local->state < 4) { DBGH("state is < 4 ,header is not end\n"); return -1; } else if (local->state == 4) { ret = http_parse_head(buf,head_len,0,p_http,0); ret = http_parse_body(buf+head_len,len-head_len,p_http); } else { DBGH("state = %d error \n", local->state); } // ret=http_parse_body(buf+head_len,1,p_http); // http_dump_logic(p_http); // http_dump_int(p_http); // http_dump_str(p_http); //http_dump_arg(p_http); return 0; }
/* * If the HTTP header found in the first 'length' bytes of 'request' * is a complete HTTP header (i.e. contains an empty line indicating * end of header), returns the size of this header (in * bytes). Otherwise, returns -1. This function supports both requests * with LF only and with CR-LF. This function is only expected to be * called during the request retrieval process, and should not be used * after a parse function has been called, since parse functions * change the request in a way that changes the behaviour of this * function. */ int http_header_complete(const char *request, int length) { const char *body = http_parse_body(request, length); if (body && !memchr(request, '\0', body - request)) return body - request; else return -1; }
void init_req_header(req_header * req, char * header){ int len = strlen(header); req->body = http_parse_body(header, len); req->method = http_parse_method((char *) header); req->uri = http_parse_uri(header); req->path = http_parse_path(http_parse_uri(header)); cookie * cookies = parse_cookies(header); req->cookies = cookies; req->connection = http_parse_header_field(header, len, "Connection"); }
void init_req_header(req_header * req, char * header){ char * cookie_header = malloc(strlen(header)); strcpy(cookie_header, header); int len = strlen(header); req->body = http_parse_body(header, len); req->method = http_parse_method((char *) header); req->uri = http_parse_uri(header); req->path = http_parse_path(http_parse_uri(header)); req->connection = http_parse_header_field( header, len, "Connection"); req->cache_control = http_parse_header_field(header, len, "Cache-Control"); cookie * cookies = parse_cookies(cookie_header, &(req->num_cookies)); req->cookies = cookies; }
void handle_client(int socket) { node *cookie, *param; service cmd; http_method method; http_response resp; int bytes, s, expected_len, header_len; char req[BUFFER_SIZE], buf[BUFFER_SIZE]; const char *path; char *connection, *req_body_len; time_t since_time; /* TODO Loop receiving requests and sending appropriate responses, * until one of the conditions to close the connection is * met. */ cookie = param = resp.expire = resp.cookie = NULL; do { // New request free_list(resp.cookie); free_list(resp.expire); if (cookie) free_list(cookie); if (param) free_list(param); cookie = param = NULL; memset(&resp, 0, sizeof(http_response)); memset(req, 0, BUFFER_SIZE); bytes = 0; // Wait for HTTP header to complete do { bytes += recv(socket, req + bytes, BUFFER_SIZE, 0); header_len = http_header_complete(req, bytes); } while (header_len == -1); // Receive body if there is content length if (strstr(req, HDR_CONTENT_LEN)) { strcpy(buf, req); req_body_len = get_header_value_from_req(buf, HDR_CONTENT_LEN); expected_len = atoi(req_body_len) + header_len; while (bytes < expected_len) { bytes += recv(socket, req + bytes, BUFFER_SIZE, 0); } } // printf("recv %i bytes\n", bytes); // Get HTTP method method = http_parse_method(req); // Get path strcpy(buf, req); path = http_parse_path(http_parse_uri(buf)); // printf("Request: %s\n", path); // Parse cookies if (strstr(req, HDR_COOKIE)) { strcpy(buf, req); cookie = get_cookies_from_header(get_header_value_from_req(buf, HDR_COOKIE)); } else { cookie = NULL; } // Match service command cmd = SERV_UNKNOWN; for (s= 0; s < SERV_UNKNOWN; s++) { if (strncasecmp(path, service_str[s], strlen(service_str[s])) == 0) { cmd = s; break; } } // Handle command switch(cmd) { case SERV_KNOCK: case SERV_LOGIN: case SERV_LOGOUT: case SERV_GETFILE: case SERV_ADDCART: case SERV_DELCART: case SERV_CHECKOUT: if (method == METHOD_GET) { param = get_params_from_query(get_query_str_from_path(path)); if (cmd == SERV_KNOCK) { knock_handler(&resp, cookie); } else if (cmd == SERV_LOGIN) { login_handler(&resp, param); } else if (cmd == SERV_LOGOUT) { logout_handler(&resp, cookie); } else if (cmd == SERV_GETFILE) { since_time = 0; strcpy(buf, req); if (strstr(buf, HDR_IF_MOD_SINCE)) { if (!RFC_822_to_time(strstr(buf, HDR_IF_MOD_SINCE) + strlen(HDR_IF_MOD_SINCE), &since_time)) { since_time = 0; } } getfile_handler(&resp, param, since_time); } else if (cmd == SERV_ADDCART) { addcart_handler(&resp, param, cookie); } else if (cmd == SERV_DELCART) { delcart_handler(&resp, param, cookie); } else if (cmd == SERV_CHECKOUT) { checkout_handler(&resp, cookie); } else { resp.status = NOT_FOUND; } } else { resp.allow = METHOD_GET; resp.status = METHOD_NOT_ALLOWED; } break; case SERV_PUTFILE: if (method == METHOD_POST) { strcpy(buf, req); param = get_params_from_query((char*) http_parse_body(buf, bytes)); putfile_handler(&resp, cookie, param); } else { resp.allow = METHOD_POST; resp.status = METHOD_NOT_ALLOWED; } break; default: resp.status = NOT_FOUND; break; } // Check if status not ok or // client wants to close connection after completing request if (resp.status != OK) { resp.connection = CLOSE; } else if (strstr(req, "Connection:")) { connection = http_parse_header_field(buf, bytes, "Connection"); if (strcmp(connection, "close") == 0) { resp.connection = CLOSE; } } send_response(socket, &resp); } while (resp.connection != CLOSE); }
int http_parse(int fd, struct http_request *r) { int recvd; static char command[HTTP_BUFFER_LEN + 1]; char *i; int newline_machine = 0; char *linestart; char *bodystart; static char linebuf[HTTP_LINE_LEN + 1]; int linenum; if ((recvd = read(fd, (void*)command, HTTP_BUFFER_LEN)) < 0) { if (errno == EAGAIN) { printf("Eagain\n"); return recvd; } perror("recvfrom"); exit(1); } if ((recvd == 1 && *((char*)command) == '\0') || (recvd == 0)) { return 0; } command[HTTP_BUFFER_LEN] = '\0'; linenum = 0; linestart = command; for (i = command; *i; ++i) { switch (newline_machine) { case 0: case 2: { if (*i == '\r') newline_machine++; else newline_machine = 0; } break; case 1: { if (*i == '\n') newline_machine++; else newline_machine = 0; } break; case 3: { if (*i == '\n') newline_machine++; else newline_machine = 0; } break; default: { newline_machine = 0; } } if (newline_machine == 2) { int linelength = i - linestart; linelength = linelength < HTTP_LINE_LEN ? linelength : HTTP_LINE_LEN; strncpy(linebuf, linestart, i - linestart); linebuf[HTTP_LINE_LEN] = '\0'; if (linenum == 0) { if (http_parse_status(r, linebuf) < 0) { printf("Estatus\n"); return -1; } } else { if (http_parse_header(r, linebuf) < 0) { printf("Eheader\n"); return -1; } } linestart = i + 1; linenum++; } if (newline_machine == 4) { bodystart = i + 1; if (http_parse_body(r, bodystart) < 0) { printf("Ebody\n"); return -1; } linenum++; break; } } return 0; }