From 949a8d0b46d6baa9f42c2f8c3bd5e3bdc3596cbd Mon Sep 17 00:00:00 2001 From: m0gg Date: Sun, 19 Nov 2006 09:40:14 +0000 Subject: nanohttp admin patch; code cleanup --- nanohttp/Makefile.am | 6 +- nanohttp/nanohttp-admin.c | 197 +++++++++++++++++++++++++++++++++++++++++++ nanohttp/nanohttp-admin.h | 52 ++++++++++++ nanohttp/nanohttp-client.c | 30 ++++--- nanohttp/nanohttp-client.h | 11 +-- nanohttp/nanohttp-common.c | 20 +++-- nanohttp/nanohttp-common.h | 6 +- nanohttp/nanohttp-mime.c | 15 ++-- nanohttp/nanohttp-mime.h | 9 +- nanohttp/nanohttp-request.c | 28 ++++-- nanohttp/nanohttp-request.h | 12 ++- nanohttp/nanohttp-response.c | 12 +-- nanohttp/nanohttp-response.h | 10 +-- nanohttp/nanohttp-server.c | 143 +++++++++++++++---------------- nanohttp/nanohttp-server.h | 25 +++--- nanohttp/nanohttp-socket.c | 44 +++++----- nanohttp/nanohttp-socket.h | 33 ++------ nanohttp/nanohttp-ssl.c | 14 ++- nanohttp/nanohttp-ssl.h | 7 +- nanohttp/nanohttp-stream.c | 37 ++++---- nanohttp/nanohttp-stream.h | 17 ++-- 21 files changed, 489 insertions(+), 239 deletions(-) create mode 100644 nanohttp/nanohttp-admin.c create mode 100644 nanohttp/nanohttp-admin.h (limited to 'nanohttp') diff --git a/nanohttp/Makefile.am b/nanohttp/Makefile.am index b585026..311f1f1 100644 --- a/nanohttp/Makefile.am +++ b/nanohttp/Makefile.am @@ -5,12 +5,14 @@ libnanohttp_ladir=$(includedir)/nanohttp-@nanohttp_release@/nanohttp libnanohttp_la_SOURCES=nanohttp-common.c nanohttp-socket.c nanohttp-client.c \ nanohttp-server.c nanohttp-stream.c nanohttp-mime.c \ nanohttp-request.c nanohttp-response.c \ - nanohttp-base64.c nanohttp-ssl.c nanohttp-logging.c + nanohttp-base64.c nanohttp-ssl.c nanohttp-logging.c \ + nanohttp-admin.c libnanohttp_la_HEADERS=nanohttp-common.h nanohttp-socket.h nanohttp-client.h \ nanohttp-server.h nanohttp-stream.h nanohttp-mime.h \ nanohttp-request.h nanohttp-response.h \ - nanohttp-base64.h nanohttp-ssl.h nanohttp-logging.h + nanohttp-base64.h nanohttp-ssl.h nanohttp-logging.h \ + nanohttp-admin.h libnanohttp_la_LDFLAGS= -version-info @nanohttp_version@ -release @nanohttp_release@ libnanohttp_la_CFLAGS=-I${top_srcdir} diff --git a/nanohttp/nanohttp-admin.c b/nanohttp/nanohttp-admin.c new file mode 100644 index 0000000..33f9bc0 --- /dev/null +++ b/nanohttp/nanohttp-admin.c @@ -0,0 +1,197 @@ + /****************************************************************** +* $Id: nanohttp-admin.c,v 1.1 2006/11/19 09:40:14 m0gg Exp $ +* +* CSOAP Project: A SOAP client/server library in C +* Copyright (C) 2003 Ferhat Ayaz +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* 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 +******************************************************************/ +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#ifdef HAVE_STDIO_H +#include +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#include "nanohttp-common.h" +#include "nanohttp-socket.h" +#include "nanohttp-stream.h" +#include "nanohttp-request.h" +#include "nanohttp-server.h" +#include "nanohttp-admin.h" + +static void +_httpd_admin_send_title(httpd_conn_t *conn, const char *title) +{ + httpd_send_header(conn, 200, "OK"); + http_output_stream_write_string(conn->out, + "nhttpd "); + http_output_stream_write_string(conn->out, title); + http_output_stream_write_string(conn->out, "
"); + + return; +} + + +_httpd_admin_list_services(httpd_conn_t *conn) +{ + char buffer[1024]; + hservice_t *node; + + _httpd_admin_send_title(conn, "Available services"); + + http_output_stream_write_string(conn->out, "
    "); + for (node = httpd_get_services(); node; node = node->next) + { + sprintf(buffer, "
  • %s
  • ", node->ctx, node->ctx); + http_output_stream_write_string(conn->out, buffer); + } + http_output_stream_write_string(conn->out, "
