diff options
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | nanohttp/nanohttp-client.c | 47 | ||||
-rw-r--r-- | nanohttp/nanohttp-server.c | 141 |
3 files changed, 100 insertions, 91 deletions
@@ -1,4 +1,4 @@ -$Id: TODO,v 1.13 2006/12/18 09:41:14 m0gg Exp $ +$Id: TODO,v 1.14 2007/01/01 15:29:48 m0gg Exp $ =============================================================================== Things to do _before_ 1.2 release: @@ -19,6 +19,7 @@ nanohttp: csoap: ------ +- Map corrent HTTP status codes in soap_server_process (404, 500, etc.) - Re-enable WSDL via HTTP GET - move service description documents from router to service (???) - Check portability to Win32/Linux/MaxOS (only tested on FreeBSD 6.2) diff --git a/nanohttp/nanohttp-client.c b/nanohttp/nanohttp-client.c index 6f740e9..00bf7c7 100644 --- a/nanohttp/nanohttp-client.c +++ b/nanohttp/nanohttp-client.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-client.c,v 1.51 2006/12/10 19:21:06 m0gg Exp $ +* $Id: nanohttp-client.c,v 1.52 2007/01/01 15:29:48 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -303,13 +303,14 @@ httpc_send_header(httpc_conn_t * conn) hpair_t *walker; herror_t status; char buffer[1024]; + int len; 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_string(conn->sock, buffer)) != H_OK) + len = snprintf(buffer, 1024, "%s: %s\r\n", walker->key, walker->value); + if ((status = hsocket_send(conn->sock, buffer, len)) != H_OK) return status; } } @@ -367,6 +368,7 @@ _httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn, const char *url { char buffer[4096]; herror_t status; + int len; int ssl; if (conn == NULL) @@ -401,16 +403,16 @@ _httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn, const char *url { case HTTP_REQUEST_GET: - sprintf(buffer, "GET %s HTTP/%s\r\n", - (conn->url->context[0] != '\0') ? conn->url->context : ("/"), - (conn->version == HTTP_1_0) ? "1.0" : "1.1"); + len = sprintf(buffer, "GET %s HTTP/%s\r\n", + (conn->url->context[0] != '\0') ? conn->url->context : ("/"), + (conn->version == HTTP_1_0) ? "1.0" : "1.1"); break; case HTTP_REQUEST_POST: - sprintf(buffer, "POST %s HTTP/%s\r\n", - (conn->url->context[0] != '\0') ? conn->url->context : ("/"), - (conn->version == HTTP_1_0) ? "1.0" : "1.1"); + len = sprintf(buffer, "POST %s HTTP/%s\r\n", + (conn->url->context[0] != '\0') ? conn->url->context : ("/"), + (conn->version == HTTP_1_0) ? "1.0" : "1.1"); break; default: @@ -421,7 +423,7 @@ _httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn, const char *url } log_verbose1("Sending request..."); - if ((status = hsocket_send_string(conn->sock, buffer)) != H_OK) + if ((status = hsocket_send(conn->sock, buffer, len)) != H_OK) { log_error2("Cannot send request (%s)", herror_message(status)); hsocket_close(conn->sock); @@ -556,42 +558,39 @@ httpc_mime_next(httpc_conn_t * conn, const char *content_id, const char *content herror_t status; char buffer[512]; char boundary[75]; + int len; /* Get the boundary string */ _httpc_mime_get_boundary(conn, boundary); - sprintf(buffer, "\r\n--%s\r\n", boundary); + len = sprintf(buffer, "\r\n--%s\r\n", boundary); /* Send boundary */ - status = http_output_stream_write(conn->out, buffer, strlen(buffer)); - - if (status != H_OK) + if ((status = http_output_stream_write(conn->out, buffer, len)) != H_OK) return status; /* Send Content header */ - sprintf(buffer, "%s: %s\r\n%s: %s\r\n%s: %s\r\n\r\n", - HEADER_CONTENT_TYPE, content_type, - HEADER_CONTENT_TRANSFER_ENCODING, transfer_encoding, - HEADER_CONTENT_ID, content_id); + len = sprintf(buffer, "%s: %s\r\n%s: %s\r\n%s: %s\r\n\r\n", + HEADER_CONTENT_TYPE, content_type, + HEADER_CONTENT_TRANSFER_ENCODING, transfer_encoding, + HEADER_CONTENT_ID, content_id); - return http_output_stream_write(conn->out, buffer, strlen(buffer)); + return http_output_stream_write(conn->out, buffer, len); } - herror_t httpc_mime_end(httpc_conn_t * conn, hresponse_t ** out) { herror_t status; char buffer[512]; char boundary[75]; + int len; /* Get the boundary string */ _httpc_mime_get_boundary(conn, boundary); - sprintf(buffer, "\r\n--%s--\r\n\r\n", boundary); + len = sprintf(buffer, "\r\n--%s--\r\n\r\n", boundary); /* Send boundary */ - status = http_output_stream_write(conn->out, buffer, strlen(buffer)); - - if (status != H_OK) + if ((status = http_output_stream_write(conn->out, buffer, len)) != H_OK) return status; if ((status = http_output_stream_flush(conn->out)) != H_OK) diff --git a/nanohttp/nanohttp-server.c b/nanohttp/nanohttp-server.c index bca46f4..9e2af45 100644 --- a/nanohttp/nanohttp-server.c +++ b/nanohttp/nanohttp-server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-server.c,v 1.78 2006/12/31 17:24:22 m0gg Exp $ +* $Id: nanohttp-server.c,v 1.79 2007/01/01 15:29:48 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -498,7 +498,7 @@ httpd_send_header(httpd_conn_t * res, int code, const char *text) */ /* set server name */ - strcat(header, "Server: Nano HTTPD library\r\n"); + strcat(header, "Server: nanoHTTP library\r\n"); /* set _httpd_connection status */ /* strcat (header, "Connection: close\r\n"); */ @@ -521,30 +521,60 @@ httpd_send_header(httpd_conn_t * res, int code, const char *text) return H_OK; } -herror_t -httpd_send_internal_error(httpd_conn_t * conn, const char *errmsg) +static herror_t +_httpd_send_html_message(httpd_conn_t *conn, int reason, const char *phrase, const char *msg) { - const char *template1 = + const char const *tmpl = "<html>" "<head>" + "<title>%s</title>" "</head>" "<body>" - "<h3>Error!</h3>" + "<h3>%s</h3>" "<hr/>" "<div>Message: '%s'</div>" "</body>" "</html>"; + char buf[4096]; + char slen[5]; + int len; + + len = snprintf(buf, 4096, tmpl, phrase, phrase, msg); + snprintf(slen, 5, "%d", len); + + httpd_set_header(conn, HEADER_CONTENT_LENGTH, slen); + httpd_send_header(conn, reason, phrase); + + return http_output_stream_write(conn->out, buf, len); +} + +herror_t +httpd_send_internal_error(httpd_conn_t * conn, const char *msg) +{ + return _httpd_send_html_message(conn, 500, HTTP_STATUS_500_REASON_PHRASE, msg); +} - char buffer[4096]; - char buflen[5]; +herror_t +httpd_send_not_implemented(httpd_conn_t *conn, const char *msg) +{ + return _httpd_send_html_message(conn, 501, HTTP_STATUS_501_REASON_PHRASE, msg); +} + +herror_t +httpd_send_bad_request(httpd_conn_t *conn, const char *msg) +{ + return _httpd_send_html_message(conn, 400, HTTP_STATUS_400_REASON_PHRASE, msg); +} - sprintf(buffer, template1, errmsg); - snprintf(buflen, 5, "%d", strlen(buffer)); +herror_t +httpd_send_unauthorized(httpd_conn_t *conn, const char *realm) +{ + char buf[128]; - httpd_set_header(conn, HEADER_CONTENT_LENGTH, buflen); - httpd_send_header(conn, 500, HTTP_STATUS_500_REASON_PHRASE); + snprintf(buf, 128, "Basic realm=\"%s\"", realm); + httpd_set_header(conn, HEADER_WWW_AUTHENTICATE, buf); - return http_output_stream_write_string(conn->out, buffer); + return _httpd_send_html_message(conn, 401, HTTP_STATUS_401_REASON_PHRASE, "Unauthorized request logged"); } static void @@ -713,13 +743,13 @@ httpd_session_main(void *data) switch ((code = herror_code(status))) { - case HSOCKET_ERROR_SSLCLOSE: - case HSOCKET_ERROR_RECEIVE: - log_error2("hrequest_new_from_socket failed (%s)", herror_message(status)); - break; - default: - httpd_send_internal_error(rconn, herror_message(status)); - break; + case HSOCKET_ERROR_SSLCLOSE: + case HSOCKET_ERROR_RECEIVE: + log_error2("hrequest_new_from_socket failed (%s)", herror_message(status)); + break; + default: + httpd_send_bad_request(rconn, herror_message(status)); + break; } herror_release(status); done = 1; @@ -773,26 +803,14 @@ httpd_session_main(void *data) { char buffer[256]; - sprintf(buffer, "service '%s' not registered properly (service function is NULL)", req->path); + snprintf(buffer, 256, "service '%s' is not registered properly (service function is NULL)", req->path); log_verbose1(buffer); - httpd_send_internal_error(rconn, buffer); + httpd_send_not_implemented(rconn, buffer); } } else { - char *template = - "<html>" - "<head>" - "<title>Unauthorized</title>" - "</head>" - "<body>" - "<h1>Unauthorized request logged</h1>" - "</body>" - "</html>"; - - httpd_set_header(rconn, HEADER_WWW_AUTHENTICATE, "Basic realm=\"nanoHTTP\""); - httpd_send_header(rconn, 401, HTTP_STATUS_401_REASON_PHRASE); - http_output_stream_write_string(rconn->out, template); + httpd_send_unauthorized(rconn, req->path); done = 1; } } @@ -810,7 +828,7 @@ httpd_session_main(void *data) char buffer[256]; sprintf(buffer, "no service for '%s' found", req->path); log_verbose1(buffer); - httpd_send_internal_error(rconn, buffer); + httpd_send_not_implemented(rconn, buffer); done = 1; } hrequest_free(req); @@ -914,6 +932,12 @@ httpd_add_headers(httpd_conn_t * conn, const hpair_t * values) static void _httpd_register_signal_handler(void) { + +#ifndef WIN32 + sigemptyset(&thrsigset); + sigaddset(&thrsigset, SIGALRM); +#endif + log_verbose2("registering termination signal handler (SIGNAL:%d)", _httpd_terminate_signal); #ifdef WIN32 @@ -1007,11 +1031,6 @@ httpd_run(void) log_verbose1("starting run routine"); -#ifndef WIN32 - sigemptyset(&thrsigset); - sigaddset(&thrsigset, SIGALRM); -#endif - _httpd_register_signal_handler(); if ((err = hsocket_listen(&_httpd_socket)) != H_OK) @@ -1221,30 +1240,25 @@ httpd_mime_next(httpd_conn_t * conn, const char *content_id, herror_t status; char buffer[512]; char boundary[75]; + int len; /* Get the boundary string */ _httpd_mime_get_boundary(conn, boundary); - sprintf(buffer, "\r\n--%s\r\n", boundary); + len = sprintf(buffer, "\r\n--%s\r\n", boundary); /* Send boundary */ - status = - http_output_stream_write(conn->out, buffer, strlen(buffer)); - - if (status != H_OK) + if ((status = http_output_stream_write(conn->out, buffer, len)) != H_OK) return status; /* Send Content header */ - sprintf(buffer, "%s: %s\r\n%s: %s\r\n%s: %s\r\n\r\n", - HEADER_CONTENT_TYPE, content_type ? content_type : "text/plain", - HEADER_CONTENT_TRANSFER_ENCODING, - transfer_encoding ? transfer_encoding : "binary", - HEADER_CONTENT_ID, - content_id ? content_id : "<content-id-not-set>"); - - status = - http_output_stream_write(conn->out, buffer, strlen(buffer)); - - return status; + len = sprintf(buffer, "%s: %s\r\n%s: %s\r\n%s: %s\r\n\r\n", + HEADER_CONTENT_TYPE, content_type ? content_type : "text/plain", + HEADER_CONTENT_TRANSFER_ENCODING, + transfer_encoding ? transfer_encoding : "binary", + HEADER_CONTENT_ID, + content_id ? content_id : "<content-id-not-set>"); + + return http_output_stream_write(conn->out, buffer, len); } /** @@ -1303,20 +1317,15 @@ httpd_mime_end(httpd_conn_t * conn) herror_t status; char buffer[512]; char boundary[75]; + int len; /* Get the boundary string */ _httpd_mime_get_boundary(conn, boundary); - sprintf(buffer, "\r\n--%s--\r\n\r\n", boundary); + len = sprintf(buffer, "\r\n--%s--\r\n\r\n", boundary); /* Send boundary */ - status = - http_output_stream_write(conn->out, buffer, strlen(buffer)); - - if (status != H_OK) + if ((status = http_output_stream_write(conn->out, buffer, len)) != H_OK) return status; - /* Flush put stream */ - status = http_output_stream_flush(conn->out); - - return status; + return http_output_stream_flush(conn->out); } |