From b73c5d785a71edade3ba473cbb13ec57aaeec7ed Mon Sep 17 00:00:00 2001 From: snowdrop Date: Mon, 27 Feb 2006 22:26:01 +0000 Subject: - removes a memleak in examples/csoap/simpleserver.c say_hello - adds various malloc error messages - does some libcsoap/*.c #include fixups - removes a memleak in libcsoap/soap-server.c soap_server_entry - removes the double free of SoapCtx->action (again!!!) - rewrites more or less cleanly hsocket_close - adds volatile keywords for thread shared data items - _httpd_parse_arguments cleanup - rwerites the _httpd_connection initialization - adds a call to pthread_attr_destroy in httpd_session_main - fixes a wrong loop initialization in _httpd_wait_for_emtpy_conn - fixes a memleak in httpd_session_main (req) - more sophisticated httpd_server example - HTTP authentication SEGfault without password fixed --- examples/csoap/simpleserver.c | 3 +- examples/nanohttp/http_server.c | 131 +++++++++++++++++++-- libcsoap/soap-ctx.c | 31 ++++- libcsoap/soap-env.c | 26 ++++- libcsoap/soap-fault.c | 13 ++- libcsoap/soap-router.c | 10 +- libcsoap/soap-server.c | 44 +++++--- libcsoap/soap-service.c | 14 ++- libcsoap/soap-xml.c | 8 +- nanohttp/nanohttp-client.c | 8 +- nanohttp/nanohttp-client.h | 10 +- nanohttp/nanohttp-common.c | 4 +- nanohttp/nanohttp-common.h | 30 +++-- nanohttp/nanohttp-mime.c | 4 +- nanohttp/nanohttp-mime.h | 10 +- nanohttp/nanohttp-request.c | 38 ++++--- nanohttp/nanohttp-request.h | 10 +- nanohttp/nanohttp-response.c | 21 +++- nanohttp/nanohttp-response.h | 10 +- nanohttp/nanohttp-server.c | 244 +++++++++++++++++++++++----------------- nanohttp/nanohttp-server.h | 10 +- nanohttp/nanohttp-socket.c | 73 ++++++------ nanohttp/nanohttp-socket.h | 17 ++- nanohttp/nanohttp-ssl.h | 8 +- nanohttp/nanohttp-stream.c | 83 +++++++++----- nanohttp/nanohttp-stream.h | 15 +-- win32/MinGW/Makefile | 7 +- 27 files changed, 577 insertions(+), 305 deletions(-) diff --git a/examples/csoap/simpleserver.c b/examples/csoap/simpleserver.c index 8e181d9..cde4e79 100644 --- a/examples/csoap/simpleserver.c +++ b/examples/csoap/simpleserver.c @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: simpleserver.c,v 1.17 2006/01/11 09:18:17 snowdrop Exp $ + * $Id: simpleserver.c,v 1.18 2006/02/27 22:26:01 snowdrop Exp $ * * CSOAP Project: CSOAP examples project * Copyright (C) 2003-2004 Ferhat Ayaz @@ -52,6 +52,7 @@ say_hello(SoapCtx * req, SoapCtx * res) name = (char *) xmlNodeListGetString(node->doc, node->xmlChildrenNode, 1); soap_env_add_itemf(res->env, "xsd:string", "echo", "Hello '%s'", name); node = soap_xml_get_next(node); + xmlFree(name); } return H_OK; diff --git a/examples/nanohttp/http_server.c b/examples/nanohttp/http_server.c index 2f939f9..f8a0536 100644 --- a/examples/nanohttp/http_server.c +++ b/examples/nanohttp/http_server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: http_server.c,v 1.1 2006/02/19 08:45:13 snowdrop Exp $ +* $Id: http_server.c,v 1.2 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C (example) * Copyright (C) 2003 Ferhat Ayaz @@ -22,42 +22,157 @@ * Email: hero@persua.de ******************************************************************/ #include +#include #include static int simple_authenticator(const char *user, const char *password) { - log_verbose3("loggin in user=\"%s\" password=\"%s\"", user, password); + + log_info3("logging in user=\"%s\" password=\"%s\"", user, password); + + if (strcmp(user, "bob")) { + + log_warn2("user \"%s\" unkown", user); + return 0; + } + + if (strcmp(password, "builder")) { + + log_warn1("wrong password"); + return 0; + } return 1; } -static void simple_service(httpd_conn_t *conn, hrequest_t *req) +static void secure_service(httpd_conn_t *conn, hrequest_t *req) +{ + + httpd_send_header(conn, 200, "OK"); + hsocket_send(conn->sock, + "" + "" + "Secure ressource!" + "" + "" + "

Authenticated access!!!

" + "" + ""); + + return; +} + +static void default_service(httpd_conn_t *conn, hrequest_t *req) { + httpd_send_header(conn, 404, "Not found"); + hsocket_send(conn->sock, + "" + "" + "Default error page" + "" + "" + "

Default error page

" + "
"); + + hsocket_send(conn->sock, req->path); + + hsocket_send(conn->sock, " can not be found" + "
" + "" + ""); + + return; +} + +static void headers_service(httpd_conn_t *conn, hrequest_t *req) +{ + hpair_t *walker; + + httpd_send_header(conn, 200, "OK"); + hsocket_send(conn->sock, + "" + "" + "Request headers" + "" + "" + "

Request headers

" + "
    "); + + for (walker=req->header; walker; walker=walker->next) + { + hsocket_send(conn->sock, "
  • "); + hsocket_send(conn->sock, walker->key); + hsocket_send(conn->sock, " = "); + hsocket_send(conn->sock, walker->value); + hsocket_send(conn->sock, "
  • "); + } + + hsocket_send(conn->sock, + "
" + "" + ""); + + return; +} + +static void root_service(httpd_conn_t *conn, hrequest_t *req) +{ httpd_send_header(conn, 200, "OK"); - hsocket_send(conn->sock, "Success!

Success!!!

"); + hsocket_send(conn->sock, + "" + "" + "nanoHTTP server examples" + "" + "" + "

nanoHTTP server examples

