/*-------------------------------------------------- FUNCTION: httpc_send_header DESC: Sends the current header information stored in conn through conn->sock. ----------------------------------------------------*/ herror_t httpc_send_header(httpc_conn_t * conn) { hpair_t *walker; herror_t status; char buffer[1024]; for (walker = conn->header; walker; walker = walker->next) { if (walker->key && walker->value) { sprintf(buffer, "%s: %s\r\n", walker->key, walker->value); if ((status = hsocket_send(&(conn->sock), buffer)) != H_OK) return status; } } return hsocket_send(&(conn->sock), "\r\n"); }
herror_t httpd_send_header(httpd_conn_t * res, int code, const char *text) { struct tm stm; time_t nw; char buffer[255]; char header[1024]; hpair_t *cur; herror_t status; /* set status code */ sprintf(header, "HTTP/1.1 %d %s\r\n", code, text); /* set date */ nw = time(NULL); localtime_r(&nw, &stm); strftime(buffer, 255, "Date: %a, %d %b %Y %H:%M:%S GMT\r\n", &stm); strcat(header, buffer); /* set content-type */ /* * if (res->content_type[0] == '\0') { strcat(header, "Content-Type: * text/html\r\n"); } else { sprintf(buffer, "Content-Type: %s\r\n", * res->content_type); strcat(header, buffer); } */ /* set server name */ strcat(header, "Server: nanoHTTP library\r\n"); /* set _httpd_connection status */ /* strcat (header, "Connection: close\r\n"); */ /* add pairs */ for (cur = res->header; cur; cur = cur->next) { sprintf(buffer, "%s: %s\r\n", cur->key, cur->value); strcat(header, buffer); } /* set end of header */ strcat(header, "\r\n"); /* send header */ if ((status = hsocket_send(res->sock, header, strlen(header))) != H_OK) return status; res->out = http_output_stream_new(res->sock, res->header); return H_OK; }
/*-------------------------------------------------- FUNCTION: httpc_talk_to_server DESC: This function is the heart of the httpc module. It will send the request and process the response. Here the parameters: method: the request method. This can be HTTP_REQUEST_POST and HTTP_REQUEST_GET. conn: the connection object (created with httpc_new()) urlstr: the complete url in string format. http://<host>:<port>/<context> where <port> is not mendatory. start_cb: a callback function, which will be called when the response header is completely arrives. cb: a callback function, which will be called everytime when data arrives. content_size: size of content to send. (only if method is HTTP_REQUEST_POST) content: the content data to send. (only if method is HTTP_REQUEST_POST) userdata: a user define data, which will be passed to the start_cb and cb callbacks as a parameter. This can also be NULL. If success, this function will return 0. >0 otherwise. ----------------------------------------------------*/ static herror_t httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn, const char *urlstr) { hurl_t url; char buffer[4096]; herror_t status; int ssl; if (conn == NULL) { return herror_new("httpc_talk_to_server", GENERAL_INVALID_PARAM, "httpc_conn_t param is NULL"); } /* Build request header */ httpc_header_set_date(conn); if ((status = hurl_parse(&url, urlstr)) != H_OK) { log_error2("Can not parse URL '%s'", SAVE_STR(urlstr)); return status; } /* TODO (#1#): Check for HTTP protocol in URL */ /* Set hostname */ httpc_set_header(conn, HEADER_HOST, url.host); ssl = url.protocol == PROTOCOL_HTTPS ? 1 : 0; /* Open connection */ if ((status = hsocket_open(&conn->sock, url.host, url.port, ssl)) != H_OK) return status; switch(method) { case HTTP_REQUEST_GET: sprintf(buffer, "GET %s HTTP/%s\r\n", (url.context[0] != '\0') ? url.context : ("/"), (conn->version == HTTP_1_0) ? "1.0" : "1.1"); break; case HTTP_REQUEST_POST: sprintf(buffer, "POST %s HTTP/%s\r\n", (url.context[0] != '\0') ? url.context : ("/"), (conn->version == HTTP_1_0) ? "1.0" : "1.1"); break; default: log_error1("Unknown method type!"); return herror_new("httpc_talk_to_server", GENERAL_INVALID_PARAM, "hreq_method_t must be HTTP_REQUEST_GET or HTTP_REQUEST_POST"); } log_verbose1("Sending request..."); if ((status = hsocket_send(&(conn->sock), buffer)) != H_OK) { log_error2("Cannot send request (%s)", herror_message(status)); hsocket_close(&(conn->sock)); return status; } log_verbose1("Sending header..."); if ((status = httpc_send_header(conn)) != H_OK) { log_error2("Cannot send header (%s)", herror_message(status)); hsocket_close(&(conn->sock)); return status; } return H_OK; }