summaryrefslogtreecommitdiffstats
path: root/nanohttp/nanohttp-server.c
diff options
context:
space:
mode:
Diffstat (limited to 'nanohttp/nanohttp-server.c')
-rw-r--r--nanohttp/nanohttp-server.c341
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;
}