" + "" + "" + ""); return; } int main(int argc, char *argv[]) { - log_set_level(HLOG_VERBOSE); + log_set_level(HLOG_INFO); if (httpd_init(argc, argv)) { - fprintf(stderr, "can not init httpd"); + fprintf(stderr, "Can not init httpd"); return 1; } - if (!httpd_register_secure("/", simple_service, simple_authenticator)) - { + if (!httpd_register("/", root_service)) { fprintf(stderr, "Can not register service"); return 1; } + if (!httpd_register_secure("/secure", secure_service, simple_authenticator)) { + + fprintf(stderr, "Can not register secure service"); + return 1; + } + + if (!httpd_register("/headers", headers_service)) { + + fprintf(stderr, "Can not register headers service"); + return 1; + } + + if (!httpd_register_default("/error", default_service)) { + + fprintf(stderr, "Can not register default service"); + return 1; + } + if (httpd_run()) { fprintf(stderr, "can not run httpd"); diff --git a/libcsoap/soap-ctx.c b/libcsoap/soap-ctx.c index dd68861..a06b897 100755 --- a/libcsoap/soap-ctx.c +++ b/libcsoap/soap-ctx.c @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-ctx.c,v 1.8 2006/02/18 20:14:36 snowdrop Exp $ + * $Id: soap-ctx.c,v 1.9 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -21,14 +21,35 @@ * * Email: ferhatayaz@jprogrammer.net ******************************************************************/ +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_STDIO_H +#include +#endif + +#ifdef HAVE_STRING_H #include +#endif + +#ifdef HAVE_ERRNO_H +#include +#endif -#include +#include "soap-ctx.h" SoapCtx * soap_ctx_new(SoapEnv * env) /* should only be used internally */ { - SoapCtx *ctx = (SoapCtx *) malloc(sizeof(SoapCtx)); + SoapCtx *ctx; + + if (!(ctx = (SoapCtx *) malloc(sizeof(SoapCtx)))) + { + log_error2("malloc failed (%s)", strerror(errno)); + return NULL; + } + ctx->env = env; ctx->attachments = NULL; ctx->action = NULL; @@ -132,12 +153,16 @@ soap_ctx_free(SoapCtx * ctx) if (ctx->attachments) attachments_free(ctx->attachments); + if (ctx->env) soap_env_free(ctx->env); + if (ctx->action) free(ctx->action); free(ctx); + + return; } diff --git a/libcsoap/soap-env.c b/libcsoap/soap-env.c index cb55bd2..8f4df35 100644 --- a/libcsoap/soap-env.c +++ b/libcsoap/soap-env.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-env.c,v 1.16 2006/02/25 10:09:28 snowdrop Exp $ +* $Id: soap-env.c,v 1.17 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -21,11 +21,27 @@ * * Email: ayaz@jprogrammer.net ******************************************************************/ +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_STDARG_H #include +#endif + +#ifdef HAVE_STDIO_H #include +#endif + +#ifdef HAVE_STRING_H #include +#endif + +#ifdef HAVE_ERRNO_H +#include +#endif -#include +#include "soap-env.h" #ifdef WIN32 #define USE_XMLSTRING @@ -128,7 +144,11 @@ soap_env_new_from_doc(xmlDocPtr doc, SoapEnv ** out) XML_ERROR_EMPTY_DOCUMENT, "XML Document is empty!"); } - env = (SoapEnv *) malloc(sizeof(SoapEnv)); + if (!(env = (SoapEnv *) malloc(sizeof(SoapEnv)))) + { + log_error2("malloc failed (%s)", strerror(errno)); + return herror_new("soap_env_from_doc", GENERAL_INVALID_PARAM, "malloc failed"); + } /* set root */ env->root = node; diff --git a/libcsoap/soap-fault.c b/libcsoap/soap-fault.c index 1e6cae8..edeb688 100644 --- a/libcsoap/soap-fault.c +++ b/libcsoap/soap-fault.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-fault.c,v 1.8 2006/01/10 11:29:04 snowdrop Exp $ +* $Id: soap-fault.c,v 1.9 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -21,9 +21,16 @@ * * Email: ayaz@jprogrammer.net ******************************************************************/ -#include -#include +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_STRING_H #include +#endif + +#include "soap-fault.h" +#include "soap-xml.h" static char *soap_env_ns = "http://schemas.xmlsoap.org/soap/envelope/"; static char *soap_env_enc = "http://schemas.xmlsoap.org/soap/encoding/"; diff --git a/libcsoap/soap-router.c b/libcsoap/soap-router.c index fc26916..7b93b03 100644 --- a/libcsoap/soap-router.c +++ b/libcsoap/soap-router.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-router.c,v 1.6 2006/02/18 20:14:36 snowdrop Exp $ +* $Id: soap-router.c,v 1.7 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -21,9 +21,15 @@ * * Email: ayaz@jprogrammer.net ******************************************************************/ +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_STRING_H #include +#endif -#include +#include "soap-router.h" SoapRouter * soap_router_new(void) diff --git a/libcsoap/soap-server.c b/libcsoap/soap-server.c index 68d6f16..eade02a 100644 --- a/libcsoap/soap-server.c +++ b/libcsoap/soap-server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-server.c,v 1.17 2006/02/18 20:14:36 snowdrop Exp $ +* $Id: soap-server.c,v 1.18 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -21,11 +21,17 @@ * * Email: ayaz@jprogrammer.net ******************************************************************/ +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_STRING_H #include +#endif #include -#include +#include "soap-server.h" typedef struct _SoapRouterNode { @@ -54,13 +60,15 @@ _soap_server_send_env(http_output_stream_t * out, SoapEnv * env) } static void -_soap_server_send_fault(httpd_conn_t * conn, hpair_t * header, - const char *errmsg) +_soap_server_send_fault(httpd_conn_t * conn, const char *errmsg) { SoapEnv *envres; + hpair_t *header; herror_t err; char buffer[45]; + header = hpairnode_new(HEADER_CONTENT_TYPE, "text/xml", NULL); + httpd_set_headers(conn, header); if ((err = httpd_send_header(conn, 500, "FAILED")) != H_OK) @@ -92,12 +100,14 @@ _soap_server_send_fault(httpd_conn_t * conn, hpair_t * header, http_output_stream_write_string(conn->out, ""); herror_release(err); - return; } else { _soap_server_send_env(conn->out, envres); } + + hpairnode_free(header); + return; } @@ -209,7 +219,6 @@ router_find(const char *context) static void soap_server_entry(httpd_conn_t * conn, hrequest_t * req) { - hpair_t *header = NULL; char buffer[1054]; char *urn; char *method; @@ -232,12 +241,10 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req) } - header = hpairnode_new(HEADER_CONTENT_TYPE, "text/xml", NULL); - err = soap_env_new_from_stream(req->in, &env); if (err != H_OK) { - _soap_server_send_fault(conn, header, herror_message(err)); + _soap_server_send_fault(conn, herror_message(err)); herror_release(err); return; } @@ -246,7 +253,7 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req) if (env == NULL) { - _soap_server_send_fault(conn, header, "Can not receive POST data!"); + _soap_server_send_fault(conn, "Can not receive POST data!"); } else @@ -254,13 +261,16 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req) ctx = soap_ctx_new(env); ctx->action = hpairnode_get_ignore_case(req->header, "SoapAction"); + if (ctx->action) + ctx->action = strdup(ctx->action); + ctx->http = req; soap_ctx_add_files(ctx, req->attachments); if (ctx->env == NULL) { - _soap_server_send_fault(conn, header, "Can not parse POST data!"); + _soap_server_send_fault(conn, "Can not parse POST data!"); } else @@ -273,7 +283,7 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req) if (router == NULL) { - _soap_server_send_fault(conn, header, "Can not find router!"); + _soap_server_send_fault(conn, "Can not find router!"); } else @@ -282,7 +292,7 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req) if (!(urn=soap_env_find_urn(ctx->env))) { - _soap_server_send_fault(conn, header, "No URN found!"); + _soap_server_send_fault(conn, "No URN found!"); soap_ctx_free(ctx); return; } @@ -294,7 +304,7 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req) if (!(method=soap_env_find_methodname(ctx->env))) { - _soap_server_send_fault(conn, header, "No method found!"); + _soap_server_send_fault(conn, "No method found!"); soap_ctx_free(ctx); return; } @@ -309,7 +319,7 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req) { sprintf(buffer, "URN '%s' not found", urn); - _soap_server_send_fault(conn, header, buffer); + _soap_server_send_fault(conn, buffer); soap_ctx_free(ctx); return; } @@ -327,7 +337,7 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req) sprintf(buffer, "Service returned following error message: '%s'", herror_message(err)); herror_release(err); - _soap_server_send_fault(conn, header, buffer); + _soap_server_send_fault(conn, buffer); soap_ctx_free(ctx); return; } @@ -336,7 +346,7 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req) { sprintf(buffer, "Service '%s' returned no envelope", urn); - _soap_server_send_fault(conn, header, buffer); + _soap_server_send_fault(conn, buffer); soap_ctx_free(ctx); return; diff --git a/libcsoap/soap-service.c b/libcsoap/soap-service.c index 376daa7..fd72ce6 100644 --- a/libcsoap/soap-service.c +++ b/libcsoap/soap-service.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-service.c,v 1.6 2006/01/10 11:29:04 snowdrop Exp $ +* $Id: soap-service.c,v 1.7 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -21,9 +21,17 @@ * * Email: ayaz@jprogrammer.net ******************************************************************/ -#include -#include +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_STRING_H #include +#endif + +#include + +#include "soap-service.h" SoapServiceNode * soap_service_node_new(SoapService * service, SoapServiceNode * next) diff --git a/libcsoap/soap-xml.c b/libcsoap/soap-xml.c index 62b0b7d..37487d3 100644 --- a/libcsoap/soap-xml.c +++ b/libcsoap/soap-xml.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-xml.c,v 1.9 2006/02/08 11:13:14 snowdrop Exp $ +* $Id: soap-xml.c,v 1.10 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -21,7 +21,11 @@ * * Email: ayaz@jprogrammer.net ******************************************************************/ -#include +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "soap-xml.h" xmlNodePtr soap_xml_get_children(xmlNodePtr param) diff --git a/nanohttp/nanohttp-client.c b/nanohttp/nanohttp-client.c index 802e021..09605b9 100644 --- a/nanohttp/nanohttp-client.c +++ b/nanohttp/nanohttp-client.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-client.c,v 1.38 2006/02/18 20:14:36 snowdrop Exp $ +* $Id: nanohttp-client.c,v 1.39 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -147,7 +147,7 @@ httpc_close_free(httpc_conn_t * conn) if (conn == NULL) return; - hsocket_close(conn->sock); + hsocket_close(&(conn->sock)); httpc_free(conn); return; @@ -363,7 +363,7 @@ httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn, if ((status = hsocket_send(conn->sock, buffer)) != H_OK) { log_error2("Can not send request (status:%d)", status); - hsocket_close(conn->sock); + hsocket_close(&(conn->sock)); return status; } @@ -371,7 +371,7 @@ httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn, if ((status = httpc_send_header(conn)) != H_OK) { log_error2("Can not send header (status:%d)", status); - hsocket_close(conn->sock); + hsocket_close(&(conn->sock)); return status; } diff --git a/nanohttp/nanohttp-client.h b/nanohttp/nanohttp-client.h index d77f80f..5562ea6 100644 --- a/nanohttp/nanohttp-client.h +++ b/nanohttp/nanohttp-client.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-client.h,v 1.21 2006/02/27 00:00:14 snowdrop Exp $ + * $Id: nanohttp-client.h,v 1.22 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -24,10 +24,6 @@ #ifndef NANO_HTTP_CLIENT_H #define NANO_HTTP_CLIENT_H -#ifdef __cplusplus -extern "C" { -#endif - #include #include #include @@ -50,6 +46,10 @@ typedef struct httpc_conn } httpc_conn_t; +#ifdef __cplusplus +extern "C" { +#endif + /* -------------------------------------------------------------- HTTP CLIENT MODULE RELATED FUNCTIONS ---------------------------------------------------------------*/ diff --git a/nanohttp/nanohttp-common.c b/nanohttp/nanohttp-common.c index 1f2040d..f49cc85 100644 --- a/nanohttp/nanohttp-common.c +++ b/nanohttp/nanohttp-common.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-common.c,v 1.27 2006/02/18 20:14:36 snowdrop Exp $ +* $Id: nanohttp-common.c,v 1.28 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -53,7 +53,7 @@ #include #endif -#include +#include "nanohttp-common.h" #define MAX_OPTION_SIZE 50 #define MAX_OPTION_VALUE_SIZE 150 diff --git a/nanohttp/nanohttp-common.h b/nanohttp/nanohttp-common.h index 736f84c..307f349 100644 --- a/nanohttp/nanohttp-common.h +++ b/nanohttp/nanohttp-common.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-common.h,v 1.26 2006/02/27 00:26:23 snowdrop Exp $ + * $Id: nanohttp-common.h,v 1.27 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -24,10 +24,6 @@ #ifndef NANO_HTTP_COMMON_H #define NANO_HTTP_COMMON_H -#ifdef __cplusplus -extern "C" { -#endif - #include #include @@ -157,17 +153,6 @@ Set Sleep function platform depended #define system_sleep(seconds) sleep(seconds); #endif -#ifdef WIN32 -#include -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; - - - /** Indicates the version of the used HTTP protocol. @@ -189,6 +174,19 @@ typedef enum _hreq_method } hreq_method_t; +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef WIN32 +#include +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, ...); int herror_code(herror_t err); char *herror_func(herror_t err); diff --git a/nanohttp/nanohttp-mime.c b/nanohttp/nanohttp-mime.c index 10926fe..5ab5592 100755 --- a/nanohttp/nanohttp-mime.c +++ b/nanohttp/nanohttp-mime.c @@ -3,7 +3,7 @@ * | \/ | | | | \/ | | _/ * |_''_| |_| |_''_| |_'/ PARSER * -* $Id: nanohttp-mime.c,v 1.10 2006/02/18 20:14:36 snowdrop Exp $ +* $Id: nanohttp-mime.c,v 1.11 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -45,7 +45,7 @@ Buffered Reader. A helper object to read bytes from a source #include #endif -#include +#include "nanohttp-mime.h" /* ------------------------------------------------------------------ diff --git a/nanohttp/nanohttp-mime.h b/nanohttp/nanohttp-mime.h index bf3c8c0..f63535a 100755 --- a/nanohttp/nanohttp-mime.h +++ b/nanohttp/nanohttp-mime.h @@ -3,7 +3,7 @@ * | \/ | | | | \/ | | _/ * |_''_| |_| |_''_| |_'/ PARSER * -* $Id: nanohttp-mime.h,v 1.7 2006/02/27 00:26:23 snowdrop Exp $ +* $Id: nanohttp-mime.h,v 1.8 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -29,14 +29,12 @@ #ifndef NANO_HTTP_MIME_PARSER_H #define NANO_HTTP_MIME_PARSER_H -#ifdef __cplusplus -extern "C" { -#endif - #include #include -#include +#ifdef __cplusplus +extern "C" { +#endif /* ------------------------------------------------------------------ "multipart/related" MIME Message Builder diff --git a/nanohttp/nanohttp-request.c b/nanohttp/nanohttp-request.c index 98880f2..1a3e998 100755 --- a/nanohttp/nanohttp-request.c +++ b/nanohttp/nanohttp-request.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-request.c,v 1.10 2006/02/18 20:14:36 snowdrop Exp $ +* $Id: nanohttp-request.c,v 1.11 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -25,24 +25,35 @@ #include #endif +#ifdef HAVE_STDIO_H +#include +#endif + #ifdef HAVE_STRING_H #include #endif +#ifdef HAVE_ERRNO_H +#include +#endif + #ifdef MEM_DEBUG #include #endif -#include -#include - -/* request stuff */ - +#include "nanohttp-common.h" +#include "nanohttp-request.h" static hrequest_t * hrequest_new() { - hrequest_t *req = (hrequest_t *) malloc(sizeof(hrequest_t)); + hrequest_t *req; + + if (!(req = (hrequest_t *) malloc(sizeof(hrequest_t)))) { + + log_error2("malloc failed (%s)", strerror(errno)); + return NULL; + } req->method = HTTP_REQUEST_GET; req->version = HTTP_1_1; @@ -147,7 +158,11 @@ _hrequest_parse_header(char *data) /* create option pair */ if (opt_key != NULL) { - tmppair = (hpair_t *) malloc(sizeof(hpair_t)); + if (!(tmppair = (hpair_t *) malloc(sizeof(hpair_t)))) + { + log_error2("malloc failed (%s)", strerror(errno)); + return NULL; + } if (req->query == NULL) { @@ -161,11 +176,8 @@ _hrequest_parse_header(char *data) /* fill hpairnode_t struct */ qpair->next = NULL; - qpair->key = (char *) malloc(strlen(opt_key) + 1); - qpair->value = (char *) malloc(strlen(opt_value) + 1); - - strcpy(qpair->key, opt_key); - strcpy(qpair->value, opt_value); + qpair->key = strdup(opt_key); + qpair->value = strdup(opt_value); } } diff --git a/nanohttp/nanohttp-request.h b/nanohttp/nanohttp-request.h index d89fa91..c0c014c 100755 --- a/nanohttp/nanohttp-request.h +++ b/nanohttp/nanohttp-request.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-request.h,v 1.5 2006/02/27 00:26:23 snowdrop Exp $ + * $Id: nanohttp-request.h,v 1.6 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -24,10 +24,6 @@ #ifndef NANO_HTTP_REQUEST_H #define NANO_HTTP_REQUEST_H -#ifdef __cplusplus -extern "C" { -#endif - #include #include @@ -49,6 +45,10 @@ typedef struct hrequest char root_part_id[150]; } hrequest_t; +#ifdef __cplusplus +extern "C" { +#endif + herror_t hrequest_new_from_socket(hsocket_t sock, hrequest_t ** out); void hrequest_free(hrequest_t * req); diff --git a/nanohttp/nanohttp-response.c b/nanohttp/nanohttp-response.c index cf728e4..64eac44 100755 --- a/nanohttp/nanohttp-response.c +++ b/nanohttp/nanohttp-response.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-response.c,v 1.8 2006/02/18 20:14:36 snowdrop Exp $ +* $Id: nanohttp-response.c,v 1.9 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -25,16 +25,24 @@ #include #endif +#ifdef HAVE_STDIO_H +#include +#endif + #ifdef HAVE_STRING_H #include #endif +#ifdef HAVE_ERRNO_H +#include +#endif + #ifdef MEM_DEBUG #include #endif -#include -#include +#include "nanohttp-common.h" +#include "nanohttp-response.h" static hresponse_t * hresponse_new() @@ -42,7 +50,12 @@ hresponse_new() hresponse_t *res; /* create response object */ - res = (hresponse_t *) malloc(sizeof(hresponse_t)); + if (!(res = (hresponse_t *) malloc(sizeof(hresponse_t)))) { + + log_error2("malloc failed (%s)", strerror(errno)); + return NULL; + } + res->version = HTTP_1_1; res->errcode = -1; res->desc[0] = '\0'; diff --git a/nanohttp/nanohttp-response.h b/nanohttp/nanohttp-response.h index bd7bb50..3b3f532 100755 --- a/nanohttp/nanohttp-response.h +++ b/nanohttp/nanohttp-response.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-response.h,v 1.5 2006/02/27 00:26:23 snowdrop Exp $ + * $Id: nanohttp-response.h,v 1.6 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -24,10 +24,6 @@ #ifndef NANO_HTTP_RESPONSE_H #define NANO_HTTP_RESPONSE_H -#ifdef __cplusplus -extern "C" { -#endif - #include #include #include @@ -47,6 +43,10 @@ typedef struct hresponse char root_part_id[150]; } hresponse_t; +#ifdef __cplusplus +extern "C" { +#endif + herror_t hresponse_new_from_socket(hsocket_t sock, hresponse_t ** out); void hresponse_free(hresponse_t * res); diff --git a/nanohttp/nanohttp-server.c b/nanohttp/nanohttp-server.c index c885a72..d60c797 100644 --- a/nanohttp/nanohttp-server.c +++ b/nanohttp/nanohttp-server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-server.c,v 1.50 2006/02/21 16:40:47 mrcsys Exp $ +* $Id: nanohttp-server.c,v 1.51 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -29,6 +29,10 @@ #include #endif +#ifdef HAVE_SOCKET_H +#include +#endif + #ifdef HAVE_SYS_TIME_H #include #endif @@ -57,17 +61,16 @@ #include #endif -#ifdef HAVE_PTHREAD_H -#include +#ifdef HAVE_ERRNO_H +#include #endif -#ifdef HAVE_SOCKET_H -#include +#ifdef HAVE_PTHREAD_H +#include #endif -#ifdef WIN32 +#ifdef HAVE_PROCESS_H #include -#define snprintf(buffer, num, s1, s2) sprintf(buffer, s1,s2) #endif #ifdef MEM_DEBUG @@ -97,13 +100,15 @@ conndata_t; * internally globals * ----------------------------------------------------- */ +static volatile int _httpd_run = 1; + +static hsocket_t _httpd_socket; static int _httpd_port = 10000; static int _httpd_max_connections = 20; -static hsocket_t _httpd_socket; + static hservice_t *_httpd_services_default = NULL; static hservice_t *_httpd_services_head = NULL; static hservice_t *_httpd_services_tail = NULL; -static int _httpd_run = 1; static conndata_t *_httpd_connection; #ifdef WIN32 @@ -111,15 +116,42 @@ static DWORD _httpd_terminate_signal = CTRL_C_EVENT; static int _httpd_max_idle = 120; static void WSAReaper (void *x); #define strncasecmp(s1, s2, num) strncmp(s1, s2, num) +#define snprintf(buffer, num, s1, s2) sprintf(buffer, s1,s2) #else static int _httpd_terminate_signal = SIGINT; static sigset_t thrsigset; #endif -#ifdef HAVE_SSL -/*extern SSL_CTX *SSLctx;*/ -#endif +static void +_httpd_parse_arguments(int argc, char **argv) +{ + int i; + /* write argument information */ + log_verbose1 ("Arguments:"); + for (i = 0; i < argc; i++) + log_verbose3 ("argv[%i] = '%s'", i, SAVE_STR (argv[i])); + + for (i = 1; i < argc; i++) + { + if (!strcmp (argv[i-1], NHTTPD_ARG_PORT)) + { + _httpd_port = atoi (argv[i]); + } + else if (!strcmp (argv[i-1], NHTTPD_ARG_TERMSIG)) + { + _httpd_terminate_signal = atoi (argv[i]); + } + else if (!strcmp (argv[i-1], NHTTPD_ARG_MAXCONN)) + { + _httpd_max_connections = atoi (argv[i]); + } + } + + log_verbose2 ("socket bind to port '%d'", _httpd_port); + + return; +} /* * ----------------------------------------------------- @@ -136,33 +168,14 @@ httpd_init (int argc, char *argv[]) char *SSLCert = NULL, *SSLPass = NULL, *SSLCA = NULL; #endif + /* XXX: two times argument parsing... */ hoption_init_args (argc, argv); + _httpd_parse_arguments(argc, argv); + if ((status = hsocket_module_init()) != H_OK) return status; - /* write argument information */ - 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]); - } - else if (!strcmp (argv[i], NHTTPD_ARG_MAXCONN) && i < argc - 1) - { - _httpd_max_connections = atoi (argv[i + 1]); - } - } - log_verbose2 ("socket bind to port '%d'", _httpd_port); /* init built-in services */ @@ -171,9 +184,7 @@ httpd_init (int argc, char *argv[]) _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])); - } + hsocket_init(&(_httpd_connection[i].sock)); #ifdef WIN32 /* @@ -183,7 +194,7 @@ httpd_init (int argc, char *argv[]) */ #endif - /* create socket */ + /* XXX: move SSL stuff to nanohttp-socket.c and handle this transparently */ #ifdef HAVE_SSL SSLCert = hoption_get(HOPTION_SSL_CERT); SSLPass = hoption_get(HOPTION_SSL_PASS); @@ -221,7 +232,7 @@ httpd_register_secure(const char *ctx, httpd_service func, httpd_auth auth) if (!(service = (hservice_t *) malloc (sizeof (hservice_t)))) { - log_error1("malloc failed"); + log_error2("malloc failed (%s)", strerror(errno)); return -1; } @@ -396,10 +407,13 @@ httpd_send_internal_error (httpd_conn_t * conn, const char *errmsg) char buffer[4064]; char buflen[5]; + sprintf (buffer, template1, errmsg); snprintf (buflen, 5, "%d", strlen (buffer)); + httpd_set_header (conn, HEADER_CONTENT_LENGTH, buflen); httpd_send_header (conn, 500, "INTERNAL"); + return hsocket_nsend (conn->sock, buffer, strlen (buffer)); } @@ -421,28 +435,29 @@ httpd_request_print (hrequest_t * req) (req->version == HTTP_1_0) ? "HTTP/1.0" : "HTTP/1.1"); log_verbose1 (" Parsed query string :"); - pair = req->query; - while (pair != NULL) - { + for (pair = req->query; pair; pair = pair->next) log_verbose3 (" %s = '%s'", pair->key, pair->value); - pair = pair->next; - } + log_verbose1 (" Parsed header :"); - pair = req->header; - while (pair != NULL) - { + for (pair = req->header; pair; pair = pair->next) log_verbose3 (" %s = '%s'", pair->key, pair->value); - pair = pair->next; - } + log_verbose1 ("++++++++++++++++++++++++"); + return; } httpd_conn_t * httpd_new (hsocket_t sock) { - httpd_conn_t *conn = (httpd_conn_t *) malloc (sizeof (httpd_conn_t)); + httpd_conn_t *conn; + + if (!(conn = (httpd_conn_t *) malloc (sizeof (httpd_conn_t)))) { + + log_error2("malloc failed (%s)", strerror(errno)); + return NULL; + } conn->sock = sock; conn->out = NULL; conn->content_type[0] = '\0'; @@ -455,15 +470,18 @@ httpd_new (hsocket_t sock) void httpd_free (httpd_conn_t * conn) { - if(!conn) - return; - if (conn->out != NULL) + if (!conn) + return; + + if (conn->out) http_output_stream_free (conn->out); - if (conn->header != NULL) + if (conn->header) hpairnode_free_deep (conn->header); free (conn); + + return; } void @@ -485,44 +503,44 @@ do_req_timeout (int signum) #endif } -static int httpd_decode_authorization(const char *value, char **user, char **pass) +static int _httpd_decode_authorization(const char *value, char **user, char **pass) { unsigned char *tmp, *tmp2; + size_t len; - tmp = malloc(strlen(value) * 2); -#ifdef WIN32 - memset(tmp, 0, strlen(value)*2); - value = strstr(value, ' '); -#else - bzero(tmp, strlen(value) * 2); - value = index(value, ' '); -#endif + len = strlen(value) * 2; + if (!(tmp = (char *)calloc(1, len))) { + + log_error2("malloc failed (%s)", strerror(errno)); + return -1; + } + value = strstr(value, " ") + 1; - value++; - log_debug2("Authorization (base64) = \"%s\"", value); + log_error2("Authorization (base64) = \"%s\"", value); base64_decode(value, tmp); - log_debug2("Authorization (ascii) = \"%s\"", tmp); + log_error2("Authorization (ascii) = \"%s\"", tmp); -#ifdef WIN32 - tmp2 = strstr(tmp, ':'); -#else - tmp2 = index(tmp, ':'); -#endif - *tmp2++ = '\0'; - - *pass = strdup(tmp2); + if ((tmp2 = strstr(tmp, ":"))) + { + *tmp2++ = '\0'; + *pass = strdup(tmp2); + } + else + { + *pass = strdup(""); + } *user = strdup(tmp); free(tmp); - return 1; + return 0; } -static int httpd_authenticate_request(hrequest_t *req, httpd_auth auth) +static int _httpd_authenticate_request(hrequest_t *req, httpd_auth auth) { char *user, *pass; char *authorization; @@ -532,17 +550,20 @@ static int httpd_authenticate_request(hrequest_t *req, httpd_auth auth) return 1; if (!(authorization = hpairnode_get_ignore_case(req->header, HEADER_AUTHORIZATION))) { + log_debug2("%s header not set", HEADER_AUTHORIZATION); return 0; } - if (!httpd_decode_authorization(authorization, &user, &pass)) + if (_httpd_decode_authorization(authorization, &user, &pass)) { log_error1("httpd_base64_decode_failed"); return 0; } - if (!(ret = auth(user, pass))) - log_info1("Authentication failed"); + if ((ret = auth(user, pass))) + log_info2("Access granted for user=\"%s\"", user); + else + log_info2("Authentication failed for user=\"%s\"", user); free(user); free(pass); @@ -563,19 +584,20 @@ 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); int done = 0; char buffer[256]; /* temp buffer for recv() */ char header[4064]; /* received header */ hrequest_t *req = NULL; /* only for test */ + conndata_t *conn; httpd_conn_t *rconn = NULL; hservice_t *service = NULL; herror_t status; header[0] = '\0'; len = 0; + conn = (conndata_t *) data; log_verbose1 ("starting httpd_session_main()"); #ifdef HAVE_SSL @@ -598,15 +620,19 @@ httpd_session_main (void *data) /* call the service */ /* req = hrequest_new_from_buffer (header);*/ + rconn = httpd_new (conn->sock); + while (!done) { log_verbose1 ("starting HTTP request"); - rconn = httpd_new (conn->sock); + /* XXX: only used in WSAreaper */ + conn->atime = time(NULL); if ((status = hrequest_new_from_socket (conn->sock, &req)) != H_OK) { /* "Request parse error!" */ + /* XXX: may be "socket read error" */ if (herror_code (status) != HSOCKET_ERROR_SSLCLOSE) { httpd_send_internal_error (rconn, herror_message (status)); @@ -617,7 +643,7 @@ httpd_session_main (void *data) else { char *conn_str = hpairnode_get_ignore_case (req->header, HEADER_CONNECTION); - if (conn_str && strncasecmp (conn_str, "close", 5) == 0) + if (conn_str && strncasecmp (conn_str, "close", 6) == 0) { done = 1; } @@ -627,12 +653,11 @@ httpd_session_main (void *data) } httpd_request_print (req); - service = httpd_find_service (req->path); - if (service != NULL) + if ((service = httpd_find_service (req->path))) { log_verbose3 ("service '%s' for '%s' found", service->ctx, req->path); - if (httpd_authenticate_request(req, service->auth)) { + if (_httpd_authenticate_request(req, service->auth)) { if (service->func != NULL) { @@ -649,33 +674,39 @@ httpd_session_main (void *data) httpd_send_internal_error (rconn, buffer); } } - else { + else { httpd_set_header(rconn, HEADER_WWW_AUTHENTICATE, "Basic realm=\"nanoHTTP\""); httpd_send_header(rconn, 401, "Unauthorized"); - hsocket_send(conn->sock, "Unauthorized

