/* One-by-one read lines terminated by CR-LF from the socket, and * parse the headers contained in them. */ int httpd_parse_hdr_tags(httpd_request_t *req, int sock, char *buffer, int len) { int req_line_len; int err; uint8_t done = 0; while (TRUE) { req_line_len = htsys_getln_soc(sock, buffer, len); if (req_line_len == -kInProgressErr) { httpd_d("Could not read line from socket"); return -kInProgressErr; } err = __httpd_parse_hdr_tags(buffer, req_line_len, req, &done); if (err != kNoErr) return err; if (done == 1) { if (req->agent.product[0] != 0) { /* Populate the diagnostics statistics variable * with the user agent string. Do not do * anything if the agent string is NULL * (http-client). This is required since this * code is used by http server as well as client * and we do not want the user agent diagnostics * variable to change during the client code * path */ /* Note that, currently wm_hd_useragent is * populated only for file handling requests and * HTTP POST requests and not for HTTP GET. This * is because, in GET requests we directly purge * all the headers without reading them and * hence do not populate the useragent */ // memcpy(&g_wm_stats.wm_hd_useragent, &req->agent, // sizeof(g_wm_stats.wm_hd_useragent)); // g_wm_stats.wm_hd_time = wmtime_time_get_posix(); } return kNoErr; } } }
/* Handle an incoming message (request) from the client. This is the * main processing function of the HTTPD. */ int httpd_handle_message(int conn) { int err; int req_line_len; char msg_in[128]; /* clear out the httpd_req structure */ memset(&httpd_req, 0x00, sizeof(httpd_req)); httpd_req.sock = conn; /* Read the first line of the HTTP header */ req_line_len = htsys_getln_soc(conn, msg_in, sizeof(msg_in)); if (req_line_len == 0) return HTTPD_DONE; if (req_line_len < 0) { httpd_e("Could not read from socket"); return -WM_FAIL; } /* Parse the first line of the header */ err = httpd_parse_hdr_main(msg_in, &httpd_req); if (err == -WM_E_HTTPD_NOTSUPP) /* Send 505 HTTP Version not supported */ return httpd_send_error(conn, HTTP_505); else if (err != WM_SUCCESS) { /* Send 500 Internal Server Error */ return httpd_send_error(conn, HTTP_500); } /* set a generic error that can be overridden by the wsgi handling. */ httpd_d("Presetting error to: "); httpd_set_error("wsgi handler failed"); /* Web Services Gateway Interface branch point: * At this point we have the request type (httpd_req.type) and the path * (httpd_req.filename) and all the headers waiting to be read from * the socket. * * The call bellow will iterate through all the url patterns and * invoke the handlers that match the request type and pattern. If * request type and url patern match, invoke the handler. */ err = httpd_wsgi(&httpd_req); if (err == HTTPD_DONE) { httpd_d("Done processing request."); return WM_SUCCESS; } else if (err == -WM_E_HTTPD_NO_HANDLER) { httpd_w("No handler for the given URL %s was found", httpd_req.filename); /* * We have not yet read the complete data from the current * request, from the socket. We are in an error state and * we wish to cancel this HTTP transaction. We sent * appropriate message to the client and read (flush) out * all the pending data in the socket. We let the client * close the socket for us, if necessary. */ httpd_purge_socket_data(&httpd_req, msg_in, sizeof(msg_in), conn); httpd_set_error("File %s not_found", httpd_req.filename); httpd_send_error(conn, HTTP_404); return WM_SUCCESS; } else { httpd_e("WSGI handler failed."); /* Send 500 Internal Server Error */ return httpd_send_error(conn, HTTP_500); } }