"); + + http_output_stream_write_string(conn->out, ""); + + return; +} + + +static void +_httpd_admin_list_statistics(httpd_conn_t *conn, const char *service_name) +{ + char buffer[1024]; + hservice_t *service; + + sprintf(buffer, "Listing statistics for service %s", service_name); + _httpd_admin_send_title(conn, buffer); + + if (!(service = httpd_find_service(service_name))) + { + http_output_stream_write_string(conn->out, "service not found!"); + http_output_stream_write_string(conn->out, ""); + return; + } + + pthread_rwlock_rdlock(&(service->statistics->lock)); + sprintf(buffer, "
    " + "
  • Requests served: %lu
  • " + "
  • Bytes read: %lu
  • " + "
  • Bytes sent: %lu
  • " + "
  • Time used: %li.%li sec
  • " + "
      ", + service->statistics->requests, + service->statistics->bytes_received, + service->statistics->bytes_transmitted, + service->statistics->time.tv_sec, + service->statistics->time.tv_usec); + pthread_rwlock_unlock(&(service->statistics->lock)); + + http_output_stream_write_string(conn->out, buffer); + + http_output_stream_write_string(conn->out, ""); + + return; +} + + +static void +_httpd_admin_handle_get(httpd_conn_t * conn, hrequest_t * req) +{ + char *param; + + if ((param = hpairnode_get_ignore_case(req->query, NHTTPD_ADMIN_QUERY_SERVICES))) + { + _httpd_admin_list_services(conn); + } + else if ((param = hpairnode_get_ignore_case(req->query, NHTTPD_ADMIN_QUERY_STATISTICS))) + { + _httpd_admin_list_statistics(conn, param); + } + else + { + _httpd_admin_send_title(conn, "Welcome to the admin site"); + + http_output_stream_write_string(conn->out, "
        "); + http_output_stream_write_string(conn->out, + "
      • Services
      • "); + http_output_stream_write_string(conn->out, "
      "); + + http_output_stream_write_string(conn->out, ""); + } + + return; +} + + +static void +_httpd_admin_entry(httpd_conn_t * conn, hrequest_t * req) +{ + if (req->method == HTTP_REQUEST_GET) + { + _httpd_admin_handle_get(conn, req); + } + else + { + httpd_send_header(conn, 200, "OK"); + http_output_stream_write_string(conn->out, + "" + "" + "" + "" + "

      Sorry!

      " + "
      " + "
      POST Service is not implemented now. Use your browser.
      " + "" + ""); + } + return; +} + + +herror_t +httpd_admin_init_args(int argc, char **argv) +{ + int i; + + for (i=0; i #endif -#ifdef HAVE_TIME_H -#include +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#include #endif #ifdef HAVE_STDIO_H @@ -45,14 +49,17 @@ #include #endif -#ifdef MEM_DEBUG -#include +#ifdef HAVE_NETINET_IN_H +#include #endif -#include "nanohttp-client.h" +#include "nanohttp-common.h" #include "nanohttp-socket.h" +#include "nanohttp-stream.h" +#include "nanohttp-response.h" #include "nanohttp-base64.h" #include "nanohttp-logging.h" +#include "nanohttp-client.h" /*-------------------------------------------------- FUNCTION: httpc_init @@ -553,8 +560,7 @@ httpc_mime_next(httpc_conn_t * conn, sprintf(buffer, "\r\n--%s\r\n", boundary); /* Send boundary */ - status = http_output_stream_write(conn->out, - (const byte_t *) buffer, strlen(buffer)); + status = http_output_stream_write(conn->out, buffer, strlen(buffer)); if (status != H_OK) return status; @@ -565,8 +571,7 @@ httpc_mime_next(httpc_conn_t * conn, HEADER_CONTENT_TRANSFER_ENCODING, transfer_encoding, HEADER_CONTENT_ID, content_id); - return http_output_stream_write(conn->out, - (const byte_t *) buffer, strlen(buffer)); + return http_output_stream_write(conn->out, buffer, strlen(buffer)); } @@ -582,8 +587,7 @@ httpc_mime_end(httpc_conn_t * conn, hresponse_t ** out) sprintf(buffer, "\r\n--%s--\r\n\r\n", boundary); /* Send boundary */ - status = http_output_stream_write(conn->out, - (const byte_t *) buffer, strlen(buffer)); + status = http_output_stream_write(conn->out, buffer, strlen(buffer)); if (status != H_OK) return status; @@ -610,7 +614,7 @@ httpc_mime_send_file(httpc_conn_t * conn, { herror_t status; FILE *fd = fopen(filename, "rb"); - byte_t buffer[MAX_FILE_BUFFER_SIZE]; + unsigned char buffer[MAX_FILE_BUFFER_SIZE]; size_t size; if (fd == NULL) diff --git a/nanohttp/nanohttp-client.h b/nanohttp/nanohttp-client.h index 67066d6..2ef96a8 100644 --- a/nanohttp/nanohttp-client.h +++ b/nanohttp/nanohttp-client.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-client.h,v 1.24 2006/04/26 17:30:29 m0gg Exp $ + * $Id: nanohttp-client.h,v 1.25 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -21,13 +21,8 @@ * * Email: ferhatayaz@yahoo.com ******************************************************************/ -#ifndef NANO_HTTP_CLIENT_H -#define NANO_HTTP_CLIENT_H - -#include -#include -#include -#include +#ifndef __nanohttp_client_h +#define __nanohttp_client_h typedef struct httpc_conn { diff --git a/nanohttp/nanohttp-common.c b/nanohttp/nanohttp-common.c index 0784684..ebba360 100644 --- a/nanohttp/nanohttp-common.c +++ b/nanohttp/nanohttp-common.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-common.c,v 1.30 2006/07/09 16:24:19 snowdrop Exp $ +* $Id: nanohttp-common.c,v 1.31 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -41,6 +41,10 @@ #include #endif +#ifdef HAVE_ERRNO_H +#include +#endif + #ifdef HAVE_CTYPE_H #include #endif @@ -49,10 +53,6 @@ #include #endif -#ifdef MEM_DEBUG -#include -#endif - #include "nanohttp-common.h" #include "nanohttp-logging.h" @@ -90,16 +90,22 @@ herror_t herror_new(const char *func, int errcode, const char *format, ...) { va_list ap; + herror_impl_t *impl; + + if (!(impl = (herror_impl_t *) malloc(sizeof(herror_impl_t)))) + { + log_error2("malloc failed (%s)", strerror(errno)); + return NULL; + } - herror_impl_t *impl = (herror_impl_t *) malloc(sizeof(herror_impl_t)); impl->errcode = errcode; strcpy(impl->func, func); + va_start(ap, format); vsprintf(impl->message, format, ap); va_end(ap); return (herror_t) impl; - } int diff --git a/nanohttp/nanohttp-common.h b/nanohttp/nanohttp-common.h index 2cd4bb8..bf54a12 100644 --- a/nanohttp/nanohttp-common.h +++ b/nanohttp/nanohttp-common.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-common.h,v 1.31 2006/07/09 16:24:19 snowdrop Exp $ + * $Id: nanohttp-common.h,v 1.32 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -24,9 +24,6 @@ #ifndef NANO_HTTP_COMMON_H #define NANO_HTTP_COMMON_H -#include -#include - #define HEADER_CONTENT_ID "Content-Id" #define HEADER_CONTENT_TRANSFER_ENCODING "Content-Transfer-Encoding" #define TRANSFER_ENCODING_CHUNKED "chunked" @@ -284,7 +281,6 @@ char *strtok_r(char *s, const char *delim, char **save_ptr); struct tm *localtime_r(const time_t * const timep, struct tm *p_tm); #endif -typedef unsigned char byte_t; typedef void *herror_t; herror_t herror_new(const char *func, int errcode, const char *format, ...); diff --git a/nanohttp/nanohttp-mime.c b/nanohttp/nanohttp-mime.c index 6a2e6d7..cbea458 100755 --- a/nanohttp/nanohttp-mime.c +++ b/nanohttp/nanohttp-mime.c @@ -3,7 +3,7 @@ * | \/ | | | | \/ | | _/ * |_''_| |_| |_''_| |_'/ PARSER * -* $Id: nanohttp-mime.c,v 1.13 2006/07/09 16:24:19 snowdrop Exp $ +* $Id: nanohttp-mime.c,v 1.14 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -37,16 +37,19 @@ #include #endif +#ifdef HAVE_NETINET_IN_H +#include +#endif + /*---------------------------------------------------------------- Buffered Reader. A helper object to read bytes from a source ----------------------------------------------------------------*/ -#ifdef MEM_DEBUG -#include -#endif - -#include "nanohttp-logging.h" +#include "nanohttp-common.h" +#include "nanohttp-socket.h" +#include "nanohttp-stream.h" #include "nanohttp-mime.h" +#include "nanohttp-logging.h" /* ------------------------------------------------------------------ diff --git a/nanohttp/nanohttp-mime.h b/nanohttp/nanohttp-mime.h index f63535a..7d718d9 100755 --- a/nanohttp/nanohttp-mime.h +++ b/nanohttp/nanohttp-mime.h @@ -3,7 +3,7 @@ * | \/ | | | | \/ | | _/ * |_''_| |_| |_''_| |_'/ PARSER * -* $Id: nanohttp-mime.h,v 1.8 2006/02/27 22:26:02 snowdrop Exp $ +* $Id: nanohttp-mime.h,v 1.9 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -26,11 +26,8 @@ * Email: ferhatayaz@yahoo.com ******************************************************************/ -#ifndef NANO_HTTP_MIME_PARSER_H -#define NANO_HTTP_MIME_PARSER_H - -#include -#include +#ifndef __nanohttp_mime_h +#define __nanohttp_mime_h #ifdef __cplusplus extern "C" { diff --git a/nanohttp/nanohttp-request.c b/nanohttp/nanohttp-request.c index 8350848..c7d159b 100755 --- a/nanohttp/nanohttp-request.c +++ b/nanohttp/nanohttp-request.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-request.c,v 1.14 2006/07/09 16:24:19 snowdrop Exp $ +* $Id: nanohttp-request.c,v 1.15 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -25,6 +25,10 @@ #include #endif +#ifdef HAVE_SYS_TIME_H +#include +#endif + #ifdef HAVE_STDIO_H #include #endif @@ -37,12 +41,14 @@ #include #endif -#ifdef MEM_DEBUG -#include +#ifdef HAVE_NETINET_IN_H +#include #endif #include "nanohttp-logging.h" #include "nanohttp-common.h" +#include "nanohttp-socket.h" +#include "nanohttp-stream.h" #include "nanohttp-request.h" static hrequest_t * @@ -52,9 +58,18 @@ hrequest_new(void) if (!(req = (hrequest_t *) malloc(sizeof(hrequest_t)))) { - log_error2("malloc failed (%s)", strerror(errno)); - return NULL; + log_error2("malloc failed (%s)", strerror(errno)); + return NULL; + } + + if (!(req->statistics = (struct request_statistics *)malloc(sizeof(struct request_statistics)))) { + + log_error2("malloc failed (%s)", strerror(errno)); + free(req); + return NULL; } + if (gettimeofday(&(req->statistics->time), NULL) < 0) + log_error2("gettimeofday failed (%s)", strerror(errno)); req->method = HTTP_REQUEST_GET; req->version = HTTP_1_1; @@ -255,6 +270,9 @@ hrequest_free(hrequest_t * req) if (req->attachments) attachments_free(req->attachments); + if (req->statistics) + free(req->statistics); + free(req); return; diff --git a/nanohttp/nanohttp-request.h b/nanohttp/nanohttp-request.h index 03cea1e..d34466a 100755 --- a/nanohttp/nanohttp-request.h +++ b/nanohttp/nanohttp-request.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-request.h,v 1.7 2006/03/06 13:37:38 m0gg Exp $ + * $Id: nanohttp-request.h,v 1.8 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -24,8 +24,12 @@ #ifndef NANO_HTTP_REQUEST_H #define NANO_HTTP_REQUEST_H -#include -#include +struct request_statistics +{ + unsigned long bytes_transmitted; + unsigned long bytes_received; + struct timeval time; +}; /* request object @@ -39,6 +43,8 @@ typedef struct hrequest hpair_t *query; hpair_t *header; + struct request_statistics *statistics; + http_input_stream_t *in; content_type_t *content_type; attachments_t *attachments; diff --git a/nanohttp/nanohttp-response.c b/nanohttp/nanohttp-response.c index 879fd6c..d38056d 100755 --- a/nanohttp/nanohttp-response.c +++ b/nanohttp/nanohttp-response.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-response.c,v 1.11 2006/07/09 16:24:19 snowdrop Exp $ +* $Id: nanohttp-response.c,v 1.12 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -37,20 +37,21 @@ #include #endif -#ifdef MEM_DEBUG -#include +#ifdef HAVE_NETINET_IN_H +#include #endif #include "nanohttp-logging.h" #include "nanohttp-common.h" +#include "nanohttp-socket.h" +#include "nanohttp-stream.h" #include "nanohttp-response.h" static hresponse_t * -hresponse_new() +hresponse_new(void) { hresponse_t *res; - /* create response object */ if (!(res = (hresponse_t *) malloc(sizeof(hresponse_t)))) { log_error2("malloc failed (%s)", strerror(errno)); @@ -64,6 +65,7 @@ hresponse_new() res->in = NULL; res->content_type = NULL; res->attachments = NULL; + return res; } diff --git a/nanohttp/nanohttp-response.h b/nanohttp/nanohttp-response.h index 622ef63..4dcc452 100755 --- a/nanohttp/nanohttp-response.h +++ b/nanohttp/nanohttp-response.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-response.h,v 1.7 2006/03/06 13:37:38 m0gg Exp $ + * $Id: nanohttp-response.h,v 1.8 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -21,12 +21,8 @@ * * Email: ferhatayaz@yahoo.com ******************************************************************/ -#ifndef NANO_HTTP_RESPONSE_H -#define NANO_HTTP_RESPONSE_H - -#include -#include -#include +#ifndef __nanohttp_response_h +#define __nanohttp_response_h /* response object */ typedef struct hresponse diff --git a/nanohttp/nanohttp-server.c b/nanohttp/nanohttp-server.c index d5d77dd..c75eacf 100644 --- a/nanohttp/nanohttp-server.c +++ b/nanohttp/nanohttp-server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-server.c,v 1.62 2006/07/09 16:24:19 snowdrop Exp $ +* $Id: nanohttp-server.c,v 1.63 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -41,6 +41,10 @@ #include #endif +#ifdef HAVE_NETINET_IN_H +#include +#endif + #ifdef HAVE_STDIO_H #include #endif @@ -73,14 +77,15 @@ #include #endif -#ifdef MEM_DEBUG -#include -#endif - #include "nanohttp-logging.h" +#include "nanohttp-common.h" +#include "nanohttp-socket.h" +#include "nanohttp-stream.h" +#include "nanohttp-request.h" #include "nanohttp-server.h" #include "nanohttp-base64.h" #include "nanohttp-ssl.h" +#include "nanohttp-admin.h" typedef struct _conndata { @@ -118,9 +123,6 @@ static hservice_t *_httpd_services_tail = NULL; static conndata_t *_httpd_connection; -static int _httpd_enable_service_list = 0; -static int _httpd_enable_statistics = 0; - #ifdef WIN32 static DWORD _httpd_terminate_signal = CTRL_C_EVENT; static int _httpd_max_idle = 120; @@ -176,6 +178,7 @@ _httpd_connection_slots_init(void) #else pthread_mutex_init(&_httpd_connection_lock, NULL); #endif + _httpd_connection = calloc(_httpd_max_connections, sizeof(conndata_t)); for (i = 0; i < _httpd_max_connections; i++) hsocket_init(&(_httpd_connection[i].sock)); @@ -183,17 +186,13 @@ _httpd_connection_slots_init(void) return; } -static void -_httpd_register_builtin_services(void) +static void +_httpd_register_builtin_services(int argc, char **argv) { + herror_t status; - if (_httpd_enable_service_list) - ; /* httpd_register("/httpd/services", - _httpd_list_services); */ - - if (_httpd_enable_statistics) - ; /* httpd_register("/httpd/statistics", - _httpd_statistics); */ + if ((status = httpd_admin_init_args(argc, argv)) != H_OK) + log_error2("httpd_admin_init_args failed (%s)", herror_message(status)); return; } @@ -218,15 +217,7 @@ httpd_init(int argc, char *argv[]) _httpd_connection_slots_init(); - _httpd_register_builtin_services(); - -#ifdef WIN32 - /* - if (_beginthread (WSAReaper, 0, NULL) == -1) { log_error1 ("Winsock - reaper thread failed to start"); return herror_new("httpd_init", - THREAD_BEGIN_ERROR, "_beginthread() failed while starting WSAReaper"); } - */ -#endif + _httpd_register_builtin_services(argc, argv); if ((status = hsocket_init(&_httpd_socket)) != H_OK) { @@ -253,6 +244,16 @@ httpd_register_secure(const char *ctx, httpd_service func, httpd_auth auth) return -1; } + if (!(service->statistics = (struct service_statistics *)malloc(sizeof(struct service_statistics)))) + { + log_error2("malloc failed (%s)", strerror(errno)); + return -1; + } + memset(service->statistics, 0, sizeof(struct service_statistics)); + service->statistics->time.tv_sec = 0; + service->statistics->time.tv_usec = 0; + pthread_rwlock_init(&(service->statistics->lock), NULL); + service->next = NULL; service->auth = auth; service->func = func; @@ -319,7 +320,7 @@ httpd_set_timeout(int t) const char * httpd_get_protocol(void) { - return hssl_enabled()? "https" : "http"; + return hssl_enabled() ? "https" : "http"; } /*-------------------------------------------------- @@ -328,28 +329,24 @@ FUNCTION: httpd_get_conncount int httpd_get_conncount(void) { - int i; - int c=0; + int i, ret; - for (i = 0;i<_httpd_max_connections; i++) + for (ret = i = 0; i<_httpd_max_connections; i++) { - if (_httpd_connection[i].flag == CONNECTION_IN_USE) - { - c++; - } + ret++; } - return c; + return ret; } /* * ----------------------------------------------------- - * FUNCTION: httpd_services + * FUNCTION: httpd_get_services * ----------------------------------------------------- */ hservice_t * -httpd_services(void) +httpd_get_services(void) { return _httpd_services_head; } @@ -372,18 +369,15 @@ hservice_free(hservice_t * service) * FUNCTION: httpd_find_service * ----------------------------------------------------- */ -static hservice_t * -httpd_find_service(const char *ctx) +hservice_t * +httpd_find_service(const char *context) { - hservice_t *cur = _httpd_services_head; + hservice_t *cur; - while (cur != NULL) + for (cur = _httpd_services_head; cur; cur = cur->next) { - if (!strcmp(cur->ctx, ctx)) - { + if (!strcmp(cur->ctx, context)) return cur; - } - cur = cur->next; } return _httpd_services_default; @@ -546,24 +540,6 @@ httpd_free(httpd_conn_t * conn) return; } -void -do_req_timeout(int signum) -{ -/* - struct sigaction req_timeout; - memset(&req_timeout, 0, sizeof(&req_timeout)); - req_timeout.sa_handler=SIG_IGN; - sigaction(SIGALRM, &req_timeout, NULL); -*/ - - /* XXX this is not real pretty, is there a better way? */ - log_verbose1("Thread timeout."); -#ifdef WIN32 - _endthread(); -#else - pthread_exit(0); -#endif -} static int _httpd_decode_authorization(const char *value, char **user, char **pass) @@ -657,8 +633,12 @@ httpd_session_main(void *data) httpd_conn_t *rconn; hservice_t *service; herror_t status; + struct timeval start, end, duration; int done; + if (gettimeofday(&start, NULL) == -1) + log_error2("gettimeofday failed (%s)", strerror(errno)); + conn = (conndata_t *) data; log_verbose2("starting new httpd session on socket %d", conn->sock); @@ -708,13 +688,27 @@ httpd_session_main(void *data) { log_verbose3("service '%s' for '%s' found", service->ctx, req->path); + pthread_rwlock_wrlock(&(service->statistics->lock)); + service->statistics->requests++; + pthread_rwlock_unlock(&(service->statistics->lock)); + if (_httpd_authenticate_request(req, service->auth)) { if (service->func != NULL) { service->func(rconn, req); - if (rconn->out - && rconn->out->type == HTTP_TRANSFER_CONNECTION_CLOSE) + + if (gettimeofday(&end, NULL) == -1) + log_error2("gettimeofday failed (%s)", strerror(errno)); + timersub(&end, &start, &duration); + + pthread_rwlock_wrlock(&(service->statistics->lock)); + service->statistics->bytes_received += rconn->sock->bytes_received; + service->statistics->bytes_transmitted += rconn->sock->bytes_transmitted; + timeradd(&(service->statistics->time), &duration, &(service->statistics->time)); + pthread_rwlock_unlock(&(service->statistics->lock)); + + if (rconn->out && rconn->out->type == HTTP_TRANSFER_CONNECTION_CLOSE) { log_verbose1("Connection close requested"); done = 1; @@ -735,11 +729,13 @@ httpd_session_main(void *data) { char *template = "" - "" - "Unauthorized" + "" + "Unauthorized" "" "" - "

      Unauthorized request logged

      " "" ""; + "

      Unauthorized request logged

      " + "" + ""; httpd_set_header(rconn, HEADER_WWW_AUTHENTICATE, "Basic realm=\"nanoHTTP\""); @@ -1259,8 +1255,7 @@ httpd_mime_next(httpd_conn_t * conn, const char *content_id, /* Send boundary */ status = - http_output_stream_write(conn->out, (const byte_t *) buffer, - strlen(buffer)); + http_output_stream_write(conn->out, buffer, strlen(buffer)); if (status != H_OK) return status; @@ -1274,8 +1269,7 @@ httpd_mime_next(httpd_conn_t * conn, const char *content_id, content_id ? content_id : ""); status = - http_output_stream_write(conn->out, (const byte_t *) buffer, - strlen(buffer)); + http_output_stream_write(conn->out, buffer, strlen(buffer)); return status; } @@ -1289,7 +1283,7 @@ httpd_mime_send_file(httpd_conn_t * conn, const char *content_id, const char *content_type, const char *transfer_encoding, const char *filename) { - byte_t buffer[MAX_FILE_BUFFER_SIZE]; + unsigned char buffer[MAX_FILE_BUFFER_SIZE]; herror_t status; FILE *fd; size_t size; @@ -1343,8 +1337,7 @@ httpd_mime_end(httpd_conn_t * conn) /* Send boundary */ status = - http_output_stream_write(conn->out, (const byte_t *) buffer, - strlen(buffer)); + http_output_stream_write(conn->out, buffer, strlen(buffer)); if (status != H_OK) return status; diff --git a/nanohttp/nanohttp-server.h b/nanohttp/nanohttp-server.h index a5e1be1..f132285 100644 --- a/nanohttp/nanohttp-server.h +++ b/nanohttp/nanohttp-server.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-server.h,v 1.21 2006/05/31 19:39:34 mrcsys Exp $ + * $Id: nanohttp-server.h,v 1.22 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -21,15 +21,8 @@ * * Email: ferhatayaz@yahoo.com ******************************************************************/ -#ifndef NANO_HTTP_SERVER_H -#define NANO_HTTP_SERVER_H - - -#include -#include -#include -#include - +#ifndef __nanohttp_server_h +#define __nanohttp_server_h typedef struct httpd_conn @@ -49,6 +42,14 @@ typedef void (*httpd_service) (httpd_conn_t *, hrequest_t *); typedef int (*httpd_auth) (hrequest_t * req, const char *user, const char *password); +struct service_statistics { + unsigned long requests; + unsigned long bytes_transmitted; + unsigned long bytes_received; + struct timeval time; + pthread_rwlock_t lock; +}; + /* * Service representation object */ @@ -58,6 +59,7 @@ typedef struct tag_hservice httpd_service func; httpd_auth auth; struct tag_hservice *next; + struct service_statistics *statistics; } hservice_t; @@ -91,7 +93,8 @@ extern "C" const char *httpd_get_protocol(void); int httpd_get_conncount(void); - hservice_t *httpd_services(void); + hservice_t *httpd_get_services(void); + hservice_t *httpd_find_service(const char *name); herror_t httpd_send_header(httpd_conn_t * res, int code, const char *text); diff --git a/nanohttp/nanohttp-socket.c b/nanohttp/nanohttp-socket.c index dbb79c7..d9e8900 100644 --- a/nanohttp/nanohttp-socket.c +++ b/nanohttp/nanohttp-socket.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-socket.c,v 1.61 2006/07/09 16:24:19 snowdrop Exp $ +* $Id: nanohttp-socket.c,v 1.62 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -70,8 +70,6 @@ #include #include -#define inline - #ifndef __MINGW32__ typedef int ssize_t; #endif @@ -81,17 +79,13 @@ typedef int ssize_t; #endif -#ifdef MEM_DEBUG -#include -#endif - #include "nanohttp-logging.h" -#include "nanohttp-socket.h" #include "nanohttp-common.h" +#include "nanohttp-socket.h" #include "nanohttp-ssl.h" #ifdef WIN32 -static inline void +static void _hsocket_module_sys_init(int argc, char **argv) { struct WSAData info; @@ -100,7 +94,7 @@ _hsocket_module_sys_init(int argc, char **argv) return; } -static inline void +static void _hsocket_module_sys_destroy(void) { WSACleanup(); @@ -150,7 +144,6 @@ FUNCTION: hsocket_init herror_t hsocket_init(hsocket_t * sock) { - memset(sock, 0, sizeof(hsocket_t)); sock->sock = HSOCKET_FREE; @@ -220,7 +213,7 @@ hsocket_open(hsocket_t * dsock, const char *hostname, int port, int ssl) FUNCTION: hsocket_bind ----------------------------------------------------*/ herror_t -hsocket_bind(hsocket_t * dsock, int port) +hsocket_bind(hsocket_t * dsock, unsigned short port) { hsocket_t sock; struct sockaddr_in addr; @@ -237,7 +230,7 @@ hsocket_bind(hsocket_t * dsock, int port) setsockopt(sock.sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); /* bind socket */ addr.sin_family = AF_INET; - addr.sin_port = htons((unsigned short) port); /* short, network byte order */ + addr.sin_port = htons(port); addr.sin_addr.s_addr = INADDR_ANY; memset(&(addr.sin_zero), '\0', 8); /* zero the rest of the struct */ @@ -350,7 +343,7 @@ hsocket_listen(hsocket_t * sock) } #ifdef WIN32 -static inline void +static void _hsocket_sys_close(hsocket_t * sock) { char junk[10]; @@ -359,7 +352,7 @@ _hsocket_sys_close(hsocket_t * sock) shutdown(sock->sock, SD_SEND); while (recv(sock->sock, junk, sizeof(junk), 0) > 0); - /* nothing */ + /* nothing */ closesocket(sock->sock); return; @@ -389,6 +382,9 @@ hsocket_close(hsocket_t * sock) _hsocket_sys_close(sock); + sock->bytes_received = 0; + sock->bytes_transmitted = 0; + log_verbose1("socket closed"); return; @@ -398,7 +394,7 @@ hsocket_close(hsocket_t * sock) FUNCTION: hsocket_send ----------------------------------------------------*/ herror_t -hsocket_nsend(hsocket_t * sock, const byte_t * bytes, int n) +hsocket_nsend(hsocket_t * sock, const unsigned char * bytes, int n) { herror_t status; size_t total = 0; @@ -439,31 +435,29 @@ hsocket_send(hsocket_t * sock, const char *str) } int -hsocket_select_read(int sock, char *buf, size_t len) +hsocket_select_recv(int sock, char *buf, size_t len) { struct timeval timeout; fd_set fds; - int ret; + FD_ZERO(&fds); FD_SET(sock, &fds); + timeout.tv_sec = httpd_get_timeout(); timeout.tv_usec = 0; - ret = select(sock + 1, &fds, NULL, NULL, &timeout); - if (ret == 0) + + if (select(sock + 1, &fds, NULL, NULL, &timeout) == 0) { errno = ETIMEDOUT; log_verbose2("Socket %d timeout", sock); return -1; } -#ifdef WIN32 + return recv(sock, buf, len, 0); -#else - return read(sock, buf, len); -#endif } herror_t -hsocket_read(hsocket_t * sock, byte_t * buffer, int total, int force, +hsocket_read(hsocket_t * sock, unsigned char * buffer, int total, int force, int *received) { herror_t status; diff --git a/nanohttp/nanohttp-socket.h b/nanohttp/nanohttp-socket.h index eb805fd..9bb88b5 100644 --- a/nanohttp/nanohttp-socket.h +++ b/nanohttp/nanohttp-socket.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-socket.h,v 1.29 2006/05/01 17:56:32 mrcsys Exp $ + * $Id: nanohttp-socket.h,v 1.30 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -21,25 +21,8 @@ * * Email: ayaz@jprogrammer.net ******************************************************************/ -#ifndef NANO_HTTP_SOCKET_H -#define NANO_HTTP_SOCKET_H - -#include - -#include - -#ifdef HAVE_SSL -#include -#endif - -#ifdef WIN32 -#include -#else -#include -#include -#endif - -#include +#ifndef __nanohttp_socket_h +#define __nanohttp_socket_h #define HSOCKET_FREE -1 @@ -54,6 +37,8 @@ typedef struct hsocket_t int sock; #endif struct sockaddr_in addr; + size_t bytes_transmitted; + size_t bytes_received; void *ssl; } hsocket_t; /* end of socket definition */ @@ -138,7 +123,7 @@ extern "C" @see hsocket_listen */ - herror_t hsocket_bind(hsocket_t * sock, int port); + herror_t hsocket_bind(hsocket_t * sock, unsigned short port); /** @@ -166,7 +151,7 @@ extern "C"
      HSOCKET_ERROR_NOT_INITIALIZED
      HSOCKET_ERROR_ACCEPT */ - herror_t hsocket_accept(hsocket_t * sock, hsocket_t * dest); + herror_t hsocket_accept(hsocket_t *sock, hsocket_t *dest); /** @@ -180,7 +165,7 @@ extern "C"
      HSOCKET_ERROR_NOT_INITIALIZED
      HSOCKET_ERROR_SEND */ - herror_t hsocket_nsend(hsocket_t * sock, const byte_t * bytes, int size); + herror_t hsocket_nsend(hsocket_t * sock, const unsigned char *bytes, int size); /** @@ -213,7 +198,7 @@ extern "C" the socket. */ - herror_t hsocket_read(hsocket_t * sock, byte_t * buffer, int size, + herror_t hsocket_read(hsocket_t * sock, unsigned char *buffer, int size, int force, int *readed); #ifdef __cplusplus diff --git a/nanohttp/nanohttp-ssl.c b/nanohttp/nanohttp-ssl.c index a1f4ffb..d8e6e3f 100644 --- a/nanohttp/nanohttp-ssl.c +++ b/nanohttp/nanohttp-ssl.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-ssl.c,v 1.28 2006/07/09 16:24:19 snowdrop Exp $ +* $Id: nanohttp-ssl.c,v 1.29 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2001-2005 Rochester Institute of Technology @@ -448,7 +448,7 @@ static int _hssl_bio_read(BIO * b, char *out, int outl) { - return hsocket_select_read(b->num, out, outl);; + return hsocket_select_recv(b->num, out, outl);; } herror_t @@ -532,10 +532,11 @@ hssl_read(hsocket_t * sock, char *buf, size_t len, size_t * received) } else { - if ((count = hsocket_select_read(sock->sock, buf, len)) == -1) + if ((count = hsocket_select_recv(sock->sock, buf, len)) == -1) return herror_new("hssl_read", HSOCKET_ERROR_RECEIVE, "recv failed (%s)", strerror(errno)); } + sock->bytes_received += count; *received = count; return H_OK; @@ -562,6 +563,7 @@ hssl_write(hsocket_t * sock, const char *buf, size_t len, size_t * sent) return herror_new("hssl_write", HSOCKET_ERROR_SEND, "send failed (%s)", strerror(errno)); } + sock->bytes_transmitted += count; *sent = count; return H_OK; @@ -574,10 +576,12 @@ hssl_read(hsocket_t * sock, char *buf, size_t len, size_t * received) { int count; - if ((count = hsocket_select_read(sock->sock, buf, len)) == -1) + if ((count = hsocket_select_recv(sock->sock, buf, len)) == -1) return herror_new("hssl_read", HSOCKET_ERROR_RECEIVE, "recv failed (%s)", strerror(errno)); + sock->bytes_received += count; *received = count; + return H_OK; } @@ -590,7 +594,9 @@ hssl_write(hsocket_t * sock, const char *buf, size_t len, size_t * sent) if ((count = send(sock->sock, buf, len, 0)) == -1) return herror_new("hssl_write", HSOCKET_ERROR_SEND, "send failed (%s)", strerror(errno)); + sock->bytes_received += count; *sent = count; + return H_OK; } diff --git a/nanohttp/nanohttp-ssl.h b/nanohttp/nanohttp-ssl.h index 12f3fcf..e81668d 100644 --- a/nanohttp/nanohttp-ssl.h +++ b/nanohttp/nanohttp-ssl.h @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-ssl.h,v 1.18 2006/05/15 06:40:47 m0gg Exp $ +* $Id: nanohttp-ssl.h,v 1.19 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2001-2005 Rochester Institute of Technology @@ -21,8 +21,8 @@ * * Author: Matt Campbell ******************************************************************/ -#ifndef __NANOHTTP_SSL_H_ -#define __NANOHTTP_SSL_H_ +#ifndef __nanohttp_ssl_h +#define __nanohttp_ssl_h #ifdef HAVE_CONFIG_H #include @@ -50,6 +50,7 @@ extern "C" void hssl_set_certificate(char *c); void hssl_set_certpass(char *c); void hssl_set_ca(char *c); + void hssl_enable(void); int hssl_enabled(void); diff --git a/nanohttp/nanohttp-stream.c b/nanohttp/nanohttp-stream.c index bda1a2c..27d8d62 100755 --- a/nanohttp/nanohttp-stream.c +++ b/nanohttp/nanohttp-stream.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-stream.c,v 1.13 2006/07/09 16:24:19 snowdrop Exp $ +* $Id: nanohttp-stream.c,v 1.14 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -29,6 +29,10 @@ #include #endif +#ifdef HAVE_STDLIB_H +#include +#endif + #ifdef HAVE_STRING_H #include #endif @@ -37,20 +41,18 @@ #include #endif -#ifdef MEM_DEBUG -#include +#ifdef HAVE_NETINET_IN_H +#include #endif +#include "nanohttp-common.h" +#include "nanohttp-socket.h" #include "nanohttp-logging.h" #include "nanohttp-stream.h" -/* -------------------------------------------------------------------- - +/*------------------------------------------------------------ HTTP INPUT STREAM - -------------------------------------------------------------------- -*/ +------------------------------------------------------------*/ static int _http_stream_is_content_length(hpair_t * header) @@ -200,8 +202,7 @@ _http_input_stream_is_file_ready(http_input_stream_t * stream) } static int -_http_input_stream_content_length_read(http_input_stream_t * stream, - byte_t * dest, int size) +_http_input_stream_content_length_read(http_input_stream_t * stream, unsigned char *dest, int size) { herror_t status; int read; @@ -211,8 +212,7 @@ _http_input_stream_content_length_read(http_input_stream_t * stream, size = stream->content_length - stream->received; /* read from socket */ - status = hsocket_read(stream->sock, dest, size, 1, &read); - if (status != H_OK) + if ((status = hsocket_read(stream->sock, dest, size, 1, &read)) != H_OK) { stream->err = status; return -1; @@ -282,7 +282,7 @@ _http_input_stream_chunked_read_chunk_size(http_input_stream_t * stream) } static int -_http_input_stream_chunked_read(http_input_stream_t * stream, byte_t * dest, +_http_input_stream_chunked_read(http_input_stream_t * stream, unsigned char *dest, int size) { int status, counter; @@ -387,7 +387,7 @@ _http_input_stream_chunked_read(http_input_stream_t * stream, byte_t * dest, static int _http_input_stream_connection_closed_read(http_input_stream_t * stream, - byte_t * dest, int size) + unsigned char *dest, int size) { int status; herror_t err; @@ -407,8 +407,7 @@ _http_input_stream_connection_closed_read(http_input_stream_t * stream, } static int -_http_input_stream_file_read(http_input_stream_t * stream, byte_t * dest, - int size) +_http_input_stream_file_read(http_input_stream_t * stream, unsigned char *dest, int size) { size_t len; @@ -456,7 +455,7 @@ http_input_stream_is_ready(http_input_stream_t * stream) <0 on error */ int -http_input_stream_read(http_input_stream_t * stream, byte_t * dest, int size) +http_input_stream_read(http_input_stream_t * stream, unsigned char *dest, int size) { int len = 0; /* paranoia check */ @@ -569,7 +568,7 @@ http_output_stream_free(http_output_stream_t * stream) */ herror_t http_output_stream_write(http_output_stream_t * stream, - const byte_t * bytes, int size) + const unsigned char *bytes, int size) { herror_t status; char chunked[15]; diff --git a/nanohttp/nanohttp-stream.h b/nanohttp/nanohttp-stream.h index 88e5f97..88e783e 100755 --- a/nanohttp/nanohttp-stream.h +++ b/nanohttp/nanohttp-stream.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-stream.h,v 1.10 2006/03/06 13:37:38 m0gg Exp $ + * $Id: nanohttp-stream.h,v 1.11 2006/11/19 09:40:14 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -21,13 +21,8 @@ * * Email: ferhatayaz@yahoo.com ******************************************************************/ -#ifndef NANO_HTTP_STREAM_H -#define NANO_HTTP_STREAM_H - -#include - -#include -#include +#ifndef __nanohttp_stream_h +#define __nanohttp_stream_h /* HTTP Stream modul: @@ -88,7 +83,7 @@ typedef struct http_input_stream int received; int content_length; int chunk_size; - byte_t connection_closed; + char connection_closed; /* file handling */ FILE *fd; @@ -194,7 +189,7 @@ int http_input_stream_is_ready(http_input_stream_t * stream); @returns the actual readed bytes or -1 on error. */ int http_input_stream_read(http_input_stream_t * stream, - byte_t * dest, int size); + unsigned char* dest, int size); /* @@ -241,7 +236,7 @@ void http_output_stream_free(http_output_stream_t * stream);
      HSOCKET_ERROR_SEND */ herror_t http_output_stream_write(http_output_stream_t * stream, - const byte_t * bytes, int size); + const unsigned char* bytes, int size); /** Writes a null terminated string to the stream. -- cgit v1.1-32-gdbae