Unauthorized

"); - } + hsocket_send(conn->sock, "Unauthorized

Unauthorized request logged

"); + } } else { - sprintf (buffer, "service '%s' not found", req->path); + sprintf (buffer, "no service for '%s' found", req->path); log_verbose1 (buffer); httpd_send_internal_error (rconn, buffer); } + hrequest_free(req); } } - hsocket_close (conn->sock); - log_verbose1 ("Marking connection as available"); - conn->sock.sock = 0; - hrequest_free (req); - httpd_free (rconn); + httpd_free(rconn); + + hsocket_close (&(conn->sock)); #ifdef WIN32 CloseHandle ((HANDLE) conn->tid); +#else + pthread_attr_destroy(&(conn->attr)); +#endif + + hsocket_init(&(conn->sock)); + +#ifdef WIN32 _endthread (); return 0; -#else +#else /* pthread_exits automagically */ return NULL; #endif @@ -809,7 +840,7 @@ static conndata_t * _httpd_wait_for_empty_conn (void) { int i; - for (i = 0;; i++) + for (i = 0; ; i++) { if (!_httpd_run) return NULL; @@ -817,9 +848,9 @@ _httpd_wait_for_empty_conn (void) if (i >= _httpd_max_connections) { system_sleep (1); - i = 0; + i = -1; } - else if (_httpd_connection[i].sock.sock == 0) + else if (_httpd_connection[i].sock.sock == HSOCKET_FREE) { break; } @@ -947,11 +978,11 @@ httpd_run (void) && herror_code (err) == SSL_ERROR_INIT*/ ) { - hsocket_close (conn->sock); + hsocket_close(&(conn->sock)); hsocket_init(&(conn->sock)); - log_error1 (herror_message (err)); + log_error1(herror_message (err)); continue; } else if (err != H_OK) @@ -1061,14 +1092,17 @@ httpd_get_postdata (httpd_conn_t * conn, hrequest_t * req, long *received, if (content_length == 0) { *received = 0; - postdata = (char *) malloc (1); + if (!(postdata = (char *) malloc (1))) { + + log_error2("malloc failed (%s)", strerror(errno)); + return NULL; + } postdata[0] = '\0'; return postdata; } - postdata = (unsigned char *) malloc (content_length + 1); - if (postdata == NULL) + if (!(postdata = (unsigned char *) malloc (content_length + 1))) { - log_error1 ("Not enough memory"); + log_error2 ("malloc failed (%)", strerror(errno)); return NULL; } if (http_input_stream_read (req->in, postdata, (int) content_length) > 0) @@ -1082,8 +1116,6 @@ httpd_get_postdata (httpd_conn_t * conn, hrequest_t * req, long *received, } - - /* MIME support httpd_mime_* function set */ diff --git a/nanohttp/nanohttp-server.h b/nanohttp/nanohttp-server.h index bf7405d..1768edd 100644 --- a/nanohttp/nanohttp-server.h +++ b/nanohttp/nanohttp-server.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-server.h,v 1.14 2006/02/27 00:26:23 snowdrop Exp $ + * $Id: nanohttp-server.h,v 1.15 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -25,10 +25,6 @@ #define NANO_HTTP_SERVER_H -#ifdef __cplusplus -extern "C" { -#endif - #include #include #include @@ -63,6 +59,10 @@ typedef struct tag_hservice } hservice_t; +#ifdef __cplusplus +extern "C" { +#endif + /* Begin httpd_* function set diff --git a/nanohttp/nanohttp-socket.c b/nanohttp/nanohttp-socket.c index c3b2f85..77d4d9c 100644 --- a/nanohttp/nanohttp-socket.c +++ b/nanohttp/nanohttp-socket.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-socket.c,v 1.52 2006/02/21 21:26:58 mrcsys Exp $ +* $Id: nanohttp-socket.c,v 1.53 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -136,12 +136,8 @@ hsocket_init(hsocket_t * sock) { log_verbose1("Starting hsocket init"); -#ifdef WIN32 memset(sock, 0, sizeof(hsocket_t)); -#else - bzero(sock, sizeof(hsocket_t)); -#endif - sock->sock = -1; + sock->sock = HSOCKET_FREE; return H_OK; } @@ -342,49 +338,50 @@ hsocket_listen(hsocket_t sock) return H_OK; } -/*-------------------------------------------------- -FUNCTION: hsocket_close -----------------------------------------------------*/ -void -hsocket_close(hsocket_t sock) +#ifdef WIN32 +static inline void +_hsocket_sys_close(hsocket_t *sock) { char junk[10]; -/* _hsocket_wait_until_receive(sock);*/ - log_verbose2("closing socket %d...", sock.sock); -/* - struct linger _linger; - hsocket_block(sock,1); - _linger.l_onoff =1; - _linger.l_linger = 30000; - setsockopt(sock, SOL_SOCKET, SO_LINGER, (const char*)&_linger, sizeof(struct linger)); -*/ - -#ifdef WIN32 /* shutdown(sock,SD_RECEIVE); */ - shutdown(sock.sock, SD_SEND); - while (recv(sock.sock, junk, sizeof(junk), 0) > 0) ; + shutdown(sock->sock, SD_SEND); + while (recv(sock->sock, junk, sizeof(junk), 0) > 0) ; /* nothing */ - closesocket(sock.sock); + closesocket(sock->sock); + return; +} #else - /* XXX m. campbell - It seems like the while loop here needs this */ - fcntl(sock.sock, F_SETFL, O_NONBLOCK); +static inline void +_hsocket_sys_close(hsocket_t *sock) +{ + + shutdown(sock->sock, SHUT_RDWR); + + return; +} +#endif + +/*-------------------------------------------------- +FUNCTION: hsocket_close +----------------------------------------------------*/ +void +hsocket_close(hsocket_t *sock) +{ + log_verbose3("closing socket %p (%d)...", sock, sock->sock); + #ifdef HAVE_SSL - if (sock.ssl) + if (sock->ssl) { log_verbose1("Closing SSL"); - ssl_cleanup(sock.ssl); - sock.ssl = NULL; + ssl_cleanup(sock->ssl); + sock->ssl = NULL; } #endif - shutdown(sock.sock, SHUT_RDWR); - while (recv(sock.sock, junk, sizeof(junk), 0) > 0) ; - /* nothing */ - close(sock.sock); -#endif + _hsocket_sys_close(sock); log_verbose1("socket closed"); @@ -427,11 +424,17 @@ hsocket_nsend(hsocket_t sock, const byte_t * bytes, int n) /* size = _test_send_to_file(filename, bytes, n); */ #ifdef WIN32 if (size == INVALID_SOCKET) + { if (WSAGetLastError() == WSAEWOULDBLOCK) + { continue; + } else + { return herror_new("hsocket_nsend", HSOCKET_ERROR_SEND, "Socket error: %d", errno); + } + } #else if (size == -1) { diff --git a/nanohttp/nanohttp-socket.h b/nanohttp/nanohttp-socket.h index f5f8aa7..63d55dd 100644 --- a/nanohttp/nanohttp-socket.h +++ b/nanohttp/nanohttp-socket.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-socket.h,v 1.23 2006/02/27 00:26:23 snowdrop Exp $ + * $Id: nanohttp-socket.h,v 1.24 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -24,14 +24,10 @@ #ifndef NANO_HTTP_SOCKET_H #define NANO_HTTP_SOCKET_H -#ifdef __cplusplus -extern "C" { -#endif +#include #include -#include - #ifdef HAVE_SSL #include #endif @@ -40,6 +36,7 @@ extern "C" { #include #endif +#define HSOCKET_FREE -1 /* Socket definition @@ -55,7 +52,7 @@ typedef struct hsocket_t #ifdef WIN32 SOCKET sock; #else - int sock; + volatile int sock; #endif int block; @@ -65,7 +62,9 @@ typedef struct hsocket_t typedef int socklen_t; #endif - +#ifdef __cplusplus +extern "C" { +#endif /** @@ -145,7 +144,7 @@ herror_t hsocket_open(hsocket_t * sock, const char *host, int port); @param sock the socket to close */ -void hsocket_close(hsocket_t sock); +void hsocket_close(hsocket_t *sock); /** diff --git a/nanohttp/nanohttp-ssl.h b/nanohttp/nanohttp-ssl.h index 798a1ee..1cdafb2 100644 --- a/nanohttp/nanohttp-ssl.h +++ b/nanohttp/nanohttp-ssl.h @@ -25,10 +25,6 @@ /* Do enter only if --with-ssl was specified by the configure script */ #ifdef HAVE_SSL -#ifdef __cplusplus -extern "C" { -#endif - #ifdef TRU64 #include typedef unsigned int uint32_t; @@ -61,6 +57,10 @@ typedef struct Con * Callback for password checker */ +#ifdef __cplusplus +extern "C" { +#endif + //static int pw_cb(char* buf, int num, int rwflag, void *userdata); /* diff --git a/nanohttp/nanohttp-stream.c b/nanohttp/nanohttp-stream.c index 8908e54..0d8188a 100755 --- a/nanohttp/nanohttp-stream.c +++ b/nanohttp/nanohttp-stream.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-stream.c,v 1.10 2006/02/18 20:14:36 snowdrop Exp $ +* $Id: nanohttp-stream.c,v 1.11 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -25,10 +25,18 @@ #include #endif +#ifdef HAVE_STDIO_H +#include +#endif + #ifdef HAVE_STRING_H #include #endif +#ifdef HAVE_ERRNO_H +#include +#endif + #ifdef MEM_DEBUG #include #endif @@ -88,7 +96,12 @@ http_input_stream_new(hsocket_t sock, hpair_t * header) /* Paranoya check */ /* if (header == NULL) return NULL; */ /* Create object */ - result = (http_input_stream_t *) malloc(sizeof(http_input_stream_t)); + if (!(result = (http_input_stream_t *) malloc(sizeof(http_input_stream_t)))) + { + log_error2("malloc failed (%s)", strerror(errno)); + return NULL; + } + result->sock = sock; result->err = H_OK; @@ -131,17 +144,27 @@ http_input_stream_t * http_input_stream_new_from_file(const char *filename) { http_input_stream_t *result; - FILE *fd = fopen(filename, "rb"); + FILE *fd; + + if (!(fd = fopen(filename, "rb"))) { - if (fd == NULL) + log_error2("fopen failed (%s)", strerror(errno)); return NULL; + } /* Create object */ - result = (http_input_stream_t *) malloc(sizeof(http_input_stream_t)); + if (!(result = (http_input_stream_t *) malloc(sizeof(http_input_stream_t)))) + { + log_error2("malloc failed (%s)", strerror(errno)); + fclose(fd); + return NULL; + } + result->type = HTTP_TRANSFER_FILE; result->fd = fd; result->deleteOnExit = 0; strcpy(result->filename, filename); + return result; } @@ -225,7 +248,7 @@ _http_input_stream_chunked_read_chunk_size(http_input_stream_t * stream) { stream->err = herror_new("_http_input_stream_chunked_read_chunk_size", GENERAL_INVALID_PARAM, - "This should never happens!"); + "This should never happen!"); return -1; } @@ -262,7 +285,7 @@ _http_input_stream_chunked_read_chunk_size(http_input_stream_t * stream) i++; } - /* this should never happens */ + /* this should never happen */ stream->err = herror_new("_http_input_stream_chunked_read_chunk_size", STREAM_ERROR_NO_CHUNK_SIZE, "reached max line == %d", i); @@ -343,7 +366,7 @@ _http_input_stream_chunked_read(http_input_stream_t * stream, byte_t * dest, { stream->err = herror_new("_http_input_stream_chunked_read", GENERAL_INVALID_PARAM, - "This should never happens(remain=%d)(status=%d)!", + "This should never happen (remain=%d)(status=%d)!", remain, status); return -1; } @@ -356,7 +379,7 @@ _http_input_stream_chunked_read(http_input_stream_t * stream, byte_t * dest, { stream->err = herror_new("_http_input_stream_chunked_read", GENERAL_INVALID_PARAM, - "This should never happens(size=%d)(status=%d)!", + "This should never happen (size=%d)(status=%d)!", size, status); return -1; } @@ -403,17 +426,16 @@ static int _http_input_stream_file_read(http_input_stream_t * stream, byte_t * dest, int size) { - int readed; + size_t len; - readed = fread(dest, 1, size, stream->fd); - if (readed == -1) + if ((len = fread(dest, 1, size, stream->fd)) == -1) { stream->err = herror_new("_http_input_stream_file_read", HSOCKET_ERROR_RECEIVE, "fread() returned -1"); return -1; } - return readed; + return len; } /** @@ -452,8 +474,8 @@ http_input_stream_is_ready(http_input_stream_t * stream) int http_input_stream_read(http_input_stream_t * stream, byte_t * dest, int size) { - int readed = 0; - /* paranoya check */ + int len = 0; + /* paranoia check */ if (stream == NULL) { return -1; @@ -465,16 +487,16 @@ http_input_stream_read(http_input_stream_t * stream, byte_t * dest, int size) switch (stream->type) { case HTTP_TRANSFER_CONTENT_LENGTH: - readed = _http_input_stream_content_length_read(stream, dest, size); + len = _http_input_stream_content_length_read(stream, dest, size); break; case HTTP_TRANSFER_CHUNKED: - readed = _http_input_stream_chunked_read(stream, dest, size); + len = _http_input_stream_chunked_read(stream, dest, size); break; case HTTP_TRANSFER_CONNECTION_CLOSE: - readed = _http_input_stream_connection_closed_read(stream, dest, size); + len = _http_input_stream_connection_closed_read(stream, dest, size); break; case HTTP_TRANSFER_FILE: - readed = _http_input_stream_file_read(stream, dest, size); + len = _http_input_stream_file_read(stream, dest, size); break; default: stream->err = herror_new("http_input_stream_read", @@ -483,7 +505,7 @@ http_input_stream_read(http_input_stream_t * stream, byte_t * dest, int size) return -1; } - return readed; + return len; } @@ -511,7 +533,12 @@ http_output_stream_new(hsocket_t sock, hpair_t * header) return NULL; */ /* Create object */ - result = (http_output_stream_t *) malloc(sizeof(http_output_stream_t)); + if (!(result = (http_output_stream_t *) malloc(sizeof(http_output_stream_t)))) + { + log_error2("malloc failed (%s)", strerror(errno)); + return NULL; + } + result->sock = sock; result->sent = 0; @@ -548,6 +575,8 @@ void http_output_stream_free(http_output_stream_t * stream) { free(stream); + + return; } /** @@ -564,23 +593,20 @@ http_output_stream_write(http_output_stream_t * stream, if (stream->type == HTTP_TRANSFER_CHUNKED) { sprintf(chunked, "%x\r\n", size); - status = hsocket_send(stream->sock, chunked); - if (status != H_OK) + if ((status = hsocket_send(stream->sock, chunked)) != H_OK) return status; } if (size > 0) { _log_str("stream.out", (char *) bytes, size); - status = hsocket_nsend(stream->sock, bytes, size); - if (status != H_OK) + if ((status = hsocket_nsend(stream->sock, bytes, size)) != H_OK) return status; } if (stream->type == HTTP_TRANSFER_CHUNKED) { - status = hsocket_send(stream->sock, "\r\n"); - if (status != H_OK) + if ((status = hsocket_send(stream->sock, "\r\n")) != H_OK) return status; } @@ -606,8 +632,7 @@ http_output_stream_flush(http_output_stream_t * stream) if (stream->type == HTTP_TRANSFER_CHUNKED) { - status = hsocket_send(stream->sock, "0\r\n\r\n"); - if (status != H_OK) + if ((status = hsocket_send(stream->sock, "0\r\n\r\n")) != H_OK) return status; } diff --git a/nanohttp/nanohttp-stream.h b/nanohttp/nanohttp-stream.h index 0cc3ab7..ac78603 100755 --- a/nanohttp/nanohttp-stream.h +++ b/nanohttp/nanohttp-stream.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-stream.h,v 1.8 2006/02/27 00:26:23 snowdrop Exp $ + * $Id: nanohttp-stream.h,v 1.9 2006/02/27 22:26:02 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -24,12 +24,15 @@ #ifndef NANO_HTTP_STREAM_H #define NANO_HTTP_STREAM_H +#include + +#include +#include + #ifdef __cplusplus extern "C" { #endif -#include - void _log_str(char *fn, char *str, int size); /* @@ -57,12 +60,6 @@ void _log_str(char *fn, char *str, int size); */ -#include -#include - -#include - - /** Transfer types supported while sending/receiving data. diff --git a/win32/MinGW/Makefile b/win32/MinGW/Makefile index 88f8155..de4787c 100644 --- a/win32/MinGW/Makefile +++ b/win32/MinGW/Makefile @@ -4,10 +4,9 @@ # LIBXML2 #--------------------------------------------------------- # This should be set as -# mingw32-make LIBXML2_DIR= ICONV_DIR= +# mingw32-make LIBXML2_DIR= # #LIBXML2_DIR=../../../libxml2-2.6.23.win32 -#ICONV_DIR=../../../iconv-1.9.1.win32 #--------------------------------------------------------- # LIBSOAP @@ -57,13 +56,13 @@ INCLUDE=-I. -I../include -I../.. -I$(LIBXML2_DIR)/include -I$(ICONV_DIR)/include all: nanohttp libsoap simpleclient simpleserver echo OK - + nanohttp: $(NANOHTTP_OBJECTS) $(AR) cru libnanohttp.a $? libsoap: $(LIBSOAP_OBJECTS) $(AR) cru libsoap.a $? - + simpleclient: ../../examples/csoap/simpleclient.o $(CC) -o simpleclient $? -L$(LIBXML2_DIR)/lib -L. -lsoap -lnanohttp -lxml2 -lws2_32 -- cgit v1.1-32-gdbae