diff options
Diffstat (limited to 'nanohttp/nanohttp-server.c')
-rw-r--r-- | nanohttp/nanohttp-server.c | 341 |
1 files changed, 177 insertions, 164 deletions
diff --git a/nanohttp/nanohttp-server.c b/nanohttp/nanohttp-server.c index 807ab58..9b51cd6 100644 --- a/nanohttp/nanohttp-server.c +++ b/nanohttp/nanohttp-server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-server.c,v 1.14 2004/08/31 16:34:08 rans Exp $ +* $Id: nanohttp-server.c,v 1.15 2004/09/01 07:58:08 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -18,7 +18,7 @@ * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. -* +* * Email: ayaz@jprogrammer.net ******************************************************************/ #include <nanohttp/nanohttp-server.h> @@ -42,45 +42,48 @@ #endif -/* ----------------------------------------------------- -nano httpd internally globals ------------------------------------------------------ */ -static int _httpd_port = 10000; -static int _httpd_max_connections = 20; -static int _httpd_max_idle = 120; +/* + * ----------------------------------------------------- nano httpd + * internally globals ----------------------------------------------------- + */ +static int _httpd_port = 10000; +static int _httpd_max_connections = 20; +static int _httpd_max_idle = 120; static hsocket_t _httpd_socket; static hservice_t *_httpd_services_head = NULL; static hservice_t *_httpd_services_tail = NULL; -static int _httpd_run = 1; -static int _httpd_terminate_signal = SIGTERM; +static int _httpd_run = 1; +static int _httpd_terminate_signal = SIGTERM; static conndata_t *_httpd_connection; #ifdef WIN32 #include <nanohttp/nanohttp-windows.h> #endif -/* ----------------------------------------------------- -FUNCTION: httpd_init
-NOTE: This will be called from soap_server_init_args() ------------------------------------------------------ */ -int httpd_init(int argc, char *argv[]) +/* + * ----------------------------------------------------- FUNCTION: httpd_init + * NOTE: This will be called from soap_server_init_args() + * ----------------------------------------------------- + */ +int +httpd_init(int argc, char *argv[]) { - int i, status; -
status = hsocket_module_init();
- if (status != 0)
- return status;
+ int i, status; + status = hsocket_module_init(); + if (status != 0) + return status; /* write argument information */ - log_verbose1("Arguments:"); - for (i=0;i<argc;i++) + log_verbose1("Arguments:"); + for (i = 0; i < argc; i++) log_verbose3("argv[%i] = '%s'", i, SAVE_STR(argv[i])); /* initialize from arguments */ - for (i=0;i<argc;i++) { - if (!strcmp(argv[i], NHTTPD_ARG_PORT) && i < argc-1) { - _httpd_port = atoi(argv[i+1]); - } else if (!strcmp(argv[i], NHTTPD_ARG_TERMSIG) && i < argc-1) { - _httpd_terminate_signal = atoi(argv[i+1]); + for (i = 0; i < argc; i++) { + if (!strcmp(argv[i], NHTTPD_ARG_PORT) && i < argc - 1) { + _httpd_port = atoi(argv[i + 1]); + } else if (!strcmp(argv[i], NHTTPD_ARG_TERMSIG) && i < argc - 1) { + _httpd_terminate_signal = atoi(argv[i + 1]); } } @@ -88,15 +91,18 @@ int httpd_init(int argc, char *argv[]) /* init built-in services */ /* - httpd_register("/httpd/list", service_list); - */ - _httpd_connection=calloc(_httpd_max_connections, sizeof(conndata_t));
for(i=0; i<_httpd_max_connections; i++)
{
memset((char *)&_httpd_connection[i], 0, sizeof(_httpd_connection[i])); + * httpd_register("/httpd/list", service_list); + */ + _httpd_connection = calloc(_httpd_max_connections, sizeof(conndata_t)); + for (i = 0; i < _httpd_max_connections; i++) { + memset((char *) &_httpd_connection[i], 0, + sizeof(_httpd_connection[i])); } #ifdef WIN32 - if (_beginthread(WSAReaper, 0, NULL)==-1) { + if (_beginthread(WSAReaper, 0, NULL) == -1) { log_error1("Winsock reaper thread failed to start"); - return(-1); + return (-1); } #endif @@ -107,21 +113,22 @@ int httpd_init(int argc, char *argv[]) return status; } -/* ----------------------------------------------------- -FUNCTION: httpd_register ------------------------------------------------------ */ +/* + * ----------------------------------------------------- FUNCTION: + * httpd_register ----------------------------------------------------- + */ -int httpd_register(const char* ctx, httpd_service func) +int +httpd_register(const char *ctx, httpd_service func) { - hservice_t* service; + hservice_t *service; - service = (hservice_t*)malloc(sizeof(hservice_t)); + service = (hservice_t *) malloc(sizeof(hservice_t)); service->next = NULL; service->func = func; strcpy(service->ctx, ctx); - log_verbose3("register service:t(%p):%s", service, SAVE_STR(ctx));
-
+ log_verbose3("register service:t(%p):%s", service, SAVE_STR(ctx)); if (_httpd_services_head == NULL) { _httpd_services_head = _httpd_services_tail = service; } else { @@ -133,21 +140,25 @@ int httpd_register(const char* ctx, httpd_service func) } -/* ----------------------------------------------------- -FUNCTION: httpd_services ------------------------------------------------------ */ -hservice_t *httpd_services() +/* + * ----------------------------------------------------- FUNCTION: + * httpd_services ----------------------------------------------------- + */ +hservice_t * +httpd_services() { return _httpd_services_head; } -/* ----------------------------------------------------- -FUNCTION: httpd_find_service ------------------------------------------------------ */ -static hservice_t *httpd_find_service(const char* ctx) +/* + * ----------------------------------------------------- FUNCTION: + * httpd_find_service ----------------------------------------------------- + */ +static hservice_t * +httpd_find_service(const char *ctx) { - hservice_t *cur = _httpd_services_head; + hservice_t *cur = _httpd_services_head; while (cur != NULL) { if (!strcmp(cur->ctx, ctx)) { @@ -160,29 +171,33 @@ static hservice_t *httpd_find_service(const char* ctx) } -/* ----------------------------------------------------- -FUNCTION: httpd_response_set_content_type ------------------------------------------------------ */ -void httpd_response_set_content_type(httpd_conn_t *res, - const char* content_type) +/* + * ----------------------------------------------------- FUNCTION: + * httpd_response_set_content_type + * ----------------------------------------------------- + */ +void +httpd_response_set_content_type(httpd_conn_t * res, const char *content_type) { strncpy(res->content_type, content_type, 25); } -/* ----------------------------------------------------- -FUNCTION: httpd_response_send_header ------------------------------------------------------ */ -int httpd_send_header(httpd_conn_t *res, - int code, const char* text, - hpair_t *pair) +/* + * ----------------------------------------------------- FUNCTION: + * httpd_response_send_header + * ----------------------------------------------------- + */ +int +httpd_send_header(httpd_conn_t * res, + int code, const char *text, hpair_t * pair) { - struct tm stm; - time_t nw; - char buffer[255]; - char header[1024]; - hpair_t *cur; - int status; + struct tm stm; + time_t nw; + char buffer[255]; + char header[1024]; + hpair_t *cur; + int status; /* set status code */ sprintf(header, "HTTP/1.1 %d %s\r\n", code, text); @@ -196,13 +211,10 @@ int httpd_send_header(httpd_conn_t *res, /* 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); - } - */ + * 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: Nano HTTPD library\r\n"); @@ -228,23 +240,26 @@ int httpd_send_header(httpd_conn_t *res, } -int httpd_send_internal_error(httpd_conn_t *conn, const char* errmsg) +int +httpd_send_internal_error(httpd_conn_t * conn, const char *errmsg) { - const char *template1 = - "<html><body><h3>Error!</h3><hr> Message: '%s' </body></html>\r\n"; + const char *template1 = + "<html><body><h3>Error!</h3><hr> Message: '%s' </body></html>\r\n"; - char buffer[4064]; + char buffer[4064]; sprintf(buffer, template1, errmsg); httpd_send_header(conn, 500, "INTERNAL", NULL); return send(conn->sock, buffer, strlen(buffer), 0); } -/* ----------------------------------------------------- -FUNCTION: httpd_request_print ------------------------------------------------------ */ -static void httpd_request_print(hrequest_t *req) +/* + * ----------------------------------------------------- FUNCTION: + * httpd_request_print ----------------------------------------------------- + */ +static void +httpd_request_print(hrequest_t * req) { - hpair_t *pair; + hpair_t *pair; log_verbose1("++++++ Request +++++++++"); log_verbose2(" Method : '%s'", req->method); @@ -261,55 +276,60 @@ static void httpd_request_print(hrequest_t *req) } -/* ----------------------------------------------------- -FUNCTION: httpd_session_main ------------------------------------------------------ */ +/* + * ----------------------------------------------------- FUNCTION: + * httpd_session_main ----------------------------------------------------- + */ #ifdef WIN32 -static unsigned _stdcall httpd_session_main(void *data) +static unsigned _stdcall +httpd_session_main(void *data) #else -static void* httpd_session_main(void *data) +static void * +httpd_session_main(void *data) #endif { - conndata_t *conn = (conndata_t*)data; - const char *msg = "SESSION 1.0\n"; - int len = strlen(msg); - char ch[2]; - char buffer[256]; /* temp buffer for recv() */ - char header[4064]; /* received header */ - int total; /* result from recv() */ - int headerreached =0; /* whether reach header "\n\n" */ - hrequest_t* req = NULL; /* only for test */ - httpd_conn_t *rconn; - hservice_t* service = NULL; - long content_length = 0; + conndata_t *conn = (conndata_t *) data; + const char *msg = "SESSION 1.0\n"; + int len = strlen(msg); + char ch[2]; + char buffer[256]; /* temp buffer for recv() */ + char header[4064]; /* received header */ + int total; /* result from recv() */ + int headerreached = 0; /* whether reach header + * "\n\n" */ + hrequest_t *req = NULL; /* only for test */ + httpd_conn_t *rconn; + hservice_t *service = NULL; + long content_length = 0; header[0] = '\0'; len = 0; log_verbose1("starting httpd_session_main()"); - conn->atime=time((time_t)0); + conn->atime = time((time_t) 0); while (len < 4064) { - /*printf("receiving ...\n");*/ + /* printf("receiving ...\n"); */ total = recv(conn->sock, ch, 1, 0); - if (total==0) break; + if (total == 0) + break; header[len] = ch[0]; len++; if (len > 3) { - if (!strncmp(&header[len-4], "\r\n\r\n", 4)) { + if (!strncmp(&header[len - 4], "\r\n\r\n", 4)) { header[len] = '\0'; break; } } } - /* log_verbose2("=== HEADER ===\n%s\n============\n", header);*/ + /* log_verbose2("=== HEADER ===\n%s\n============\n", header); */ /* call the service */ req = hrequest_new_from_buffer(header); httpd_request_print(req); - rconn = (httpd_conn_t*)malloc(sizeof(httpd_conn_t)); + rconn = (httpd_conn_t *) malloc(sizeof(httpd_conn_t)); rconn->sock = conn->sock; rconn->content_type[0] = '\0'; @@ -319,8 +339,8 @@ static void* httpd_session_main(void *data) if (service->func != NULL) { service->func(rconn, req); } else { - sprintf(buffer, - "service '%s' not registered properly (func == NULL)", + sprintf(buffer, + "service '%s' not registered properly (func == NULL)", req->path); log_verbose1(buffer); httpd_send_internal_error(rconn, buffer); @@ -332,70 +352,67 @@ static void* httpd_session_main(void *data) } close(conn->sock); + conn->sock = 0; - /* httpd_response_free(res);*/ + /* httpd_response_free(res); */ hrequest_free(req); #ifdef WIN32 - CloseHandle((HANDLE)conn->tid); + CloseHandle((HANDLE) conn->tid); _endthread(); return 0; #else pthread_exit(NULL); return service; #endif -} +} -/* ----------------------------------------------------- -FUNCTION: httpd_term ------------------------------------------------------ */ -void httpd_term(int sig) +/* + * ----------------------------------------------------- FUNCTION: httpd_term + * ----------------------------------------------------- + */ +void +httpd_term(int sig) { if (sig == _httpd_terminate_signal) _httpd_run = 0; } -/* ----------------------------------------------------- -FUNCTION: httpd_run ------------------------------------------------------ */ +/* + * ----------------------------------------------------- FUNCTION: httpd_run + * ----------------------------------------------------- + */ -int httpd_run() +int +httpd_run() { - int err; - fd_set fds; - struct timeval timeout; + int err; + fd_set fds; + struct timeval timeout; -#ifndef WIN32 -pthread_attr_init(&attr); -#ifdef PTHREAD_CREATE_DETACHED - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); -#endif -#endif - log_verbose1("starting run routine"); timeout.tv_sec = 1; timeout.tv_usec = 0; /* listen to port */ - err = hsocket_listen(_httpd_socket,15); - if (err != HSOCKET_OK) { + err = hsocket_listen(_httpd_socket, 15); + if (err != HSOCKET_OK) { log_error2("httpd_run(): '%d'", err); return err; } - - log_verbose2("registering termination signal handler (SIGNAL:%d)", _httpd_terminate_signal); + log_verbose2("registering termination signal handler (SIGNAL:%d)", + _httpd_terminate_signal); signal(_httpd_terminate_signal, httpd_term); log_verbose2("listening to port '%d'", _httpd_port); - err=hsocket_makenonblock(_httpd_socket); - if (err != HSOCKET_OK) { + err = hsocket_makenonblock(_httpd_socket); + if (err != HSOCKET_OK) { log_error2("httpd_run(): '%d'", err); return err; } - timeout.tv_sec = 1; timeout.tv_usec = 0; @@ -407,22 +424,20 @@ pthread_attr_init(&attr); #ifndef WIN32 select(1, &fds, NULL, NULL, &timeout); #else - if(select(1, &fds, NULL, NULL, &timeout)==SOCKET_ERROR) - { - err=WSAGetLastError(); + if (select(1, &fds, NULL, NULL, &timeout) == SOCKET_ERROR) { + err = WSAGetLastError(); log_error1("select error"); return -1; } #endif - while (_httpd_run && (FD_ISSET(_httpd_socket, &fds))) - + while (_httpd_run && (FD_ISSET(_httpd_socket, &fds))) if (!_httpd_run) break; - if (hsocket_accept(_httpd_socket, httpd_session_main, _httpd_connection, - _httpd_max_connections) != 0) - { + if (hsocket_accept + (_httpd_socket, httpd_session_main, _httpd_connection, + _httpd_max_connections) != 0) { continue; } } @@ -430,16 +445,18 @@ pthread_attr_init(&attr); return 0; } -char *httpd_get_postdata(httpd_conn_t *conn, hrequest_t *req, long *received, long max) +char * +httpd_get_postdata(httpd_conn_t * conn, hrequest_t * req, long *received, + long max) { - char *content_length_str; - long content_length = 0; - long total = 0; - char *postdata = NULL; + char *content_length_str; + long content_length = 0; + long total = 0; + char *postdata = NULL; if (!strcmp(req->method, "POST")) { - content_length_str = + content_length_str = hpairnode_get_ignore_case(req->header, HEADER_CONTENT_LENGTH); if (content_length_str != NULL) @@ -448,32 +465,28 @@ char *httpd_get_postdata(httpd_conn_t *conn, hrequest_t *req, long *received, lo } else { log_warn1("Not a POST method"); return NULL; - } + } - if (content_length > max && max != -1) + if (content_length > max && max != -1) return NULL; if (content_length == 0) { *received = 0; - postdata = (char*)malloc(1); + postdata = (char *) malloc(1); postdata[0] = '\0'; return postdata; } - - postdata = (char*)malloc(content_length+1); + postdata = (char *) malloc(content_length + 1); if (postdata == NULL) { log_error1("Not enough memory"); return NULL; } - - - if (hsocket_read(conn->sock, postdata, - (int)content_length, 1) == HSOCKET_OK) { - *received = content_length; - postdata[content_length] = '\0'; - return postdata; - } - - free (postdata); - return NULL; + if (hsocket_read(conn->sock, postdata, + (int) content_length, 1) == HSOCKET_OK) { + *received = content_length; + postdata[content_length] = '\0'; + return postdata; + } + free(postdata); + return NULL; } |