static int receive_http_response(int sock, char *buffer, size_t buffer_len, struct http_response_parts *parts) { int len = 0; int count; do { if ((count = read(sock, &buffer[len], buffer_len - len)) == -1) return WHYF_perror("read(%d, %p, %d)", sock, &buffer[len], buffer_len - len); len += count; } while (len < buffer_len && count != 0 && !http_header_complete(buffer, len, len)); if (debug & DEBUG_RHIZOME_RX) DEBUGF("Received HTTP response %s", alloca_toprint(-1, buffer, len)); if (unpack_http_response(buffer, parts) == -1) return -1; if (parts->code != 200 && parts->code != 201) { INFOF("Failed HTTP request: server returned %003u %s", parts->code, parts->reason); return -1; } if (parts->content_length == -1) { if (debug & DEBUG_RHIZOME_RX) DEBUGF("Invalid HTTP reply: missing Content-Length header"); return -1; } DEBUGF("content_length=%d", parts->content_length); return 0; }
void rhizome_client_poll(struct sched_ent *alarm) { rhizome_http_request *r = (rhizome_http_request *)alarm; if (alarm->poll.revents == 0){ rhizome_server_free_http_request(r); return; } switch(r->request_type) { case RHIZOME_HTTP_REQUEST_RECEIVING: /* Keep reading until we have two CR/LFs in a row */ r->request[r->request_length] = '\0'; sigPipeFlag=0; int bytes = read_nonblock(r->alarm.poll.fd, &r->request[r->request_length], RHIZOME_HTTP_REQUEST_MAXLEN - r->request_length); /* If we got some data, see if we have found the end of the HTTP request */ if (bytes > 0) { // reset inactivity timer r->alarm.alarm = gettime_ms() + RHIZOME_IDLE_TIMEOUT; r->alarm.deadline = r->alarm.alarm + RHIZOME_IDLE_TIMEOUT; unschedule(&r->alarm); schedule(&r->alarm); r->request_length += bytes; if (http_header_complete(r->request, r->request_length, bytes + 4)) { /* We have the request. Now parse it to see if we can respond to it */ rhizome_server_parse_http_request(r); } } else { if (debug & DEBUG_RHIZOME_TX) DEBUG("Empty read, closing connection"); rhizome_server_free_http_request(r); return; } if (sigPipeFlag) { if (debug & DEBUG_RHIZOME_TX) DEBUG("Received SIGPIPE, closing connection"); rhizome_server_free_http_request(r); return; } break; default: /* Socket already has request -- so just try to send some data. */ rhizome_server_http_send_bytes(r); break; } return; }
void handle_client(int socket) { initialize_routes(); req_header header; int recv_bytes; int total_recv; do { char buffer[5000] = {0}; recv_bytes = 0; total_recv=0; do { recv_bytes = recv(socket, buffer + total_recv, 5000, 0); if(recv_bytes == -1 || recv_bytes == 0) return; total_recv += recv_bytes ; }while(http_header_complete(buffer, total_recv) == -1); printf("%s", buffer); init_req_header(&header, buffer); printf("Connection : %s\n", header.connection); char * returnString = handle_request(&header); send_string(socket, returnString, strlen(returnString)); if(!strncmp(header.connection, "close", 5)){ return; } fflush(socket); }while( recv_bytes != 0 && recv_bytes != -1); /* TODO Loop receiving requests and sending appropriate responses, * until one of the conditions to close the connection is * met. */ }
void handle_client(int socket) { initialize_routes(); req_header header; int recv_bytes; int total_recv; while(1){ char buffer[5000] = {0}; recv_bytes = 0; total_recv=0; do { recv_bytes = recv(socket, buffer + total_recv, 5000, 0); if(recv_bytes == -1 || recv_bytes == 0) return; total_recv += recv_bytes ; }while(http_header_complete(buffer, total_recv) == -1); init_req_header(&header, buffer); char * returnString = handle_request(&header); printf("%s\n", returnString); int actlen = strlen(returnString); int send_length = send(socket, returnString, strlen(returnString), 0); //send_string(socket, returnString, strlen(returnString) + 2); //fflush(socket); if(!strncmp(header.connection, "close", 5)){ return; } } //}while(!strcmp(header.connection, "keep-alive")); //close(socket); /* TODO Loop receiving requests and sending appropriate responses, * until one of the conditions to close the connection is * met. */ return; }
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); }