From 088da5ce241680069c8881de30f29bed5639a065 Mon Sep 17 00:00:00 2001 From: m0gg Date: Sat, 2 Dec 2006 21:50:47 +0000 Subject: Added XML preamble --- nanohttp/nanohttp-admin.c | 81 +++++++++++++++++++++++++--- nanohttp/nanohttp-admin.h | 33 ++++++++++-- nanohttp/nanohttp-client.c | 66 +++++++---------------- nanohttp/nanohttp-client.h | 5 +- nanohttp/nanohttp-server.c | 127 +++++++++++++++++++++++++++---------------- nanohttp/nanohttp-server.h | 132 ++++++++++++++++++++++++++------------------- 6 files changed, 279 insertions(+), 165 deletions(-) (limited to 'nanohttp') diff --git a/nanohttp/nanohttp-admin.c b/nanohttp/nanohttp-admin.c index d5d5939..29462a0 100644 --- a/nanohttp/nanohttp-admin.c +++ b/nanohttp/nanohttp-admin.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-admin.c,v 1.6 2006/11/25 16:35:57 m0gg Exp $ +* $Id: nanohttp-admin.c,v 1.7 2006/12/02 21:50:47 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -66,7 +66,6 @@ _httpd_admin_send_title(httpd_conn_t *conn, const char *title) return; } - static void _httpd_admin_list_services(httpd_conn_t *conn) { @@ -78,7 +77,16 @@ _httpd_admin_list_services(httpd_conn_t *conn) http_output_stream_write_string(conn->out, ""); @@ -88,7 +96,6 @@ _httpd_admin_list_services(httpd_conn_t *conn) return; } - static void _httpd_admin_list_statistics(httpd_conn_t *conn, const char *service_name) { @@ -100,8 +107,9 @@ _httpd_admin_list_statistics(httpd_conn_t *conn, const char *service_name) if (!(service = httpd_find_service(service_name))) { - http_output_stream_write_string(conn->out, "service not found!"); - http_output_stream_write_string(conn->out, ""); + http_output_stream_write_string(conn->out, + "

Service not found!

" + ""); return; } @@ -126,6 +134,57 @@ _httpd_admin_list_statistics(httpd_conn_t *conn, const char *service_name) return; } +static void +_httpd_admin_enable_service(httpd_conn_t *conn, const char *service_name) +{ + hservice_t *service; + char buffer[1024]; + + sprintf(buffer, "Enabling 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!

" + ""); + return; + } + + httpd_enable_service(service); + + http_output_stream_write_string(conn->out, + "

Service enabled

" + ""); + + return; +} + +static void +_httpd_admin_disable_service(httpd_conn_t *conn, const char *service_name) +{ + hservice_t *service; + char buffer[1024]; + + sprintf(buffer, "Disabling 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!

" + ""); + return; + } + + httpd_disable_service(service); + + http_output_stream_write_string(conn->out, + "

Service disabled

" + ""); + + return; +} static void _httpd_admin_handle_get(httpd_conn_t * conn, struct hrequest_t *req) @@ -140,6 +199,14 @@ _httpd_admin_handle_get(httpd_conn_t * conn, struct hrequest_t *req) { _httpd_admin_list_statistics(conn, param); } + else if ((param = hpairnode_get_ignore_case(req->query, NHTTPD_ADMIN_QUERY_ENABLE_SERVICE))) + { + _httpd_admin_enable_service(conn, param); + } + else if ((param = hpairnode_get_ignore_case(req->query, NHTTPD_ADMIN_QUERY_DISABLE_SERVICE))) + { + _httpd_admin_disable_service(conn, param); + } else { _httpd_admin_send_title(conn, "Welcome to the admin site"); @@ -155,7 +222,6 @@ _httpd_admin_handle_get(httpd_conn_t * conn, struct hrequest_t *req) return; } - static void _httpd_admin_entry(httpd_conn_t * conn, struct hrequest_t *req) { @@ -180,7 +246,6 @@ _httpd_admin_entry(httpd_conn_t * conn, struct hrequest_t *req) return; } - herror_t httpd_admin_init_args(int argc, char **argv) { diff --git a/nanohttp/nanohttp-admin.h b/nanohttp/nanohttp-admin.h index 64550e9..02cc18e 100644 --- a/nanohttp/nanohttp-admin.h +++ b/nanohttp/nanohttp-admin.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-admin.h,v 1.3 2006/12/01 10:56:00 m0gg Exp $ + * $Id: nanohttp-admin.h,v 1.4 2006/12/02 21:50:47 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -32,7 +32,7 @@ * @see NHTTPD_ADMIN_CONTEXT * */ -#define NHTTPD_ARG_ENABLE_ADMIN "-NHTTPDadmin" +#define NHTTPD_ARG_ENABLE_ADMIN "-NHTTPDadmin" /** * @@ -45,7 +45,7 @@ * @see httpd_register * */ -#define NHTTPD_ADMIN_CONTEXT "/nhttp" +#define NHTTPD_ADMIN_CONTEXT "/nhttp" /** * @@ -56,7 +56,7 @@ * http://localhost:10000/nhttp?services=list * */ -#define NHTTPD_ADMIN_QUERY_SERVICES "services" +#define NHTTPD_ADMIN_QUERY_SERVICES "services" /** * @@ -67,7 +67,30 @@ * http://localhost:10000/nhttp?statistics=SERVICE_CONTEXT * */ -#define NHTTPD_ADMIN_QUERY_STATISTICS "statistics" +#define NHTTPD_ADMIN_QUERY_STATISTICS "statistics" + + +/** + * + * Parameter to enable a server. + * + * Example query: + * + * http://localhost:10000/nhttp?enable=SERVICE_CONTEXT + * + */ +#define NHTTPD_ADMIN_QUERY_ENABLE_SERVICE "enable" + +/** + * + * Parameter to disable a service. + * + * Example query: + * + * http://localhost:10000/nhttp?disable=SERVICE_CONTEXT + * + */ +#define NHTTPD_ADMIN_QUERY_DISABLE_SERVICE "disable" #ifdef __cplusplus extern "C" { diff --git a/nanohttp/nanohttp-client.c b/nanohttp/nanohttp-client.c index 1c4c6d7..53aba83 100644 --- a/nanohttp/nanohttp-client.c +++ b/nanohttp/nanohttp-client.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-client.c,v 1.48 2006/11/30 14:23:59 m0gg Exp $ +* $Id: nanohttp-client.c,v 1.49 2006/12/02 21:50:47 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -61,6 +61,10 @@ #include #endif +#ifdef WIN32 +#define snprintf(buffer, num, s1, s2) sprintf(buffer, s1,s2) +#endif + #include "nanohttp-logging.h" #include "nanohttp-error.h" #include "nanohttp-common.h" @@ -71,21 +75,12 @@ #include "nanohttp-base64.h" #include "nanohttp-client.h" -/*-------------------------------------------------- -FUNCTION: httpc_init -DESC: Initialize http client connection -NOTE: This will be called from soap_client_init_args() -----------------------------------------------------*/ herror_t httpc_init(int argc, char **argv) { return hsocket_module_init(argc, argv); } -/*-------------------------------------------------- -FUNCTION: httpc_destroy -DESC: Destroy the http client module -----------------------------------------------------*/ void httpc_destroy(void) { @@ -94,12 +89,6 @@ httpc_destroy(void) return; } -/*-------------------------------------------------- -FUNCTION: httpc_new -DESC: Creates a new http client connection object -You need to create at least 1 http client connection -to communicate via http. -----------------------------------------------------*/ httpc_conn_t * httpc_new(void) { @@ -135,10 +124,6 @@ httpc_new(void) return res; } -/*-------------------------------------------------- -FUNCTION: httpc_free -DESC: Free the given http client object. -----------------------------------------------------*/ void httpc_free(httpc_conn_t * conn) { @@ -167,10 +152,6 @@ httpc_free(httpc_conn_t * conn) return; } -/*-------------------------------------------------- - FUNCTION: httpc_close_free - DESC: Close and free the given http client object. - ----------------------------------------------------*/ void httpc_close_free(httpc_conn_t * conn) { @@ -256,6 +237,7 @@ _httpc_set_basic_authorization_header(httpc_conn_t *conn, const char *key, const if (!password) password = ""; + /* XXX: do we need this really? */ memset(in, 0, 64); memset(out, 0, 64); @@ -280,10 +262,6 @@ httpc_set_basic_proxy_authorization(httpc_conn_t *conn, const char *user, const return _httpc_set_basic_authorization_header(conn, HEADER_PROXY_AUTHORIZATION, user, password); } -/*-------------------------------------------------- -FUNCTION: httpc_header_set_date -DESC: Adds the current date to the header. -----------------------------------------------------*/ static void httpc_header_set_date(httpc_conn_t * conn) { @@ -300,7 +278,6 @@ httpc_header_set_date(httpc_conn_t * conn) return; } - /*-------------------------------------------------- FUNCTION: httpc_send_header DESC: Sends the current header information stored @@ -511,12 +488,12 @@ _httpc_mime_get_boundary(httpc_conn_t * conn, char *dest) { sprintf(dest, "---=.Part_NH_%d", conn->id); log_verbose2("boundary= \"%s\"", dest); + + return; } herror_t -httpc_mime_begin(httpc_conn_t * conn, const char *url, - const char *related_start, - const char *related_start_info, const char *related_type) +httpc_mime_begin(httpc_conn_t * conn, const char *url, const char *related_start, const char *related_start_info, const char *related_type) { herror_t status; char buffer[300]; @@ -529,12 +506,6 @@ httpc_mime_begin(httpc_conn_t * conn, const char *url, */ sprintf(buffer, "multipart/related;"); - /* - using sprintf instead of snprintf because visual c does not support - snprintf */ -#ifdef WIN32 -#define snprintf(buffer, num, s1, s2) sprintf(buffer, s1,s2) -#endif if (related_type) { @@ -565,9 +536,7 @@ httpc_mime_begin(httpc_conn_t * conn, const char *url, } herror_t -httpc_mime_next(httpc_conn_t * conn, - const char *content_id, - const char *content_type, const char *transfer_encoding) +httpc_mime_next(httpc_conn_t * conn, const char *content_id, const char *content_type, const char *transfer_encoding) { herror_t status; char buffer[512]; @@ -625,19 +594,19 @@ httpc_mime_end(httpc_conn_t * conn, hresponse_t ** out) with next part */ herror_t -httpc_mime_send_file(httpc_conn_t * conn, - const char *content_id, - const char *content_type, - const char *transfer_encoding, const char *filename) +httpc_mime_send_file(httpc_conn_t * conn, const char *content_id, const char *content_type, const char *transfer_encoding, const char *filename) { herror_t status; - FILE *fd = fopen(filename, "rb"); + FILE *fd; unsigned char buffer[MAX_FILE_BUFFER_SIZE]; size_t size; - if (fd == NULL) + if ((fd = fopen(filename, "rb")) == NULL) + { + log_error2("fopen failed (%s)", strerror(errno)); return herror_new("httpc_mime_send_file", FILE_ERROR_OPEN, - "Can not open file '%s'", filename); + "Can not open file \"%s\" (%s)", filename, strerror(errno)); + } status = httpc_mime_next(conn, content_id, content_type, transfer_encoding); if (status != H_OK) @@ -670,5 +639,6 @@ httpc_mime_send_file(httpc_conn_t * conn, fclose(fd); log_verbose1("file sent!"); + return H_OK; } diff --git a/nanohttp/nanohttp-client.h b/nanohttp/nanohttp-client.h index 6e5d4c9..69807f7 100644 --- a/nanohttp/nanohttp-client.h +++ b/nanohttp/nanohttp-client.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-client.h,v 1.28 2006/11/30 14:24:00 m0gg Exp $ + * $Id: nanohttp-client.h,v 1.29 2006/12/02 21:50:47 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -76,7 +76,8 @@ extern void httpc_destroy(void); /** * - * Creates a new connection. + * Creates a new http client connection object. You need to create at least one + * http client connection to communicate via HTTP. * * @return A pointer to a httpc_conn_t structure on success, NULL on error. * diff --git a/nanohttp/nanohttp-server.c b/nanohttp/nanohttp-server.c index 87d740c..1efb0e5 100644 --- a/nanohttp/nanohttp-server.c +++ b/nanohttp/nanohttp-server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-server.c,v 1.72 2006/11/30 14:24:00 m0gg Exp $ +* $Id: nanohttp-server.c,v 1.73 2006/12/02 21:50:47 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -292,6 +292,7 @@ httpd_register_secure(const char *ctx, httpd_service func, httpd_auth auth) if (!(service->statistics = (struct service_statistics *)malloc(sizeof(struct service_statistics)))) { log_error2("malloc failed (%s)", strerror(errno)); + free(service); return herror_new("httpd_register_secure", 0, "malloc failed (%s)", strerror(errno)); } memset(service->statistics, 0, sizeof(struct service_statistics)); @@ -302,6 +303,7 @@ httpd_register_secure(const char *ctx, httpd_service func, httpd_auth auth) service->next = NULL; service->auth = auth; service->func = func; + service->status = NHTTPD_SERVICE_ENABLED; strcpy(service->ctx, ctx); log_verbose3("register service (%p) for \"%s\"", service, SAVE_STR(ctx)); @@ -392,11 +394,37 @@ httpd_get_services(void) static void hservice_free(hservice_t * service) { + if (!service) + return; + + if (service->statistics) + free(service->statistics); + free(service); return; } +int httpd_enable_service(hservice_t *service) +{ + int ret; + + ret = service->status; + service->status = NHTTPD_SERVICE_ENABLED; + + return ret; +} + +int httpd_disable_service(hservice_t *service) +{ + int ret; + + ret = service->status; + service->status = NHTTPD_SERVICE_DISABLED; + + return ret; +} + hservice_t * httpd_find_service(const char *context) { @@ -564,7 +592,6 @@ _httpd_decode_authorization(const char *value, char **user, char **pass) len = strlen(value) * 2; if (!(tmp = (char *) calloc(1, len))) { - log_error2("calloc failed (%s)", strerror(errno)); return -1; } @@ -692,60 +719,68 @@ 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 (service->status == NHTTPD_SERVICE_ENABLED) + { + 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) + if (_httpd_authenticate_request(req, service->auth)) { - service->func(rconn, req); - - 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) + if (service->func != NULL) { - log_verbose1("Connection close requested"); - done = 1; + service->func(rconn, req); + + 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; + } } - } + else + { + char buffer[256]; + + sprintf(buffer, "service '%s' not registered properly (func == NULL)", req->path); + log_verbose1(buffer); + httpd_send_internal_error(rconn, buffer); + } + } else { - char buffer[256]; - - sprintf(buffer, - "service '%s' not registered properly (func == NULL)", - req->path); - log_verbose1(buffer); - httpd_send_internal_error(rconn, buffer); + char *template = + "" + "" + "Unauthorized" + "" + "" + "

Unauthorized request logged

" + "" + ""; + + 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); + done = 1; } } else { - char *template = - "" - "" - "Unauthorized" - "" - "" - "

Unauthorized request logged

" - "" - ""; - - 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); - done = 1; + char buffer[256]; + + sprintf(buffer, "service for '%s' is disabled", req->path); + log_verbose1(buffer); + httpd_send_internal_error(rconn, buffer); } } else diff --git a/nanohttp/nanohttp-server.h b/nanohttp/nanohttp-server.h index 1b74344..8f56d4e 100644 --- a/nanohttp/nanohttp-server.h +++ b/nanohttp/nanohttp-server.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-server.h,v 1.26 2006/11/30 14:24:00 m0gg Exp $ + * $Id: nanohttp-server.h,v 1.27 2006/12/02 21:50:48 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -83,6 +83,20 @@ struct service_statistics }; #endif +/** + * + * @see hservice_t + * + */ +#define NHTTPD_SERVICE_DISABLED 0 + +/** + * + * @see hservice_t + * + */ +#define NHTTPD_SERVICE_ENABLED 1 + /** * * Service representation object @@ -91,6 +105,7 @@ struct service_statistics typedef struct tag_hservice { char ctx[255]; + int status; httpd_service func; httpd_auth auth; struct tag_hservice *next; @@ -103,83 +118,88 @@ extern "C" { #endif +/** + * + * Initialize the nanoHTTP server. + * + */ +extern herror_t httpd_init(int argc, char *argv[]); -/* - Begin httpd_* function set +/** + * + * @see httpd_init + * */ - extern herror_t httpd_init(int argc, char *argv[]); - extern void httpd_destroy(void); +extern void httpd_destroy(void); - extern herror_t httpd_run(void); - extern herror_t httpd_register(const char *ctx, httpd_service service); - extern herror_t httpd_register_secure(const char *ctx, httpd_service service, httpd_auth auth); +extern herror_t httpd_run(void); - extern herror_t httpd_register_default(const char *ctx, httpd_service service); - extern herror_t httpd_register_default_secure(const char *ctx, httpd_service service, httpd_auth auth); +extern herror_t httpd_register(const char *ctx, httpd_service service); +extern herror_t httpd_register_secure(const char *ctx, httpd_service service, httpd_auth auth); - extern short httpd_get_port(void); - extern int httpd_get_timeout(void); - extern void httpd_set_timeout(int secs); +extern herror_t httpd_register_default(const char *ctx, httpd_service service); +extern herror_t httpd_register_default_secure(const char *ctx, httpd_service service, httpd_auth auth); - extern const char *httpd_get_protocol(void); - extern int httpd_get_conncount(void); +extern short httpd_get_port(void); +extern int httpd_get_timeout(void); +extern void httpd_set_timeout(int secs); - extern hservice_t *httpd_get_services(void); - extern hservice_t *httpd_find_service(const char *name); +extern const char *httpd_get_protocol(void); +extern int httpd_get_conncount(void); - extern void httpd_response_set_content_type(httpd_conn_t * res, const char *content_type); +extern hservice_t *httpd_get_services(void); +extern hservice_t *httpd_find_service(const char *name); - extern herror_t httpd_send_header(httpd_conn_t * res, int code, const char *text); +extern int httpd_enable_service(hservice_t *service); +extern int httpd_disable_service(hservice_t *service); - extern int httpd_set_header(httpd_conn_t * conn, const char *key, const char *value); - extern void httpd_set_headers(httpd_conn_t * conn, hpair_t * header); +extern void httpd_response_set_content_type(httpd_conn_t * res, const char *content_type); - extern int httpd_add_header(httpd_conn_t * conn, const char *key, const char *value); - extern void httpd_add_headers(httpd_conn_t * conn, const hpair_t * values); +extern herror_t httpd_send_header(httpd_conn_t * res, int code, const char *text); + +extern int httpd_set_header(httpd_conn_t * conn, const char *key, const char *value); +extern void httpd_set_headers(httpd_conn_t * conn, hpair_t * header); + +extern int httpd_add_header(httpd_conn_t * conn, const char *key, const char *value); +extern void httpd_add_headers(httpd_conn_t * conn, const hpair_t * values); -/* -------------------------------------------------------------- - MIME RELATED FUNCTIONS - ---------------------------------------------------------------*/ /* - MIME support httpd_mime_* function set -*/ + * XXX: move to nanohttp-mime.c + * + * MIME support httpd_mime_* function set + */ /** - Begin MIME multipart/related POST - Returns: HSOCKET_OK or error flag -*/ - extern herror_t httpd_mime_send_header(httpd_conn_t * conn, - const char *related_start, - const char *related_start_info, - const char *related_type, int code, - const char *text); + * + * MIME multipart/related POST + * @returns H_OK on success or error flag + * + */ +extern herror_t httpd_mime_send_header(httpd_conn_t * conn, const char *related_start, const char *related_start_info, const char *related_type, int code, const char *text); /** - Send boundary and part header and continue - with next part -*/ - extern herror_t httpd_mime_next(httpd_conn_t * conn, - const char *content_id, - const char *content_type, - const char *transfer_encoding); + * + * Send boundary and part header and continue with next part + * + */ +extern herror_t httpd_mime_next(httpd_conn_t * conn, const char *content_id, const char *content_type, const char *transfer_encoding); /** - Send boundary and part header and continue - with next part -*/ - extern herror_t httpd_mime_send_file(httpd_conn_t * conn, - const char *content_id, - const char *content_type, - const char *transfer_encoding, - const char *filename); + * + * Send boundary and part header and continue with next part + * + */ +extern herror_t httpd_mime_send_file(httpd_conn_t * conn, const char *content_id, const char *content_type, const char *transfer_encoding, const char *filename); /** - Finish MIME request - Returns: HSOCKET_OK or error flag -*/ - extern herror_t httpd_mime_end(httpd_conn_t * conn); - + * + * Finish MIME request + * + * @return H_OK on success or error flag + * + */ +extern herror_t httpd_mime_end(httpd_conn_t * conn); #ifdef __cplusplus } -- cgit v1.1-32-gdbae