summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config.h.in12
-rw-r--r--libcsoap/soap-client.c36
-rw-r--r--libcsoap/soap-client.h10
-rwxr-xr-xlibcsoap/soap-ctx.h9
-rw-r--r--libcsoap/soap-env.c232
-rw-r--r--libcsoap/soap-env.h25
-rw-r--r--libcsoap/soap-fault.c10
-rw-r--r--libcsoap/soap-fault.h8
-rw-r--r--libcsoap/soap-router.h10
-rw-r--r--libcsoap/soap-server.c80
-rw-r--r--libcsoap/soap-server.h8
-rw-r--r--libcsoap/soap-service.h16
-rw-r--r--libcsoap/soap-xml.h14
-rw-r--r--nanohttp/nanohttp-client.c76
-rw-r--r--nanohttp/nanohttp-client.h5
-rw-r--r--nanohttp/nanohttp-common.c104
-rw-r--r--nanohttp/nanohttp-common.h59
-rwxr-xr-xnanohttp/nanohttp-mime.c14
-rwxr-xr-xnanohttp/nanohttp-request.c25
-rwxr-xr-xnanohttp/nanohttp-request.h4
-rwxr-xr-xnanohttp/nanohttp-response.c9
-rwxr-xr-xnanohttp/nanohttp-response.h4
-rw-r--r--nanohttp/nanohttp-server.c315
-rw-r--r--nanohttp/nanohttp-server.h12
-rw-r--r--nanohttp/nanohttp-socket.c453
-rw-r--r--nanohttp/nanohttp-socket.h72
-rw-r--r--nanohttp/nanohttp-ssl.c521
-rw-r--r--nanohttp/nanohttp-ssl.h99
-rwxr-xr-xnanohttp/nanohttp-stream.c32
-rwxr-xr-xnanohttp/nanohttp-stream.h20
30 files changed, 1078 insertions, 1216 deletions
diff --git a/config.h.in b/config.h.in
index 3117663..c6b7662 100644
--- a/config.h.in
+++ b/config.h.in
@@ -76,6 +76,9 @@
/* Define to 1 if you have the `socket' function. */
#undef HAVE_SOCKET
+/* Define to 1 if you have requested --with-ssl */
+#undef HAVE_SSL
+
/* Define to 1 if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
@@ -115,6 +118,9 @@
/* Define to 1 if you have the `strstr' function. */
#undef HAVE_STRSTR
+/* Define to 1 if you have the `strtok_r' function. */
+#undef HAVE_STRTOK_R
+
/* Define to 1 if you have the `strtol' function. */
#undef HAVE_STRTOL
@@ -139,6 +145,9 @@
/* Define to 1 if you have the `vprintf' function. */
#undef HAVE_VPRINTF
+/* Name of package */
+#undef PACKAGE
+
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
@@ -175,6 +184,9 @@
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
#undef TM_IN_SYS_TIME
+/* Version number of package */
+#undef VERSION
+
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
diff --git a/libcsoap/soap-client.c b/libcsoap/soap-client.c
index 80f8b3a..5d42ec6 100644
--- a/libcsoap/soap-client.c
+++ b/libcsoap/soap-client.c
@@ -1,5 +1,5 @@
/******************************************************************
-* $Id: soap-client.c,v 1.24 2006/02/25 10:09:28 snowdrop Exp $
+* $Id: soap-client.c,v 1.25 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A SOAP client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -37,7 +37,7 @@
#include "soap-client.h"
-static int _block_socket = 0;
+// static int _block_socket = 0;
static herror_t
_soap_client_build_result(hresponse_t * res, SoapEnv ** env)
@@ -55,25 +55,25 @@ _soap_client_build_result(hresponse_t * res, SoapEnv ** env)
if (res->errcode != 200)
return herror_new("_soap_client_build_result",
- GENERAL_INVALID_PARAM, "HTTP code is not 200 OK");
+ GENERAL_INVALID_PARAM, "HTTP code is not OK (%i)", res->errcode);
return soap_env_new_from_stream(res->in, env);
}
-void
-soap_client_block_socket(int block)
-{
- _block_socket = block;
-
- return;
-}
-
-int
-soap_client_get_blockmode(void)
-{
-
- return _block_socket;
-}
+// void
+// soap_client_block_socket(int block)
+// {
+// _block_socket = block;
+//
+// return;
+// }
+//
+// int
+// soap_client_get_blockmode(void)
+// {
+//
+// return _block_socket;
+// }
herror_t
soap_client_init_args(int argc, char *argv[])
@@ -128,7 +128,7 @@ soap_client_invoke(SoapCtx * call, SoapCtx ** response, const char *url,
return herror_new("soap_client_invoke", SOAP_ERROR_CLIENT_INIT,
"Unable to create SOAP client!");
}
- conn->sock.block = soap_client_get_blockmode();
+// conn->sock.block = soap_client_get_blockmode();
/* Set soap action */
if (soap_action != NULL)
diff --git a/libcsoap/soap-client.h b/libcsoap/soap-client.h
index 43d1359..d8bf6ee 100644
--- a/libcsoap/soap-client.h
+++ b/libcsoap/soap-client.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: soap-client.h,v 1.12 2006/01/10 11:29:04 snowdrop Exp $
+ * $Id: soap-client.h,v 1.13 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A SOAP client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -29,6 +29,10 @@
#define SOAP_ERROR_CLIENT_INIT 5001
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
Initializes the client side soap engine
*/
@@ -69,4 +73,8 @@ herror_t soap_client_invoke(SoapCtx * ctx, SoapCtx ** response,
void soap_client_block_socket(int block);
int soap_client_get_blockmode();
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/libcsoap/soap-ctx.h b/libcsoap/soap-ctx.h
index a4784f5..d418037 100755
--- a/libcsoap/soap-ctx.h
+++ b/libcsoap/soap-ctx.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: soap-ctx.h,v 1.8 2006/02/18 20:14:36 snowdrop Exp $
+ * $Id: soap-ctx.h,v 1.9 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A SOAP client/server library in C
* Copyright (C) 2003-2004 Ferhat Ayaz
@@ -42,6 +42,9 @@ typedef struct _SoapCtx
attachments_t *attachments;
} SoapCtx;
+#ifdef __cplusplus
+extern "C" {
+#endif
SoapCtx *soap_ctx_new(SoapEnv * env); /* should only be used internally */
@@ -71,4 +74,8 @@ given one to the added part.
void soap_ctx_add_files(SoapCtx * ctx, attachments_t * attachments);
void soap_ctx_free(SoapCtx * ctx);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/libcsoap/soap-env.c b/libcsoap/soap-env.c
index 8f4df35..590e5f1 100644
--- a/libcsoap/soap-env.c
+++ b/libcsoap/soap-env.c
@@ -1,5 +1,5 @@
/******************************************************************
-* $Id: soap-env.c,v 1.17 2006/02/27 22:26:02 snowdrop Exp $
+* $Id: soap-env.c,v 1.18 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A SOAP client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -41,6 +41,7 @@
#include <errno.h>
#endif
+#include "soap-xml.h"
#include "soap-env.h"
#ifdef WIN32
@@ -51,11 +52,6 @@
#include <libxml/xmlstring.h>
#endif
-static char *soap_env_ns = "http://schemas.xmlsoap.org/soap/envelope/";
-static char *soap_env_enc = "http://schemas.xmlsoap.org/soap/encoding/";
-static char *soap_xsi_ns = "http://www.w3.org/1999/XMLSchema-instance";
-static char *soap_xsd_ns = "http://www.w3.org/1999/XMLSchema";
-
/*
Parameters:
1- soap_env_ns
@@ -70,6 +66,7 @@ Parameters:
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"%s\" SOAP-ENV:encodingStyle=\"%s\"" \
" xmlns:xsi=\"%s\"" \
" xmlns:xsd=\"%s\">" \
+ " <SOAP-ENV:Header />" \
" <SOAP-ENV:Body>"\
" <m:%s xmlns:m=\"%s\">"\
" </m:%s>" \
@@ -91,6 +88,7 @@ Parameters:
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"%s\" SOAP-ENV:encodingStyle=\"%s\"" \
" xmlns:xsi=\"%s\"" \
" xmlns:xsd=\"%s\">" \
+ " <SOAP-ENV:Header />" \
" <SOAP-ENV:Body>"\
" <%s xmlns=\"%s\">"\
" </%s>" \
@@ -106,21 +104,57 @@ struct XmlNodeHolder
xmlNodePtr node;
};
-static
- void xmlbuilder_start_element(const xmlChar * element_name, int attr_count,
- xmlChar ** keys, xmlChar ** values,
- void *userData);
+static void
+xmlbuilder_start_element(const xmlChar * element_name, int attr_count, xmlChar ** keys, xmlChar ** values, void *userData)
+{
+ struct XmlNodeHolder *holder = (struct XmlNodeHolder *) userData;
+ xmlNodePtr parent = NULL;
-static
- void xmlbuilder_characters(const xmlChar * element_name,
- const xmlChar * chars, void *userData);
+ if (holder == NULL)
+ return;
+ parent = holder->node;
+ if (parent == NULL)
+ return;
-static
- void xmlbuilder_end_element(const xmlChar * element_name, void *userData);
+ holder->node = xmlNewChild(parent, NULL, element_name, NULL);
-/* ---------------------------------------------------------------------------- */
+ return;
+}
+static void
+xmlbuilder_characters(const xmlChar * element_name, const xmlChar * chars, void *userData)
+{
+ struct XmlNodeHolder *holder = (struct XmlNodeHolder *) userData;
+ xmlNodePtr parent = NULL;
+ if (holder == NULL)
+ return;
+ parent = holder->node;
+ if (parent == NULL)
+ return;
+
+ xmlNewTextChild(parent, NULL, element_name, chars);
+
+ return;
+}
+
+static void
+xmlbuilder_end_element(const xmlChar * element_name, void *userData)
+{
+
+ struct XmlNodeHolder *holder = (struct XmlNodeHolder *) userData;
+ xmlNodePtr parent = NULL;
+
+ if (holder == NULL)
+ return;
+ parent = holder->node;
+ if (parent == NULL)
+ return;
+
+ holder->node = parent->parent;
+
+ return;
+}
herror_t
soap_env_new_from_doc(xmlDocPtr doc, SoapEnv ** out)
@@ -136,10 +170,9 @@ soap_env_new_from_doc(xmlDocPtr doc, SoapEnv ** out)
"XML Document (xmlDocPtr) is NULL");
}
- node = xmlDocGetRootElement(doc);
- if (node == NULL)
+ if (!(node = xmlDocGetRootElement(doc)))
{
- log_error1("xml document is empty!");
+ log_error1("XML document is empty!");
return herror_new("soap_env_new_from_doc",
XML_ERROR_EMPTY_DOCUMENT, "XML Document is empty!");
}
@@ -150,21 +183,16 @@ soap_env_new_from_doc(xmlDocPtr doc, SoapEnv ** out)
return herror_new("soap_env_from_doc", GENERAL_INVALID_PARAM, "malloc failed");
}
- /* set root */
env->root = node;
-
- /* set method root set call->cur (current node) to <method>. xpath:
- //Envelope/Body/ */
- node = soap_xml_get_children(env->root); /* Check for NULL ! */
- env->cur = soap_xml_get_children(node); /* Check for NULL ! */
+ env->header = soap_env_get_header(env);
+ env->cur = env->body = soap_env_get_body(env);
*out = env;
+
return H_OK;
}
-
-
herror_t
soap_env_new_from_buffer(const char *buffer, SoapEnv ** out)
{
@@ -175,17 +203,14 @@ soap_env_new_from_buffer(const char *buffer, SoapEnv ** out)
return herror_new("soap_env_new_from_buffer",
GENERAL_INVALID_PARAM, "buffer (first param) is NULL");
- doc = xmlParseDoc(BAD_CAST buffer);
- if (doc == NULL)
+ if (!(doc = xmlParseDoc(BAD_CAST buffer)))
return herror_new("soap_env_new_from_buffer",
XML_ERROR_PARSE, "Can not parse xml");
- err = soap_env_new_from_doc(doc, out);
- if (err != H_OK)
+ if ((err = soap_env_new_from_doc(doc, out)) != H_OK)
{
xmlFreeDoc(doc);
}
-
return err;
}
@@ -204,8 +229,7 @@ soap_env_new_with_fault(fault_code_t faultcode,
return herror_new("soap_env_new_with_fault",
XML_ERROR_PARSE, "Can not parse fault xml");
- err = soap_env_new_from_doc(doc, out);
- if (err != H_OK)
+ if ((err = soap_env_new_from_doc(doc, out)) != H_OK)
{
xmlFreeDoc(doc);
}
@@ -250,7 +274,9 @@ soap_env_new_with_response(SoapEnv * request, SoapEnv ** out)
urn = "";
}
- res_method = malloc(strlen(method)+9);
+ if (!(res_method = (char *)malloc(strlen(method)+9)))
+ return herror_new("soap_env_new_with_response", GENERAL_INVALID_PARAM, "malloc failed");
+
sprintf(res_method, "%sResponse", method);
ret = soap_env_new_with_method(urn, res_method, out);
@@ -267,7 +293,6 @@ soap_env_new_with_method(const char *urn, const char *method, SoapEnv ** out)
xmlDocPtr env;
xmlChar buffer[1054];
-
log_verbose2("URN = '%s'", urn);
log_verbose2("Method = '%s'", method);
@@ -297,21 +322,19 @@ soap_env_new_with_method(const char *urn, const char *method, SoapEnv ** out)
}
- env = xmlParseDoc(buffer);
- if (!env)
+ if (!(env = xmlParseDoc(buffer)))
return herror_new("soap_env_new_with_method",
XML_ERROR_PARSE, "Can not parse xml");
return soap_env_new_from_doc(env, out);
-
}
-
static int
_soap_env_xml_io_read(void *ctx, char *buffer, int len)
{
int readed;
+
http_input_stream_t *in = (http_input_stream_t *) ctx;
if (!http_input_stream_is_ready(in))
return 0;
@@ -334,26 +357,24 @@ herror_t
soap_env_new_from_stream(http_input_stream_t * in, SoapEnv ** out)
{
xmlDocPtr doc;
- herror_t err;
doc = xmlReadIO(_soap_env_xml_io_read,
_soap_env_xml_io_close, in, "", NULL, 0);
if (in->err != H_OK)
return in->err;
+
if (doc == NULL)
return herror_new("soap_env_new_from_stream",
XML_ERROR_PARSE, "Trying to parse not valid xml");
- err = soap_env_new_from_doc(doc, out);
- return err;
+
+ return soap_env_new_from_doc(doc, out);
}
xmlNodePtr
-soap_env_add_item(SoapEnv * call, const char *type,
- const char *name, const char *value)
+soap_env_add_item(SoapEnv * call, const char *type, const char *name, const char *value)
{
-
xmlNodePtr newnode;
newnode = xmlNewTextChild(call->cur, NULL, BAD_CAST name, BAD_CAST value);
@@ -377,7 +398,6 @@ soap_env_add_item(SoapEnv * call, const char *type,
}
-
xmlNodePtr
soap_env_add_itemf(SoapEnv * call, const char *type,
const char *name, const char *format, ...)
@@ -395,7 +415,6 @@ soap_env_add_itemf(SoapEnv * call, const char *type,
}
-
xmlNodePtr
soap_env_add_attachment(SoapEnv * call, const char *name, const char *href)
{
@@ -421,9 +440,9 @@ soap_env_add_attachment(SoapEnv * call, const char *name, const char *href)
return newnode;
}
+
void
-soap_env_add_custom(SoapEnv * call, void *obj, XmlSerializerCallback cb,
- const char *type, const char *name)
+soap_env_add_custom(SoapEnv * call, void *obj, XmlSerializerCallback cb, const char *type, const char *name)
{
struct XmlNodeHolder holder;
@@ -433,6 +452,7 @@ soap_env_add_custom(SoapEnv * call, void *obj, XmlSerializerCallback cb,
xmlbuilder_start_element,
xmlbuilder_characters, xmlbuilder_end_element, &holder);
+ return;
}
@@ -442,12 +462,8 @@ soap_env_push_item(SoapEnv * call, const char *type, const char *name)
xmlNodePtr node;
- node = soap_env_add_item(call, type, name, "");
-
- if (node)
- {
+ if ((node = soap_env_add_item(call, type, name, "")))
call->cur = node;
- }
return node;
}
@@ -457,8 +473,11 @@ void
soap_env_pop_item(SoapEnv * call)
{
call->cur = call->cur->parent;
+
+ return;
}
+
void
soap_env_free(SoapEnv * env)
{
@@ -470,6 +489,8 @@ soap_env_free(SoapEnv * env)
}
free(env);
}
+
+ return;
}
@@ -490,16 +511,42 @@ soap_env_get_body(SoapEnv * env)
return NULL;
}
- node = soap_xml_get_children(env->root);
+ for (node = soap_xml_get_children(env->root); node; node = soap_xml_get_next(node))
+ {
+ if (!xmlStrcmp(node->name, BAD_CAST "Body")
+ && !xmlStrcmp(node->ns->href, BAD_CAST soap_env_ns))
+ return node;
+ }
- while (node != NULL)
+ log_error1("Body tag not found!");
+ return NULL;
+}
+
+
+xmlNodePtr
+soap_env_get_header(SoapEnv *env)
+{
+ xmlNodePtr node;
+
+ if (!env)
+ {
+ log_error1("SoapEnv is NULL");
+ return NULL;
+ }
+
+ if (!env->root)
+ {
+ log_error1("SoapEnv contains no document");
+ return NULL;
+ }
+
+ for (node = soap_xml_get_children(env->root); node; node = soap_xml_get_next(node))
{
- if (!xmlStrcmp(node->name, BAD_CAST "Body"))
+ if (!xmlStrcmp(node->name, BAD_CAST "Header")
+ && !xmlStrcmp(node->ns->href, BAD_CAST soap_env_ns))
return node;
- node = soap_xml_get_next(node);
}
- log_error1("Node Body tag found!");
return NULL;
}
@@ -509,7 +556,6 @@ soap_env_get_fault(SoapEnv * env)
{
xmlNodePtr node;
-
node = soap_env_get_body(env);
if (!node)
@@ -530,12 +576,11 @@ soap_env_get_fault(SoapEnv * env)
xmlNodePtr
soap_env_get_method(SoapEnv * env)
{
-
xmlNodePtr body;
- if ((body = soap_env_get_body(env)) == NULL)
+ if (!(body = soap_env_get_body(env)))
{
- log_verbose1("body is NULL");
+ log_verbose1("SoapEnv contains no Body");
return NULL;
}
@@ -544,6 +589,7 @@ soap_env_get_method(SoapEnv * env)
}
+/* XXX: unused function? */
xmlNodePtr
_soap_env_get_body(SoapEnv * env)
{
@@ -553,13 +599,13 @@ _soap_env_get_body(SoapEnv * env)
if (env == NULL)
{
- log_error1("env object is NULL");
+ log_error1("SoapEnv is NULL");
return NULL;
}
if (env->root == NULL)
{
- log_error1("env has no xml");
+ log_error1("SoapEnv contains no XML document");
return NULL;
}
@@ -661,57 +707,3 @@ soap_env_find_methodname(SoapEnv * env)
}
-
-/* ------------------------------------------------------------------ */
-/* XML serializers */
-/* ------------------------------------------------------------------ */
-
-
-static void
-xmlbuilder_start_element(const xmlChar * element_name, int attr_count,
- xmlChar ** keys, xmlChar ** values, void *userData)
-{
- struct XmlNodeHolder *holder = (struct XmlNodeHolder *) userData;
- xmlNodePtr parent = NULL;
-
- if (holder == NULL)
- return;
- parent = holder->node;
- if (parent == NULL)
- return;
-
- holder->node = xmlNewChild(parent, NULL, element_name, NULL);
-
-}
-
-static void
-xmlbuilder_characters(const xmlChar * element_name, const xmlChar * chars,
- void *userData)
-{
- struct XmlNodeHolder *holder = (struct XmlNodeHolder *) userData;
- xmlNodePtr parent = NULL;
-
- if (holder == NULL)
- return;
- parent = holder->node;
- if (parent == NULL)
- return;
-
- xmlNewTextChild(parent, NULL, element_name, chars);
-}
-
-static void
-xmlbuilder_end_element(const xmlChar * element_name, void *userData)
-{
-
- struct XmlNodeHolder *holder = (struct XmlNodeHolder *) userData;
- xmlNodePtr parent = NULL;
-
- if (holder == NULL)
- return;
- parent = holder->node;
- if (parent == NULL)
- return;
-
- holder->node = parent->parent;
-}
diff --git a/libcsoap/soap-env.h b/libcsoap/soap-env.h
index ee53f3a..5440e78 100644
--- a/libcsoap/soap-env.h
+++ b/libcsoap/soap-env.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: soap-env.h,v 1.13 2006/02/18 20:14:36 snowdrop Exp $
+ * $Id: soap-env.h,v 1.14 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A SOAP client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -29,16 +29,21 @@
#include <libcsoap/soap-xml.h>
#include <libcsoap/soap-fault.h>
-
/**
The SOAP envelope object.
*/
typedef struct _SoapEnv
{
xmlNodePtr root; /** Pointer to the firts xml element (envelope) */
+ xmlNodePtr header;
+ xmlNodePtr body;
xmlNodePtr cur; /** Pointer to the current xml element. (stack) */
} SoapEnv;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* -------------------------------------------------------------- */
/* Envelope creation methods */
@@ -177,11 +182,7 @@ herror_t soap_env_new_from_stream(http_input_stream_t * in, SoapEnv ** out);
/* XML Serializer functions and typedefs */
/* --------------------------------------------------- */
-typedef void (*XmlSerializerCallback) (void * /* obj */ , const xmlChar * /* root_element_name
- */ ,
- void (*OnStartElement) (const xmlChar * element_name, int attr_count, xmlChar ** keys, xmlChar ** values, void *userData), void (*OnCharacters) (const xmlChar * element_name, const xmlChar * chars, void *userData), void (*OnEndElement) (const xmlChar * element_name, void *userData), void * /* userdata
- */ );
-
+typedef void (*XmlSerializerCallback) (void * obj, const xmlChar *root_element_name, void (*OnStartElement) (const xmlChar * element_name, int attr_count, xmlChar ** keys, xmlChar ** values, void *userData), void (*OnCharacters) (const xmlChar * element_name, const xmlChar * chars, void *userData), void (*OnEndElement) (const xmlChar * element_name, void *userData), void *userdata);
/* ------------------------------------------------------ */
/* XML build and stack function */
@@ -279,8 +280,7 @@ soap_env_add_itemf(SoapEnv * env, const char *type,
@see tutorial
*/
-xmlNodePtr
-soap_env_push_item(SoapEnv * env, const char *type, const char *name);
+xmlNodePtr soap_env_push_item(SoapEnv * env, const char *type, const char *name);
/**
Sets the xml pointer 1 level higher.
@@ -330,9 +330,8 @@ xmlNodePtr soap_env_get_header(SoapEnv * env);
char * soap_env_find_urn(SoapEnv * env);
char * soap_env_find_methodname(SoapEnv * env);
-
-
-
-
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/libcsoap/soap-fault.c b/libcsoap/soap-fault.c
index edeb688..9de1e2b 100644
--- a/libcsoap/soap-fault.c
+++ b/libcsoap/soap-fault.c
@@ -1,5 +1,5 @@
/******************************************************************
-* $Id: soap-fault.c,v 1.9 2006/02/27 22:26:02 snowdrop Exp $
+* $Id: soap-fault.c,v 1.10 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A SOAP client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -32,11 +32,6 @@
#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/";
-static char *soap_xsi_ns = "http://www.w3.org/1999/XMLSchema-instance";
-static char *soap_xsd_ns = "http://www.w3.org/1999/XMLSchema";
-
/*
Parameters:
1- soap_env_ns
@@ -52,7 +47,8 @@ Parameters:
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"%s\" SOAP-ENV:encoding=\"%s\"" \
" xmlns:xsi=\"%s\"" \
" xmlns:xsd=\"%s\">" \
- " <SOAP-ENV:Body>"\
+ " <SOAP-ENV:Header />" \
+ " <SOAP-ENV:Body>" \
" <SOAP-ENV:Fault>"\
" <faultcode>%s</faultcode>"\
" <faultstring>%s</faultstring>"\
diff --git a/libcsoap/soap-fault.h b/libcsoap/soap-fault.h
index 7f01e9f..5aad5ed 100644
--- a/libcsoap/soap-fault.h
+++ b/libcsoap/soap-fault.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: soap-fault.h,v 1.4 2006/01/10 11:29:04 snowdrop Exp $
+ * $Id: soap-fault.h,v 1.5 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A SOAP client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -36,10 +36,16 @@ typedef enum _fault_code
Fault_Server
} fault_code_t;
+#ifdef __cplusplus
+extern "C" {
+#endif
xmlDocPtr soap_fault_build(fault_code_t faultcode,
const char *faultstring,
const char *faultactor, const char *detail);
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/libcsoap/soap-router.h b/libcsoap/soap-router.h
index 2a37117..41ea95f 100644
--- a/libcsoap/soap-router.h
+++ b/libcsoap/soap-router.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: soap-router.h,v 1.5 2006/02/18 20:14:36 snowdrop Exp $
+ * $Id: soap-router.h,v 1.6 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A SOAP client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -38,6 +38,10 @@ typedef struct _SoapRouter
} SoapRouter;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
Creates a new router object. Create a router if
you are implementing a soap server. Then register
@@ -87,4 +91,8 @@ SoapService *soap_router_find_service(SoapRouter * router,
*/
void soap_router_free(SoapRouter * router);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/libcsoap/soap-server.c b/libcsoap/soap-server.c
index eade02a..33e1736 100644
--- a/libcsoap/soap-server.c
+++ b/libcsoap/soap-server.c
@@ -1,5 +1,5 @@
/******************************************************************
-* $Id: soap-server.c,v 1.18 2006/02/27 22:26:02 snowdrop Exp $
+* $Id: soap-server.c,v 1.19 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A SOAP client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -29,6 +29,14 @@
#include <string.h>
#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef WIN32
+#define snprintf(buffer, num, s1, s2) sprintf(buffer, s1,s2)
+#endif
+
#include <nanohttp/nanohttp-server.h>
#include "soap-server.h"
@@ -57,6 +65,7 @@ _soap_server_send_env(http_output_stream_t * out, SoapEnv * env)
(const char *) xmlBufferContent(buffer));
xmlBufferFree(buffer);
+ return;
}
static void
@@ -114,18 +123,18 @@ _soap_server_send_fault(httpd_conn_t * conn, const char *errmsg)
static void
_soap_server_send_ctx(httpd_conn_t * conn, SoapCtx * ctx)
{
- xmlBufferPtr buffer;
static int counter = 1;
- char strbuffer[150];
+ xmlBufferPtr buffer;
+ char strbuffer[32];
part_t *part;
if (ctx->env == NULL || ctx->env->root == NULL)
return;
- buffer = xmlBufferCreate();
-/* xmlIndentTreeOutput = 1;*/
xmlThrDefIndentTreeOutput(1);
/* xmlKeepBlanksDefault(0);*/
+
+ buffer = xmlBufferCreate();
xmlNodeDump(buffer, ctx->env->root->doc, ctx->env->root, 1, 1);
if (ctx->attachments)
@@ -149,13 +158,11 @@ _soap_server_send_ctx(httpd_conn_t * conn, SoapCtx * ctx)
char buflen[100];
xmlXPathContextPtr xpathCtx;
xmlXPathObjectPtr xpathObj;
+
xpathCtx = xmlXPathNewContext(ctx->env->root->doc);
xpathObj = xmlXPathEvalExpression("//Fault", xpathCtx);
-#ifdef WIN32
-#define snprintf(buffer, num, s1, s2) sprintf(buffer, s1,s2)
-#endif
- snprintf(buflen, 100, "%d",
- strlen((const char *) xmlBufferContent(buffer)));
+
+ snprintf(buflen, 100, "%d", strlen((const char *) xmlBufferContent(buffer)));
httpd_set_header(conn, HEADER_CONTENT_LENGTH, buflen);
if ((xpathObj->nodesetval) ? xpathObj->nodesetval->nodeNr : 0)
{
@@ -174,25 +181,29 @@ _soap_server_send_ctx(httpd_conn_t * conn, SoapCtx * ctx)
}
xmlBufferFree(buffer);
+ return;
}
static SoapRouterNode *
router_node_new(SoapRouter * router, const char *context, SoapRouterNode * next)
{
- SoapRouterNode *node;
const char *noname = "/lost_found";
+ SoapRouterNode *node;
+
+ if (!(node = (SoapRouterNode *) malloc(sizeof(SoapRouterNode)))) {
+
+ log_error2("malloc failed (%s)", strerror(errno));
+ return NULL;
+ }
- node = (SoapRouterNode *) malloc(sizeof(SoapRouterNode));
if (context)
{
- node->context = (char *) malloc(strlen(context) + 1);
- strcpy(node->context, context);
+ node->context = strdup(context);
}
else
{
log_warn2("context is null. Using '%s'", noname);
- node->context = (char *) malloc(strlen(noname) + 1);
- strcpy(node->context, noname);
+ node->context = strdup(noname);
}
node->router = router;
@@ -204,13 +215,12 @@ router_node_new(SoapRouter * router, const char *context, SoapRouterNode * next)
static SoapRouter *
router_find(const char *context)
{
- SoapRouterNode *node = head;
+ SoapRouterNode *node;
- while (node != NULL)
+ for (node = head; node; node = node->next)
{
if (!strcmp(node->context, context))
return node->router;
- node = node->next;
}
return NULL;
@@ -232,29 +242,29 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req)
{
httpd_send_header(conn, 200, "OK");
- http_output_stream_write_string(conn->out, "<html><head></head><body>");
- http_output_stream_write_string(conn->out, "<h1>Sorry!</h1><hr />");
http_output_stream_write_string(conn->out,
- "I only speak with 'POST' method");
- http_output_stream_write_string(conn->out, "</body></html>");
+ "<html>"
+ "<head>"
+ "</head>"
+ "<body>"
+ "<h1>Sorry!</h1>"
+ "<hr />"
+ "<div>I only speak with 'POST' method </div>"
+ "</body>"
+ "</html>");
return;
}
-
- err = soap_env_new_from_stream(req->in, &env);
- if (err != H_OK)
+ if ((err = soap_env_new_from_stream(req->in, &env)) != H_OK)
{
_soap_server_send_fault(conn, herror_message(err));
herror_release(err);
return;
}
-
if (env == NULL)
{
-
_soap_server_send_fault(conn, "Can not receive POST data!");
-
}
else
{
@@ -269,9 +279,7 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req)
if (ctx->env == NULL)
{
-
_soap_server_send_fault(conn, "Can not parse POST data!");
-
}
else
{
@@ -282,9 +290,7 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req)
if (router == NULL)
{
-
_soap_server_send_fault(conn, "Can not find router!");
-
}
else
{
@@ -303,7 +309,6 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req)
if (!(method=soap_env_find_methodname(ctx->env)))
{
-
_soap_server_send_fault(conn, "No method found!");
soap_ctx_free(ctx);
return;
@@ -398,9 +403,8 @@ soap_server_register_router(SoapRouter * router, const char *context)
return 1;
}
-
herror_t
-soap_server_run()
+soap_server_run(void)
{
return httpd_run();
}
@@ -427,6 +431,6 @@ soap_server_destroy()
node = tmp;
}
httpd_destroy();
-}
-
+ return;
+}
diff --git a/libcsoap/soap-server.h b/libcsoap/soap-server.h
index 4e2db62..89c5dbd 100644
--- a/libcsoap/soap-server.h
+++ b/libcsoap/soap-server.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: soap-server.h,v 1.8 2006/02/08 11:13:14 snowdrop Exp $
+ * $Id: soap-server.h,v 1.9 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A SOAP client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -28,6 +28,9 @@
#include <libcsoap/soap-router.h>
#include <libcsoap/soap-ctx.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
/**
Initializes the soap server with commandline arguments.
@@ -77,5 +80,8 @@ int soap_server_get_port(void);
*/
void soap_server_destroy();
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/libcsoap/soap-service.h b/libcsoap/soap-service.h
index 798f842..594b994 100644
--- a/libcsoap/soap-service.h
+++ b/libcsoap/soap-service.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: soap-service.h,v 1.5 2006/01/10 11:29:04 snowdrop Exp $
+ * $Id: soap-service.h,v 1.6 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A SOAP client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -24,7 +24,6 @@
#ifndef cSOAP_SERVICE_H
#define cSOAP_SERVICE_H
-
#include <libcsoap/soap-env.h>
#include <libcsoap/soap-ctx.h>
@@ -45,13 +44,20 @@ typedef struct _SoapServiceNode
struct _SoapServiceNode *next;
} SoapServiceNode;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
SoapServiceNode *soap_service_node_new(SoapService * service,
SoapServiceNode * next);
-SoapService *soap_service_new(const char *urn, const char *method,
- SoapServiceFunc f);
-void soap_service_free(SoapService * service);
+SoapService *soap_service_new(const char *urn, const char *method, SoapServiceFunc f);
+void soap_service_free(SoapService * service);
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/libcsoap/soap-xml.h b/libcsoap/soap-xml.h
index 9ab07ea..ad578b1 100644
--- a/libcsoap/soap-xml.h
+++ b/libcsoap/soap-xml.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: soap-xml.h,v 1.7 2006/01/10 11:29:04 snowdrop Exp $
+ * $Id: soap-xml.h,v 1.8 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A SOAP client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -29,8 +29,16 @@
#include <nanohttp/nanohttp-common.h>
+static const char * const soap_env_ns = "http://schemas.xmlsoap.org/soap/envelope/";
+static const char * const soap_env_enc = "http://schemas.xmlsoap.org/soap/encoding/";
+static const char * const soap_xsi_ns = "http://www.w3.org/1999/XMLSchema-instance";
+static const char * const soap_xsd_ns = "http://www.w3.org/1999/XMLSchema";
+
typedef int (*soap_xmlnode_callback) (xmlNodePtr, void *);
+#ifdef __cplusplus
+extern "C" {
+#endif
xmlNodePtr soap_xml_get_children(xmlNodePtr param);
xmlNodePtr soap_xml_get_next(xmlNodePtr param);
@@ -45,4 +53,8 @@ soap_xpath_foreach(xmlDocPtr doc, const char *xpath,
void soap_xml_doc_print(xmlDocPtr doc);
char *soap_xml_get_text(xmlNodePtr node);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/nanohttp/nanohttp-client.c b/nanohttp/nanohttp-client.c
index 09605b9..32df75f 100644
--- a/nanohttp/nanohttp-client.c
+++ b/nanohttp/nanohttp-client.c
@@ -1,5 +1,5 @@
/******************************************************************
-* $Id: nanohttp-client.c,v 1.39 2006/02/27 22:26:02 snowdrop Exp $
+* $Id: nanohttp-client.c,v 1.40 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -51,6 +51,7 @@
#include "nanohttp-client.h"
#include "nanohttp-socket.h"
+#include "nanohttp-base64.h"
/*--------------------------------------------------
FUNCTION: httpc_init
@@ -58,11 +59,9 @@ DESC: Initialize http client connection
NOTE: This will be called from soap_client_init_args()
----------------------------------------------------*/
herror_t
-httpc_init(int argc, char *argv[])
+httpc_init(int argc, char **argv)
{
- hoption_init_args(argc, argv);
-
- return hsocket_module_init();
+ return hsocket_module_init(argc, argv);
}
/*--------------------------------------------------
@@ -87,13 +86,17 @@ httpc_conn_t *
httpc_new(void)
{
static int counter = 10000;
+ herror_t status;
httpc_conn_t *res;
if (!(res = (httpc_conn_t *) malloc(sizeof(httpc_conn_t))))
return NULL;
- if (hsocket_init(&res->sock) != H_OK)
+ if ((status = hsocket_init(&res->sock)) != H_OK)
+ {
+ log_warn("hsocket_init failed (%s)", herror_message(status));
return NULL;
+ }
res->header = NULL;
res->version = HTTP_1_1;
@@ -131,7 +134,7 @@ httpc_free(httpc_conn_t * conn)
conn->out = NULL;
}
- hsocket_free(conn->sock);
+ hsocket_free(&(conn->sock));
free(conn);
return;
@@ -214,6 +217,42 @@ httpc_set_header(httpc_conn_t *conn, const char *key, const char *value)
return 0;
}
+static int
+_httpc_set_basic_authorization_header(httpc_conn_t *conn, const char *key, const char *user, const char *password)
+{
+ /* XXX: use malloc/free */
+ char in[64], out[64];
+
+ if (!user)
+ user = "";
+
+ if (!password)
+ password = "";
+
+ memset(in, 0, 64);
+ memset(out, 0, 64);
+
+ sprintf(in, "%s:%s", user, password);
+
+ base64_encode(in, out);
+
+ sprintf(in, "Basic %s", out);
+
+ return httpc_set_header(conn, key, in);
+}
+
+int
+httpc_set_basic_authorization(httpc_conn_t *conn, const char *user, const char *password)
+{
+ return _httpc_set_basic_authorization_header(conn, HEADER_AUTHORIZATION, user, password);
+}
+
+int
+httpc_set_basic_proxy_authorization(httpc_conn_t *conn, const char *user, const char *password)
+{
+ 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.
@@ -252,12 +291,12 @@ httpc_send_header(httpc_conn_t * conn)
if (walker->key && walker->value)
{
sprintf(buffer, "%s: %s\r\n", walker->key, walker->value);
- if ((status = hsocket_send(conn->sock, buffer)) != H_OK)
+ if ((status = hsocket_send(&(conn->sock), buffer)) != H_OK)
return status;
}
}
- return hsocket_send(conn->sock, "\r\n");
+ return hsocket_send(&(conn->sock), "\r\n");
}
/*--------------------------------------------------
@@ -313,6 +352,7 @@ httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn,
hurl_t url;
char buffer[4096];
herror_t status;
+ int ssl;
if (conn == NULL)
{
@@ -332,8 +372,10 @@ httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn,
/* Set hostname */
httpc_set_header(conn, HEADER_HOST, url.host);
+ ssl = url.protocol == PROTOCOL_HTTPS ? 1 : 0;
+
/* Open connection */
- if ((status = hsocket_open(&conn->sock, url.host, url.port)) != H_OK)
+ if ((status = hsocket_open(&conn->sock, url.host, url.port, ssl)) != H_OK)
return status;
switch(method)
@@ -360,9 +402,9 @@ httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn,
}
log_verbose1("Sending request...");
- if ((status = hsocket_send(conn->sock, buffer)) != H_OK)
+ if ((status = hsocket_send(&(conn->sock), buffer)) != H_OK)
{
- log_error2("Can not send request (status:%d)", status);
+ log_error2("Cannot send request (%s)", herror_message(status));
hsocket_close(&(conn->sock));
return status;
}
@@ -370,7 +412,7 @@ httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn,
log_verbose1("Sending header...");
if ((status = httpc_send_header(conn)) != H_OK)
{
- log_error2("Can not send header (status:%d)", status);
+ log_error2("Cannot send header (%s)", herror_message(status));
hsocket_close(&(conn->sock));
return status;
}
@@ -390,7 +432,7 @@ httpc_get(httpc_conn_t * conn, hresponse_t ** out, const char *urlstr)
if ((status = httpc_talk_to_server(HTTP_REQUEST_GET, conn, urlstr)) != H_OK)
return status;
- if ((status = hresponse_new_from_socket(conn->sock, out)) != H_OK)
+ if ((status = hresponse_new_from_socket(&(conn->sock), out)) != H_OK)
return status;
return H_OK;
@@ -409,7 +451,7 @@ httpc_post_begin(httpc_conn_t * conn, const char *url)
if ((status = httpc_talk_to_server(HTTP_REQUEST_POST, conn, url)) != H_OK)
return status;
- conn->out = http_output_stream_new(conn->sock, conn->header);
+ conn->out = http_output_stream_new(&(conn->sock), conn->header);
return H_OK;
}
@@ -428,7 +470,7 @@ httpc_post_end(httpc_conn_t * conn, hresponse_t ** out)
if ((status = http_output_stream_flush(conn->out)) != H_OK)
return status;
- if ((status = hresponse_new_from_socket(conn->sock, out)) != H_OK)
+ if ((status = hresponse_new_from_socket(&(conn->sock), out)) != H_OK)
return status;
return H_OK;
@@ -548,7 +590,7 @@ httpc_mime_end(httpc_conn_t * conn, hresponse_t ** out)
if ((status = http_output_stream_flush(conn->out)) != H_OK)
return status;
- if ((status = hresponse_new_from_socket(conn->sock, out)) != H_OK)
+ if ((status = hresponse_new_from_socket(&(conn->sock), out)) != H_OK)
return status;
return H_OK;
diff --git a/nanohttp/nanohttp-client.h b/nanohttp/nanohttp-client.h
index 5562ea6..b37001a 100644
--- a/nanohttp/nanohttp-client.h
+++ b/nanohttp/nanohttp-client.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: nanohttp-client.h,v 1.22 2006/02/27 22:26:02 snowdrop Exp $
+ * $Id: nanohttp-client.h,v 1.23 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -93,6 +93,9 @@ int httpc_set_header(httpc_conn_t * conn, const char *key, const char *value);
int httpc_add_header(httpc_conn_t *conn, const char *key, const char *value);
void httpc_add_headers(httpc_conn_t *conn, const hpair_t *values);
+int httpc_set_basic_authorization(httpc_conn_t *conn, const char *user, const char *password);
+int httpc_set_basic_proxy_authorization(httpc_conn_t *conn, const char *user, const char *password);
+
/**
Invoke a "GET" method request and receive the response
*/
diff --git a/nanohttp/nanohttp-common.c b/nanohttp/nanohttp-common.c
index f49cc85..b6f0e40 100644
--- a/nanohttp/nanohttp-common.c
+++ b/nanohttp/nanohttp-common.c
@@ -1,5 +1,5 @@
/******************************************************************
-* $Id: nanohttp-common.c,v 1.28 2006/02/27 22:26:02 snowdrop Exp $
+* $Id: nanohttp-common.c,v 1.29 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -55,11 +55,6 @@
#include "nanohttp-common.h"
-#define MAX_OPTION_SIZE 50
-#define MAX_OPTION_VALUE_SIZE 150
-
-static char _hoption_table[MAX_OPTION_SIZE][MAX_OPTION_VALUE_SIZE];
-
static int
strcmpigcase(const char *s1, const char *s2)
{
@@ -83,103 +78,6 @@ strcmpigcase(const char *s1, const char *s2)
return 1;
}
-/* option stuff */
-void
-hoption_set(int opt, const char *value)
-{
- if (opt >= MAX_OPTION_SIZE)
- {
- log_warn3("Option to high (%d >= %d)", opt, MAX_OPTION_SIZE);
- return;
- }
-
- strncpy(_hoption_table[opt], value, MAX_OPTION_VALUE_SIZE);
-
- return;
-}
-
-
-char *
-hoption_get(int opt)
-{
- if (opt >= MAX_OPTION_SIZE)
- {
- log_warn3("Option to high (%d >= %d)", opt, MAX_OPTION_SIZE);
- return "";
- }
-
- return _hoption_table[opt];
-}
-
-
-void
-hoption_init_args(int argc, char *argv[])
-{
- int i;
-
- hoption_set(HOPTION_TMP_DIR, "."); /* default value */
- hoption_set(HOPTION_SSL_CERT, "");
- hoption_set(HOPTION_SSL_PASS, "");
- hoption_set(HOPTION_SSL_CA, "");
-
- /* initialize from arguments */
- for (i = 0; i < argc; i++)
- {
- if (!strcmp(argv[i], NHTTP_ARG_TMPDIR) && i < argc - 1)
- {
- hoption_set(HOPTION_TMP_DIR, argv[i + 1]);
- }
- else if (!strcmp(argv[i], NHTTP_ARG_LOGFILE) && i < argc - 1)
- {
- log_set_file(argv[i + 1]);
- }
- else if (!strcmp(argv[i], NHTTP_ARG_CERT) && i < argc - 1)
- {
-#ifndef HAVE_SSL
- fprintf(stderr,
- "WARNING: csoap compiled without '--with-ssl' flag. Parameter '%s' is disabled",
- NHTTP_ARG_CERT);
-#else
- hoption_set(HOPTION_SSL_CERT, argv[i + 1]);
-#endif
- }
- else if (!strcmp(argv[i], NHTTP_ARG_CERTPASS) && i < argc - 1)
- {
-#ifndef HAVE_SSL
- fprintf(stderr,
- "WARNING: csoap compiled without '--with-ssl' flag. Parameter '%s' is disabled",
- NHTTP_ARG_CERTPASS);
-#else
- hoption_set(HOPTION_SSL_PASS, argv[i + 1]);
-#endif
- }
- else if (!strcmp(argv[i], NHTTP_ARG_CA) && i < argc - 1)
- {
-#ifndef HAVE_SSL
- fprintf(stderr,
- "WARNING: csoap compiled without '--with-ssl' flag. Parameter '%s' is disabled",
- NHTTP_ARG_CA);
-#else
- hoption_set(HOPTION_SSL_CA, argv[i + 1]);
-#endif
- }
- else if (!strcmp(argv[i], NHTTP_ARG_HTTPS))
- {
-#ifndef HAVE_SSL
- fprintf(stderr,
- "WARNING: csoap compiled without '--with-ssl' flag. Parameter '%s' is disabled",
- NHTTP_ARG_HTTPS);
-#else
- /* TODO (#1#) handle ssl arguments */
- /*SSLCertLess = 1;*/
-#endif
- }
- }
-
-
-}
-
-
#ifdef WIN32
#ifndef __MINGW32__
diff --git a/nanohttp/nanohttp-common.h b/nanohttp/nanohttp-common.h
index 307f349..afdaee6 100644
--- a/nanohttp/nanohttp-common.h
+++ b/nanohttp/nanohttp-common.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: nanohttp-common.h,v 1.27 2006/02/27 22:26:02 snowdrop Exp $
+ * $Id: nanohttp-common.h,v 1.28 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003-2004 Ferhat Ayaz
@@ -27,31 +27,33 @@
#include <stdlib.h>
#include <time.h>
-#define HEADER_CONTENT_LENGTH "Content-Length"
-#define HEADER_CONTENT_TYPE "Content-Type"
-#define HEADER_CONTENT_ID "Content-Id"
-#define HEADER_CONTENT_LOCATION "Content-Location"
+#define HEADER_CONTENT_LENGTH "Content-Length"
+#define HEADER_CONTENT_TYPE "Content-Type"
+#define HEADER_CONTENT_ID "Content-Id"
+#define HEADER_CONTENT_LOCATION "Content-Location"
#define HEADER_CONTENT_TRANSFER_ENCODING "Content-Transfer-Encoding"
-#define HEADER_TRANSFER_ENCODING "Transfer-Encoding"
-#define HEADER_CONNECTION "Connection"
+#define HEADER_TRANSFER_ENCODING "Transfer-Encoding"
+#define HEADER_CONNECTION "Connection"
-#define HEADER_HOST "Host"
-#define HEADER_DATE "Date"
-#define HEADER_ACCEPT "Accept"
+#define HEADER_HOST "Host"
+#define HEADER_DATE "Date"
+#define HEADER_ACCEPT "Accept"
-#define HEADER_AUTHORIZATION "Authorization"
#define HEADER_WWW_AUTHENTICATE "WWW-Authenticate"
+#define HEADER_PROXY_AUTHENTICATE "Proxy-Authenticate"
+#define HEADER_AUTHORIZATION "Authorization"
+#define HEADER_PROXY_AUTHORIZATION "Proxy-Authorization"
-#define NHTTPD_ARG_PORT "-NHTTPport"
-#define NHTTPD_ARG_TERMSIG "-NHTTPtsig"
-#define NHTTPD_ARG_MAXCONN "-NHTTPmaxconn"
-#define NHTTP_ARG_LOGFILE "-NHTTPlog"
-#define NHTTP_ARG_TMPDIR "-NHTTPtmpdir"
+#define NHTTPD_ARG_PORT "-NHTTPport"
+#define NHTTPD_ARG_TERMSIG "-NHTTPtsig"
+#define NHTTPD_ARG_MAXCONN "-NHTTPmaxconn"
-#define NHTTP_ARG_CERT "-NHTTPcert"
-#define NHTTP_ARG_CERTPASS "-NHTTPcertpass"
-#define NHTTP_ARG_CA "-NHTTPCA"
-#define NHTTP_ARG_HTTPS "-NHTTPS"
+#define NHTTP_ARG_LOGFILE "-NHTTPlog"
+
+#define NHTTP_ARG_CERT "-NHTTPcert"
+#define NHTTP_ARG_CERTPASS "-NHTTPcertpass"
+#define NHTTP_ARG_CA "-NHTTPCA"
+#define NHTTP_ARG_HTTPS "-NHTTPS"
#ifndef SAVE_STR
#define SAVE_STR(str) ((str==0)?("(null)"):(str))
@@ -142,7 +144,13 @@
#define XML_ERROR_PARSE 1601
/* SSL Errors */
-/*#define SSL_ERROR_INIT 1700*/
+#define HSSL_ERROR_CA_LIST 1710
+#define HSSL_ERROR_CONTEXT 1720
+#define HSSL_ERROR_CERTIFICATE 1730
+#define HSSL_ERROR_PEM 1740
+#define HSSL_ERROR_CLIENT 1750
+#define HSSL_ERROR_SERVER 1760
+#define HSSL_ERROR_CONNECT 1770
/*
Set Sleep function platform depended
@@ -459,15 +467,6 @@ void attachments_free(attachments_t * message);
void attachments_add_part(attachments_t * attachments, part_t * part);
-/* tmp directory for multipart/related stuff */
-#define HOPTION_TMP_DIR 2
-#define HOPTION_SSL_CERT 3
-#define HOPTION_SSL_PASS 4
-#define HOPTION_SSL_CA 5
-void hoption_init_args(int argc, char *argv[]);
-void hoption_set(int opt, const char *value);
-char *hoption_get(int opt);
-
/* logging stuff */
typedef enum log_level
{
diff --git a/nanohttp/nanohttp-mime.c b/nanohttp/nanohttp-mime.c
index 5ab5592..4733dff 100755
--- a/nanohttp/nanohttp-mime.c
+++ b/nanohttp/nanohttp-mime.c
@@ -3,7 +3,7 @@
* | \/ | | | | \/ | | _/
* |_''_| |_| |_''_| |_'/ PARSER
*
-* $Id: nanohttp-mime.c,v 1.11 2006/02/27 22:26:02 snowdrop Exp $
+* $Id: nanohttp-mime.c,v 1.12 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003-2004 Ferhat Ayaz
@@ -298,7 +298,6 @@ MIME_parse(MIME_read_function reader_function,
/* Read 1 byte */
status = MIME_reader_read(&reader, ch, 1);
- _log_str("buffer.log", ch, 1);
if (status == MIME_READ_EOF)
return MIME_PARSER_INCOMPLETE_MESSAGE;
else if (status == MIME_READ_ERROR)
@@ -311,7 +310,6 @@ MIME_parse(MIME_read_function reader_function,
{
/* Read 1 byte */
status = MIME_reader_read(&reader, ch, 1);
- _log_str("buffer.log", ch, 1);
if (status == MIME_READ_EOF)
return MIME_PARSER_INCOMPLETE_MESSAGE;
else if (status == MIME_READ_ERROR)
@@ -334,7 +332,6 @@ MIME_parse(MIME_read_function reader_function,
/* Read 1 byte */
status = MIME_reader_read(&reader, ch, 1);
- _log_str("buffer.log", ch, 1);
if (status == MIME_READ_EOF)
@@ -347,7 +344,6 @@ MIME_parse(MIME_read_function reader_function,
{
/* Read 1 byte */
status = MIME_reader_read(&reader, ch, 1);
- _log_str("buffer.log", ch, 1);
if (status == MIME_READ_EOF)
@@ -381,7 +377,6 @@ MIME_parse(MIME_read_function reader_function,
/* Jump to marker and read bytes */
MIME_reader_jump_marker(&reader);
MIME_reader_read(&reader, ch, boundary_length + 2);
- _log_str("buffer.log", ch, 1);
MIME_buffer_add_bytes(&buffer, ch, boundary_length + 2);
@@ -404,7 +399,6 @@ MIME_parse(MIME_read_function reader_function,
{
/* Read 1 byte */
status = MIME_reader_read(&reader, ch, 1);
- _log_str("buffer.log", ch, 1);
if (status == MIME_READ_EOF)
return MIME_PARSER_INCOMPLETE_MESSAGE;
@@ -533,8 +527,6 @@ mime_streamreader_function(void *userdata, unsigned char *dest, int *size)
*size = readed;
if (*size != -1)
{
- /*
- _log_str("reader.log", dest, *size); */
return MIME_READ_OK;
}
return MIME_READ_ERROR;
@@ -895,8 +887,6 @@ mime_message_parse_from_file(FILE * in, const char *root_id,
}
}
-
-
herror_t
mime_get_attachments(content_type_t * ctype, http_input_stream_t * in,
attachments_t ** dest)
@@ -930,7 +920,7 @@ mime_get_attachments(content_type_t * ctype, http_input_stream_t * in,
}
mimeMessage =
- mime_message_parse(in, root_id, boundary, hoption_get(HOPTION_TMP_DIR));
+ mime_message_parse(in, root_id, boundary, ".");
if (mimeMessage == NULL)
{
/* TODO (#1#): Handle Error in http form */
diff --git a/nanohttp/nanohttp-request.c b/nanohttp/nanohttp-request.c
index 1a3e998..97a2c21 100755
--- a/nanohttp/nanohttp-request.c
+++ b/nanohttp/nanohttp-request.c
@@ -1,5 +1,5 @@
/******************************************************************
-* $Id: nanohttp-request.c,v 1.11 2006/02/27 22:26:02 snowdrop Exp $
+* $Id: nanohttp-request.c,v 1.12 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -45,7 +45,7 @@
#include "nanohttp-request.h"
static hrequest_t *
-hrequest_new()
+hrequest_new(void)
{
hrequest_t *req;
@@ -228,7 +228,6 @@ hrequest_free(hrequest_t * req)
if (req == NULL)
return;
-
hpairnode_free_deep(req->header);
hpairnode_free_deep(req->query);
@@ -242,13 +241,15 @@ hrequest_free(hrequest_t * req)
attachments_free(req->attachments);
free(req);
+
+ return;
}
herror_t
-hrequest_new_from_socket(hsocket_t sock, hrequest_t ** out)
+hrequest_new_from_socket(hsocket_t *sock, hrequest_t ** out)
{
- int i = 0, readed;
+ int i, readed;
herror_t status;
hrequest_t *req;
char buffer[MAX_HEADER_SIZE + 1];
@@ -256,33 +257,29 @@ hrequest_new_from_socket(hsocket_t sock, hrequest_t ** out)
memset(buffer, 0, MAX_HEADER_SIZE);
/* Read header */
- while (i < MAX_HEADER_SIZE)
+ for(i=0; i < MAX_HEADER_SIZE; i++)
{
- status = hsocket_read(sock, &(buffer[i]), 1, 1, &readed);
- if (status != H_OK)
+ if ((status = hsocket_read(sock, &(buffer[i]), 1, 1, &readed)) != H_OK)
{
- if (herror_code(status) != HSOCKET_ERROR_SSLCLOSE)
- {
- log_error1("Socket read error");
- }
+ log_error2("hsocket_read failed (%s)", herror_message(status));
return status;
}
buffer[i + 1] = '\0'; /* for strmp */
+// log_error2("buffer=\"%s\"", buffer);
+
if (i > 3)
{
if (!strcmp(&(buffer[i - 1]), "\n\n") ||
!strcmp(&(buffer[i - 2]), "\n\r\n"))
break;
}
- i++;
}
/* Create response */
req = _hrequest_parse_header(buffer);
-
/* Create input stream */
req->in = http_input_stream_new(sock, req->header);
diff --git a/nanohttp/nanohttp-request.h b/nanohttp/nanohttp-request.h
index c0c014c..03cea1e 100755
--- a/nanohttp/nanohttp-request.h
+++ b/nanohttp/nanohttp-request.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: nanohttp-request.h,v 1.6 2006/02/27 22:26:02 snowdrop Exp $
+ * $Id: nanohttp-request.h,v 1.7 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003-2004 Ferhat Ayaz
@@ -49,7 +49,7 @@ typedef struct hrequest
extern "C" {
#endif
-herror_t hrequest_new_from_socket(hsocket_t sock, hrequest_t ** out);
+herror_t hrequest_new_from_socket(hsocket_t *sock, hrequest_t ** out);
void hrequest_free(hrequest_t * req);
#ifdef __cplusplus
diff --git a/nanohttp/nanohttp-response.c b/nanohttp/nanohttp-response.c
index 64eac44..cb24d10 100755
--- a/nanohttp/nanohttp-response.c
+++ b/nanohttp/nanohttp-response.c
@@ -1,5 +1,5 @@
/******************************************************************
-* $Id: nanohttp-response.c,v 1.9 2006/02/27 22:26:02 snowdrop Exp $
+* $Id: nanohttp-response.c,v 1.10 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003-2004 Ferhat Ayaz
@@ -146,9 +146,9 @@ _hresponse_parse_header(const char *buffer)
herror_t
-hresponse_new_from_socket(hsocket_t sock, hresponse_t ** out)
+hresponse_new_from_socket(hsocket_t *sock, hresponse_t ** out)
{
- int i = 0, readed;
+ int i = 0, count;
herror_t status;
hresponse_t *res;
attachments_t *mimeMessage;
@@ -158,8 +158,7 @@ read_header: /* for errorcode: 100 (continue) */
/* Read header */
while (i < MAX_HEADER_SIZE)
{
- status = hsocket_read(sock, &(buffer[i]), 1, 1, &readed);
- if (status != H_OK)
+ if ((status = hsocket_read(sock, &(buffer[i]), 1, 1, &count)) != H_OK)
{
log_error1("Socket read error");
return status;
diff --git a/nanohttp/nanohttp-response.h b/nanohttp/nanohttp-response.h
index 3b3f532..622ef63 100755
--- a/nanohttp/nanohttp-response.h
+++ b/nanohttp/nanohttp-response.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: nanohttp-response.h,v 1.6 2006/02/27 22:26:02 snowdrop Exp $
+ * $Id: nanohttp-response.h,v 1.7 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003-2004 Ferhat Ayaz
@@ -47,7 +47,7 @@ typedef struct hresponse
extern "C" {
#endif
-herror_t hresponse_new_from_socket(hsocket_t sock, hresponse_t ** out);
+herror_t hresponse_new_from_socket(hsocket_t *sock, hresponse_t ** out);
void hresponse_free(hresponse_t * res);
#ifdef __cplusplus
diff --git a/nanohttp/nanohttp-server.c b/nanohttp/nanohttp-server.c
index d60c797..9a2c721 100644
--- a/nanohttp/nanohttp-server.c
+++ b/nanohttp/nanohttp-server.c
@@ -1,5 +1,5 @@
/******************************************************************
-* $Id: nanohttp-server.c,v 1.51 2006/02/27 22:26:02 snowdrop Exp $
+* $Id: nanohttp-server.c,v 1.52 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -83,6 +83,7 @@
typedef struct _conndata
{
+ volatile int flag;
hsocket_t sock;
#ifdef WIN32
HANDLE tid;
@@ -91,8 +92,10 @@ typedef struct _conndata
pthread_attr_t attr;
#endif
time_t atime;
-}
-conndata_t;
+} conndata_t;
+
+#define CONNECTION_FREE 0
+#define CONNECTION_IN_USE 1
/*
* -----------------------------------------------------
@@ -109,7 +112,12 @@ static int _httpd_max_connections = 20;
static hservice_t *_httpd_services_default = NULL;
static hservice_t *_httpd_services_head = NULL;
static hservice_t *_httpd_services_tail = NULL;
+
static conndata_t *_httpd_connection;
+static pthread_mutex_t _httpd_connection_lock;
+
+static int _httpd_enable_service_list = 0;
+static int _httpd_enable_statistics = 0;
#ifdef WIN32
static DWORD _httpd_terminate_signal = CTRL_C_EVENT;
@@ -127,24 +135,19 @@ _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++)
+ for (i=1; i < argc; i++)
{
- if (!strcmp (argv[i-1], NHTTPD_ARG_PORT))
+ if (!strcmp(argv[i-1], NHTTPD_ARG_PORT))
{
- _httpd_port = atoi (argv[i]);
+ _httpd_port = atoi(argv[i]);
}
- else if (!strcmp (argv[i-1], NHTTPD_ARG_TERMSIG))
+ else if (!strcmp(argv[i-1], NHTTPD_ARG_TERMSIG))
{
- _httpd_terminate_signal = atoi (argv[i]);
+ _httpd_terminate_signal = atoi(argv[i]);
}
- else if (!strcmp (argv[i-1], NHTTPD_ARG_MAXCONN))
+ else if (!strcmp(argv[i-1], NHTTPD_ARG_MAXCONN))
{
- _httpd_max_connections = atoi (argv[i]);
+ _httpd_max_connections = atoi(argv[i]);
}
}
@@ -153,6 +156,33 @@ _httpd_parse_arguments(int argc, char **argv)
return;
}
+
+static void
+_httpd_connection_slots_init(void)
+{
+ int i;
+
+ pthread_mutex_init(&_httpd_connection_lock, NULL);
+ _httpd_connection = calloc (_httpd_max_connections, sizeof (conndata_t));
+ for (i = 0; i < _httpd_max_connections; i++)
+ hsocket_init(&(_httpd_connection[i].sock));
+
+ return;
+}
+
+static void
+_httpd_register_builtin_services(void)
+{
+
+ if (_httpd_enable_service_list)
+;// httpd_register("/httpd/services", _httpd_list_services);
+
+ if (_httpd_enable_statistics)
+;// httpd_register("/httpd/statistics", _httpd_statistics);
+
+ return;
+}
+
/*
* -----------------------------------------------------
* FUNCTION: httpd_init
@@ -162,29 +192,18 @@ _httpd_parse_arguments(int argc, char **argv)
herror_t
httpd_init (int argc, char *argv[])
{
- int i;
herror_t status;
-#ifdef HAVE_SSL
- 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)
+ if ((status = hsocket_module_init(argc, argv)) != H_OK)
return status;
log_verbose2 ("socket bind to port '%d'", _httpd_port);
- /* init built-in services */
+ _httpd_connection_slots_init();
- /* httpd_register("/httpd/list", service_list); */
-
- _httpd_connection = calloc (_httpd_max_connections, sizeof (conndata_t));
- for (i = 0; i < _httpd_max_connections; i++)
- hsocket_init(&(_httpd_connection[i].sock));
+ _httpd_register_builtin_services();
#ifdef WIN32
/*
@@ -194,29 +213,13 @@ httpd_init (int argc, char *argv[])
*/
#endif
- /* 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);
- SSLCA = hoption_get(HOPTION_SSL_CA);
- log_verbose3("SSL: %s %s", SSLCert, SSLCA);
- if (SSLCert[0] != '\0'){
-
- start_ssl();
- status = hsocket_init_ssl(&_httpd_socket, SSLCert, SSLPass, SSLCA);
- }
- else
-#endif
- {
- status = hsocket_init (&_httpd_socket);
- }
-
- if (status != H_OK)
+ if ((status = hsocket_init (&_httpd_socket)) != H_OK)
{
+ log_error2("hsocket_init failed (%s)", herror_message(status));
return status;
}
- return hsocket_bind (&_httpd_socket, _httpd_port);
+ return hsocket_bind(&_httpd_socket, _httpd_port);
}
/*
@@ -224,7 +227,6 @@ httpd_init (int argc, char *argv[])
* FUNCTION: httpd_register
* -----------------------------------------------------
*/
-
int
httpd_register_secure(const char *ctx, httpd_service func, httpd_auth auth)
{
@@ -268,7 +270,7 @@ httpd_register_default_secure(const char *ctx, httpd_service service, httpd_auth
ret = httpd_register_secure(ctx, service, auth);
- /* this is broken, but working */
+ /* XXX: this is broken, but working */
_httpd_services_default = _httpd_services_tail;
return ret;
@@ -292,7 +294,7 @@ httpd_get_port(void)
* -----------------------------------------------------
*/
hservice_t *
-httpd_services ()
+httpd_services(void)
{
return _httpd_services_head;
}
@@ -303,9 +305,11 @@ httpd_services ()
* -----------------------------------------------------
*/
static void
-hservice_free (hservice_t * service)
+hservice_free(hservice_t * service)
{
free (service);
+
+ return;
}
/*
@@ -340,6 +344,8 @@ void
httpd_response_set_content_type (httpd_conn_t * res, const char *content_type)
{
strncpy (res->content_type, content_type, 25);
+
+ return;
}
@@ -414,7 +420,7 @@ httpd_send_internal_error (httpd_conn_t * conn, const char *errmsg)
httpd_set_header (conn, HEADER_CONTENT_LENGTH, buflen);
httpd_send_header (conn, 500, "INTERNAL");
- return hsocket_nsend (conn->sock, buffer, strlen (buffer));
+ return http_output_stream_write_string(conn->out, buffer);
}
/*
@@ -449,7 +455,7 @@ httpd_request_print (hrequest_t * req)
httpd_conn_t *
-httpd_new (hsocket_t sock)
+httpd_new (hsocket_t *sock)
{
httpd_conn_t *conn;
@@ -512,17 +518,17 @@ static int _httpd_decode_authorization(const char *value, char **user, char **pa
len = strlen(value) * 2;
if (!(tmp = (char *)calloc(1, len))) {
- log_error2("malloc failed (%s)", strerror(errno));
+ log_error2("calloc failed (%s)", strerror(errno));
return -1;
}
value = strstr(value, " ") + 1;
- log_error2("Authorization (base64) = \"%s\"", value);
+ log_verbose2("Authorization (base64) = \"%s\"", value);
base64_decode(value, tmp);
- log_error2("Authorization (ascii) = \"%s\"", tmp);
+ log_verbose2("Authorization (ascii) = \"%s\"", tmp);
if ((tmp2 = strstr(tmp, ":")))
{
@@ -584,81 +590,63 @@ static void *
httpd_session_main (void *data)
#endif
{
- 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 */
+ hrequest_t *req; /* only for test */
conndata_t *conn;
- httpd_conn_t *rconn = NULL;
- hservice_t *service = NULL;
+ httpd_conn_t *rconn;
+ hservice_t *service;
herror_t status;
+ int done;
- header[0] = '\0';
- len = 0;
conn = (conndata_t *) data;
- log_verbose1 ("starting httpd_session_main()");
-#ifdef HAVE_SSL
- if (!_httpd_socket.sslCtx)
- {
- log_verbose1 ("Using HTTP");
- }
- else
- {
- log_verbose1 ("Using HTTPS");
- conn->sock.ssl = init_ssl (_httpd_socket.sslCtx, conn->sock.sock, SSL_SERVER);
- hsocket_block (conn->sock, 0);
- if (conn->sock.ssl == NULL)
- {
- done = 1;
- }
- }
-#endif
- conn->atime = time ((time_t) 0);
- /* call the service */
-/* req = hrequest_new_from_buffer (header);*/
+ log_verbose2("starting new httpd session on socket %d", conn->sock);
- rconn = httpd_new (conn->sock);
+ rconn = httpd_new(&(conn->sock));
+ done = 0;
while (!done)
{
- log_verbose1 ("starting HTTP request");
+ log_verbose2("starting HTTP request on socket %d", conn->sock);
/* XXX: only used in WSAreaper */
conn->atime = time(NULL);
- if ((status = hrequest_new_from_socket (conn->sock, &req)) != H_OK)
+ 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)
+ int code;
+
+ switch((code = herror_code(status)))
{
- httpd_send_internal_error (rconn, herror_message (status));
- herror_release (status);
+ case HSOCKET_ERROR_SSLCLOSE:
+ case HSOCKET_ERROR_RECEIVE:
+ log_error2("hrequest_new_from_socket failed (%s)", herror_message(status));
+ break;
+ default:
+ httpd_send_internal_error(rconn, herror_message(status));
+ break;
}
+ herror_release(status);
done = 1;
}
else
{
- char *conn_str = hpairnode_get_ignore_case (req->header, HEADER_CONNECTION);
+ char *conn_str;
+
+ httpd_request_print (req);
+
+ conn_str = hpairnode_get_ignore_case (req->header, HEADER_CONNECTION);
if (conn_str && strncasecmp (conn_str, "close", 6) == 0)
- {
done = 1;
- }
+
if (!done)
- {
done = req->version == HTTP_1_0 ? 1 : 0;
- }
- httpd_request_print (req);
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)
{
service->func (rconn, req);
@@ -669,20 +657,34 @@ httpd_session_main (void *data)
}
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 {
-
- httpd_set_header(rconn, HEADER_WWW_AUTHENTICATE, "Basic realm=\"nanoHTTP\"");
- httpd_send_header(rconn, 401, "Unauthorized");
- hsocket_send(conn->sock, "<html><head><title>Unauthorized</title></header><body><h1>Unauthorized request logged</h1></body></html>");
- }
+ else
+ {
+ char *template =
+ "<html>"
+ "<head>"
+ "<title>Unauthorized</title>"
+ "</head>"
+ "<body>"
+ "<h1>Unauthorized request logged</h1>"
+ "</body>"
+ "</html>";
+
+ httpd_set_header(rconn, HEADER_WWW_AUTHENTICATE, "Basic realm=\"nanoHTTP\"");
+ httpd_send_header(rconn, 401, "Unauthorized");
+ http_output_stream_write_string(rconn->out, template);
+ done = 1;
+ }
}
else
{
+ char buffer[256];
sprintf (buffer, "no service for '%s' found", req->path);
log_verbose1 (buffer);
httpd_send_internal_error (rconn, buffer);
@@ -693,7 +695,7 @@ httpd_session_main (void *data)
httpd_free(rconn);
- hsocket_close (&(conn->sock));
+ hsocket_close(&(conn->sock));
#ifdef WIN32
CloseHandle ((HANDLE) conn->tid);
@@ -701,7 +703,7 @@ httpd_session_main (void *data)
pthread_attr_destroy(&(conn->attr));
#endif
- hsocket_init(&(conn->sock));
+ conn->flag = CONNECTION_FREE;
#ifdef WIN32
_endthread ();
@@ -722,23 +724,19 @@ httpd_set_header (httpd_conn_t * conn, const char *key, const char *value)
log_warn1 ("Connection object is NULL");
return 0;
}
- p = conn->header;
- while (p != NULL)
+
+ for (p=conn->header; p; p=p->next)
{
- if (p->key != NULL)
+ if (p->key && !strcmp(p->key, key))
{
- if (!strcmp (p->key, key))
- {
- free (p->value);
- p->value = (char *) malloc (strlen (value) + 1);
- strcpy (p->value, value);
- return 1;
- }
+ free (p->value);
+ p->value = strdup(value);
+ return 1;
}
- p = p->next;
}
conn->header = hpairnode_new (key, value, conn->header);
+
return 0;
}
@@ -795,19 +793,20 @@ httpd_term (DWORD sig)
// log_debug2 ("Got signal %d", sig);
if (sig == _httpd_terminate_signal)
_httpd_run = 0;
+
return TRUE;
}
-
#else
-
void
httpd_term (int sig)
{
log_debug2 ("Got signal %d", sig);
+
if (sig == _httpd_terminate_signal)
_httpd_run = 0;
-}
+ return;
+}
#endif
/*
@@ -840,21 +839,28 @@ static conndata_t *
_httpd_wait_for_empty_conn (void)
{
int i;
+
+ pthread_mutex_lock(&_httpd_connection_lock);
for (i = 0; ; i++)
{
- if (!_httpd_run)
+ if (!_httpd_run) {
+
+ pthread_mutex_unlock(&_httpd_connection_lock);
return NULL;
+ }
if (i >= _httpd_max_connections)
{
system_sleep (1);
i = -1;
}
- else if (_httpd_connection[i].sock.sock == HSOCKET_FREE)
+ else if (_httpd_connection[i].flag == CONNECTION_FREE)
{
+ _httpd_connection[i].flag = CONNECTION_IN_USE;
break;
}
}
+ pthread_mutex_unlock(&_httpd_connection_lock);
return &_httpd_connection[i];
}
@@ -879,10 +885,11 @@ _httpd_start_thread (conndata_t * conn)
#endif
pthread_sigmask (SIG_BLOCK, &thrsigset, NULL);
- err = pthread_create (&(conn->tid), &(conn->attr), httpd_session_main, conn);
- if (err)
- log_error2 ("Error creating thread: ('%d')", err);
+ if ((err = pthread_create (&(conn->tid), &(conn->attr), httpd_session_main, conn)))
+ log_error2 ("pthread_create failed (%s)", strerror(err));
#endif
+
+ return;
}
@@ -895,47 +902,32 @@ _httpd_start_thread (conndata_t * conn)
herror_t
httpd_run (void)
{
- herror_t err;
+ struct timeval timeout;
conndata_t *conn;
+ herror_t err;
fd_set fds;
- struct timeval timeout;
log_verbose1 ("starting run routine");
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
-
#ifndef WIN32
sigemptyset (&thrsigset);
sigaddset (&thrsigset, SIGALRM);
#endif
- /* listen to port */
- if ((err = hsocket_listen (_httpd_socket)) != H_OK)
- {
- log_error2 ("httpd_run(): '%d'", herror_message (err));
- return err;
- }
- log_verbose2 ("listening to port '%d'", _httpd_port);
-
- /* register signal handler */
_httpd_register_signal_handler ();
- /* make the socket non blocking */
- if ((err = hsocket_block (_httpd_socket, 0)) != H_OK)
+ if ((err = hsocket_listen(&_httpd_socket)) != H_OK)
{
- log_error2 ("httpd_run(): '%s'", herror_message (err));
+ log_error2 ("hsocket_listen failed (%s)", herror_message (err));
return err;
}
while (_httpd_run)
{
- /* Get an empty connection struct */
conn = _httpd_wait_for_empty_conn ();
if (!_httpd_run)
break;
-
/* Wait for a socket to accept */
while (_httpd_run)
{
@@ -971,30 +963,18 @@ httpd_run (void)
if (!_httpd_run)
break;
- /* Accept a socket */
- err = hsocket_accept (_httpd_socket, &(conn->sock));
- if (err != H_OK
- /* TODO (#1#) is this check neccessary?
- && herror_code (err) == SSL_ERROR_INIT*/
- )
+ if ((err = hsocket_accept(&_httpd_socket, &(conn->sock))) != H_OK)
{
- hsocket_close(&(conn->sock));
+ log_error2("hsocket_accept failed (%s)", herror_message (err));
- hsocket_init(&(conn->sock));
+ hsocket_close(&(conn->sock));
- log_error1(herror_message (err));
continue;
}
- else if (err != H_OK)
- {
- log_error2 ("Can not accept socket: %s", herror_message (err));
- return err; /* this is hard core! */
- }
- /* Now start a thread */
_httpd_start_thread (conn);
}
- free (_httpd_connection);
+
return 0;
}
@@ -1012,6 +992,8 @@ httpd_destroy (void)
hsocket_module_destroy ();
+ free (_httpd_connection);
+
return;
}
@@ -1239,8 +1221,7 @@ httpd_mime_send_file (httpd_conn_t * conn, const char *content_id, const char *c
return herror_new ("httpd_mime_send_file", FILE_ERROR_READ, "Can not read from file '%d'", filename);
}
- status = http_output_stream_write (conn->out, buffer, size);
- if (status != H_OK)
+ if ((status = http_output_stream_write (conn->out, buffer, size)) != H_OK)
{
fclose (fd);
return status;
diff --git a/nanohttp/nanohttp-server.h b/nanohttp/nanohttp-server.h
index 1768edd..20d7834 100644
--- a/nanohttp/nanohttp-server.h
+++ b/nanohttp/nanohttp-server.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: nanohttp-server.h,v 1.15 2006/02/27 22:26:02 snowdrop Exp $
+ * $Id: nanohttp-server.h,v 1.16 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -34,7 +34,7 @@
typedef struct httpd_conn
{
- hsocket_t sock;
+ hsocket_t *sock;
char content_type[25];
http_output_stream_t *out;
hpair_t *header;
@@ -68,6 +68,9 @@ extern "C" {
Begin httpd_* function set
*/
herror_t httpd_init(int argc, char *argv[]);
+void httpd_destroy(void);
+
+herror_t httpd_run(void);
int httpd_register(const char *ctx, httpd_service service);
int httpd_register_secure(const char *ctx, httpd_service service, httpd_auth auth);
@@ -75,12 +78,9 @@ int httpd_register_secure(const char *ctx, httpd_service service, httpd_auth aut
int httpd_register_default(const char *ctx, httpd_service service);
int httpd_register_secure_default(const char *ctx, httpd_service service, httpd_auth auth);
-herror_t httpd_run();
-void httpd_destroy();
-
int httpd_get_port(void);
-hservice_t *httpd_services();
+hservice_t *httpd_services(void);
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 77d4d9c..e1ee807 100644
--- a/nanohttp/nanohttp-socket.c
+++ b/nanohttp/nanohttp-socket.c
@@ -1,5 +1,5 @@
/******************************************************************
-* $Id: nanohttp-socket.c,v 1.53 2006/02/27 22:26:02 snowdrop Exp $
+* $Id: nanohttp-socket.c,v 1.54 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -87,12 +87,26 @@ typedef int ssize_t;
#include "nanohttp-common.h"
#include "nanohttp-ssl.h"
-#ifdef HAVE_SSL
-/*SSL_CTX *SSLctx = NULL;
-char *SSLCert = NULL;
-char *SSLPass = NULL;
-char *SSLCA = NULL;
-int SSLCertLess = 0;*/
+#ifdef WIN32
+static inline void
+_hsocket_module_sys_init(int argc, char **argv)
+{
+ struct WSAData info;
+ WSAStartup(MAKEWORD(2, 2), &info);
+
+ return;
+}
+
+static inline void
+_hsocket_module_sys_destroy(void)
+{
+ WSACleanup();
+
+ return;
+}
+#else
+static inline void _hsocket_module_sys_init(int argc, char **argv) { return; }
+static inline void _hsocket_module_sys_destroy(void) { return; }
#endif
/*--------------------------------------------------
@@ -101,29 +115,20 @@ NOTE: This will be called from httpd_init()
for server and from httpc_init() for client
----------------------------------------------------*/
herror_t
-hsocket_module_init()
+hsocket_module_init(int argc, char **argv)
{
-#ifdef WIN32
- struct WSAData info;
- WSAStartup(MAKEWORD(2, 2), &info);
-#endif
+ _hsocket_module_sys_init(argc, argv);
-#ifdef HAVE_SSL
- start_ssl();
-#endif
-
- return H_OK;
+ return hssl_module_init(argc, argv);
}
/*--------------------------------------------------
FUNCTION: hsocket_module_destroy
----------------------------------------------------*/
void
-hsocket_module_destroy()
+hsocket_module_destroy(void)
{
-#ifdef WIN32
- WSACleanup();
-#endif
+ _hsocket_module_sys_destroy();
return;
}
@@ -132,9 +137,8 @@ hsocket_module_destroy()
FUNCTION: hsocket_init
----------------------------------------------------*/
herror_t
-hsocket_init(hsocket_t * sock)
+hsocket_init(hsocket_t *sock)
{
- log_verbose1("Starting hsocket init");
memset(sock, 0, sizeof(hsocket_t));
sock->sock = HSOCKET_FREE;
@@ -143,38 +147,13 @@ hsocket_init(hsocket_t * sock)
}
/*--------------------------------------------------
-FUNCTION: hsocket_init_ssl
-----------------------------------------------------*/
-#ifdef HAVE_SSL
-herror_t
-hsocket_init_ssl(hsocket_t * sock,
- const char* sslCert,
- const char* sslPass,
- const char* sslCA)
-{
- hsocket_init(sock);
-
- log_verbose1("calling initialize_ctx()");
- sock->sslCtx = initialize_ctx(sslCert, sslPass, sslCA);
- if (sock->sslCtx == NULL)
- {
- return herror_new("hsocket_init_ctx", HSOCKET_ERROR_SSLCTX,
- "Unable to initialize SSL CTX");
- }
-
- return H_OK;
-}
-
-#endif
-
-
-/*--------------------------------------------------
FUNCTION: hsocket_free
----------------------------------------------------*/
void
-hsocket_free(hsocket_t sock)
+hsocket_free(hsocket_t *sock)
{
- /* nothing to free for unix sockets */
+ /* nop */
+
return;
}
@@ -182,21 +161,20 @@ hsocket_free(hsocket_t sock)
FUNCTION: hsocket_open
----------------------------------------------------*/
herror_t
-hsocket_open(hsocket_t * dsock, const char *hostname, int port)
+hsocket_open(hsocket_t * dsock, const char *hostname, int port, int ssl)
{
- hsocket_t sock;
- char *ip;
struct sockaddr_in address;
struct hostent *host;
+ char *ip;
- if ((sock.sock = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
+ if ((dsock->sock = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
return herror_new("hsocket_open", HSOCKET_ERROR_CREATE,
- "Socket error: %d", errno);
+ "Socket error (%s)", strerror(errno));
/* Get host data */
if (!(host = gethostbyname(hostname)))
return herror_new("hsocket_open", HSOCKET_ERROR_GET_HOSTNAME,
- "Socket error: %d", errno);
+ "Socket error (%s)", strerror(errno));
ip = inet_ntoa(*(struct in_addr *) *host->h_addr_list);
address.sin_addr.s_addr = inet_addr(ip);
@@ -205,31 +183,23 @@ hsocket_open(hsocket_t * dsock, const char *hostname, int port)
address.sin_family = host->h_addrtype;
address.sin_port = htons((unsigned short) port);
+ log_debug4("Opening %s://%s:%i", ssl ? "https" : "http", hostname, port);
+
/* connect to the server */
- if (connect(sock.sock, (struct sockaddr *) &address, sizeof(address)) != 0)
+ if (connect(dsock->sock, (struct sockaddr *) &address, sizeof(address)) != 0)
return herror_new("hsocket_open", HSOCKET_ERROR_CONNECT,
- "Socket error: %d", errno);
+ "Socket error (%s)", strerror(errno));
-#ifdef HAVE_SSL
- if (!dsock->sslCtx)
- {
-#endif
- log_verbose1("Using HTTP");
- dsock->sock = sock.sock;
-#ifdef HAVE_SSL
- }
- else
+ if (ssl)
{
herror_t status;
- log_verbose1("Using HTTPS");
- dsock->ssl = init_ssl(dsock->sslCtx, sock.sock, SSL_CLIENT);
- if ((status = hsocket_block(*dsock, dsock->block)) != H_OK)
+
+ if ((status = hssl_client_ssl(dsock)) != H_OK)
{
- log_error1("Cannot make socket non-blocking");
+ log_error2("hssl_client_ssl failed (%s)", herror_message(status));
return status;
}
}
-#endif
return H_OK;
}
@@ -247,9 +217,9 @@ hsocket_bind(hsocket_t * dsock, int port)
/* create socket */
if ((sock.sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
- log_error3("Can not create socket: '%s'", "Socket error: %d", errno);
+ log_error2("Cannot create socket (%s)", strerror(errno));
return herror_new("hsocket_bind", HSOCKET_ERROR_CREATE,
- "Socket error: %d", errno);
+ "Socket error (%s)", strerror(errno));
}
setsockopt(sock.sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
@@ -262,59 +232,83 @@ hsocket_bind(hsocket_t * dsock, int port)
if (bind(sock.sock, (struct sockaddr *) &addr, sizeof(struct sockaddr)) ==
-1)
{
- log_error3("Can not bind: '%s'", "Socket error: %d", errno);
- return herror_new("hsocket_bind", HSOCKET_ERROR_BIND, "Socket error: %d",
- errno);
+ log_error2("Cannot bind socket (%s)", strerror(errno));
+ return herror_new("hsocket_bind", HSOCKET_ERROR_BIND, "Socket error (%s)",
+ strerror(errno));
}
dsock->sock = sock.sock;
return H_OK;
}
-/*----------------------------------------------------------
-FUNCTION: hsocket_accept
-----------------------------------------------------------*/
-herror_t
-hsocket_accept(hsocket_t sock, hsocket_t * dest)
+#ifdef WIN32
+static herror_t
+_hsocket_sys_accept(hsocket_t *sock, hsocket_t *dest)
{
socklen_t asize;
hsocket_t sockfd;
- struct sockaddr_in addr;
-
- if (sock.sock <= 0)
- return herror_new("hsocket_accept", HSOCKET_ERROR_NOT_INITIALIZED,
- "Called hsocket_listen() before initializing!");
asize = sizeof(struct sockaddr_in);
-#ifdef WIN32
while (1)
{
- sockfd.sock = accept(sock.sock, (struct sockaddr *) &addr, &asize);
+ sockfd.sock = accept(sock->sock, (struct sockaddr *) &(dest->addr), &asize);
if (sockfd.sock == INVALID_SOCKET)
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
return herror_new("hsocket_accept", HSOCKET_ERROR_ACCEPT,
- "Socket error: %d", errno);
+ "Socket error (%s)", strerror(errno));
}
else
{
break;
}
}
+
+ dest->sock = sockfd.sock;
+
+ return H_OK;
+}
#else
-/* TODO (#1#): why not a loop like in win32? */
- sockfd.sock = accept(sock.sock, (struct sockaddr *) &addr, &asize);
- if (sockfd.sock == -1)
+static herror_t
+_hsocket_sys_accept(hsocket_t *sock, hsocket_t *dest)
+{
+ socklen_t len;
+
+ len = sizeof(struct sockaddr_in);
+
+ if ((dest->sock = accept(sock->sock, (struct sockaddr *) &(dest->addr), &len)) == -1)
{
- return herror_new("hsocket_accept", HSOCKET_ERROR_ACCEPT,
- "Socket error: %d", errno);
+ log_warn2("accept failed (%s)", strerror(errno));
+ return herror_new("hsocket_accept", HSOCKET_ERROR_ACCEPT, "Cannot accept network connection (%s)", strerror(errno));
}
+
+ return H_OK;
+}
#endif
-/* TODO (#1#): Write to access.log file */
- log_verbose3("accept new socket (%d) from '%s'", sockfd.sock,
- SAVE_STR(((char *) inet_ntoa(addr.sin_addr))));
+/*----------------------------------------------------------
+FUNCTION: hsocket_accept
+----------------------------------------------------------*/
+herror_t
+hsocket_accept(hsocket_t *sock, hsocket_t *dest)
+{
+ herror_t status;
+
+ if (sock->sock < 0)
+ return herror_new("hsocket_accept", HSOCKET_ERROR_NOT_INITIALIZED,
+ "hsocket_t not initialized");
+
+ if ((status = _hsocket_sys_accept(sock, dest)) != H_OK)
+ return status;
+
+ if ((status = hssl_server_ssl(dest)) != H_OK)
+ {
+ log_warn("hsocket_accept", "SSL startup failed (%s)", herror_message(status));
+ return status;
+ }
+
+ log_debug3("accepting connection from '%s' socket=%d",
+ SAVE_STR(((char *) inet_ntoa(dest->addr.sin_addr))), dest->sock);
- dest->sock = sockfd.sock;
return H_OK;
}
@@ -322,17 +316,17 @@ hsocket_accept(hsocket_t sock, hsocket_t * dest)
FUNCTION: hsocket_listen
----------------------------------------------------*/
herror_t
-hsocket_listen(hsocket_t sock)
+hsocket_listen(hsocket_t *sock)
{
- if (sock.sock <= 0)
+ if (sock->sock < 0)
return herror_new("hsocket_listen", HSOCKET_ERROR_NOT_INITIALIZED,
- "Called hsocket_listen() before initializing!");
+ "Called hsocket_listen before initializing!");
- if (listen(sock.sock, 15) == -1)
+ if (listen(sock->sock, 15) == -1)
{
- log_error3("Can not listen: '%s'", "Socket error: %d", errno);
+ log_error2("listen failed (%s)", strerror(errno));
return herror_new("hsocket_listen", HSOCKET_ERROR_LISTEN,
- "Socket error: %d", errno);
+ "Cannot listen on this socket (%s)", strerror(errno));
}
return H_OK;
@@ -360,6 +354,8 @@ _hsocket_sys_close(hsocket_t *sock)
shutdown(sock->sock, SHUT_RDWR);
+ close(sock->sock);
+
return;
}
#endif
@@ -372,14 +368,7 @@ hsocket_close(hsocket_t *sock)
{
log_verbose3("closing socket %p (%d)...", sock, sock->sock);
-#ifdef HAVE_SSL
- if (sock->ssl)
- {
- log_verbose1("Closing SSL");
- ssl_cleanup(sock->ssl);
- sock->ssl = NULL;
- }
-#endif
+ hssl_cleanup(sock);
_hsocket_sys_close(sock);
@@ -392,68 +381,34 @@ 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 byte_t * bytes, int n)
{
- int size;
- int total = 0;
+ herror_t status;
+ size_t total = 0;
+ size_t size;
log_verbose2("Starting to send on sock=%p", &sock);
- if (sock.sock <= 0)
+ if (sock->sock < 0)
return herror_new("hsocket_nsend", HSOCKET_ERROR_NOT_INITIALIZED,
- "Called hsocket_listen() before initializing!");
+ "hsocket not initialized");
/* log_verbose2( "SENDING %s", bytes );*/
- /* TODO (#1#): check return value and send again until n bytes sent */
while (1)
{
-#ifdef HAVE_SSL
- log_verbose2("ssl = %p", sock.ssl);
- if (sock.ssl)
- {
- size = SSL_write(sock.ssl, bytes + total, n);
- }
- else
- {
-#endif
- size = send((int) sock.sock, bytes + total, n, 0);
-#ifdef HAVE_SSL
- }
-#endif
- log_verbose2("Sent %d", size);
- /* 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)
+
+ if ((status = hssl_write(sock, bytes + total, n, &size)) != H_OK)
{
-#ifdef HAVE_SSL
- if (sock.ssl)
- {
- log_error1("Send error");
- log_ssl_error(sock.ssl, size);
- }
-#endif
- return herror_new("hsocket_nsend", HSOCKET_ERROR_SEND,
- "Socket error: %d", errno);
+ log_warn("hssl_write failed (%s)", herror_message(status));
+ return status;
}
-#endif
+
n -= size;
total += size;
if (n <= 0)
break;
}
+
return H_OK;
}
@@ -461,125 +416,39 @@ hsocket_nsend(hsocket_t sock, const byte_t * bytes, int n)
FUNCTION: hsocket_send
----------------------------------------------------*/
herror_t
-hsocket_send(hsocket_t sock, const char *str)
+hsocket_send(hsocket_t *sock, const char *str)
{
return hsocket_nsend(sock, str, strlen(str));
}
-/*
- return: -1 is error. read bytes otherwise
-*/
herror_t
-hsocket_read(hsocket_t sock, byte_t * buffer, int total, int force,
- int *received)
+hsocket_read(hsocket_t *sock, byte_t * buffer, int total, int force, int *received)
{
- int status;
- int totalRead;
-#ifdef WIN32
- int wsa_error = 0;
-#endif
+ herror_t status;
+ size_t totalRead;
+ size_t count;
+
+// log_verbose3("Entering hsocket_read(total=%d,force=%d)", total, force);
+
totalRead = 0;
-/*
- log_verbose3("Entering hsocket_read(total=%d,force=%d)", total, force);
-*/
do
{
-#ifdef HAVE_SSL
- if (sock.ssl)
- {
- struct timeval timeout;
- /*int i = 0;*/
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(sock.sock, &fds);
- timeout.tv_sec = 10;
- timeout.tv_usec = 0;
-#ifndef WIN32
- fcntl(sock.sock, F_SETFL, O_NONBLOCK);
-#endif
- status = SSL_read(sock.ssl, &buffer[totalRead], total - totalRead);
-
- if(ssl_checkFatal( sock.ssl, status )){
- log_verbose1("SSL Error");
- return herror_new("hsocket_read", HSOCKET_ERROR_SSLCLOSE, "SSL Error");
- }
- if (SSL_get_shutdown(sock.ssl) == SSL_RECEIVED_SHUTDOWN) {
- log_verbose1("SSL shutdown error");
- return herror_new("hsocket_read", HSOCKET_ERROR_SSLCLOSE, "SSL shutdown error");
- }
-
- if (status < 1)
- {
- int ret = select(sock.sock + 1, &fds, NULL, NULL, &timeout);
-#ifdef WIN32
- if (ret == SOCKET_ERROR)
- {
- wsa_error = WSAGetLastError();
- log_error2("WSAGetLastError()=%d", wsa_error);
- return herror_new("hsocket_read", HSOCKET_ERROR_RECEIVE,
- "Socket error: %d", errno);
-
- }
-#endif
- if (ret == 0)
- {
- log_verbose1("Socket timeout");
- return herror_new("hsocket_read", HSOCKET_ERROR_SSLCLOSE, "Timeout");
- }
- else
- {
- status = SSL_read(sock.ssl, &buffer[totalRead], total - totalRead);
- if(ssl_checkFatal( sock.ssl, status )){
- log_verbose1("SSL Error");
- return herror_new("hsocket_read", HSOCKET_ERROR_SSLCLOSE, "SSL Error");
- }
- }
- }
-#ifndef WIN32
- fcntl(sock.sock, F_SETFL, 0);
-#endif
- }
- else
- {
-#else /* HAVE_SSL */
- {
-#endif /* HAVE_SSL */
- status = recv(sock.sock, &buffer[totalRead], total - totalRead, 0);
-#ifdef WIN32
- if (status == INVALID_SOCKET)
- {
- wsa_error = WSAGetLastError();
- switch (wsa_error)
- {
- case WSAEWOULDBLOCK:
- /* case WSAEALREADY: case WSAEINPROGRESS: */
- continue;
- default:
- log_error2("WSAGetLastError()=%d", wsa_error);
- return herror_new("hsocket_read", HSOCKET_ERROR_RECEIVE,
- "Socket error: %d", errno);
- }
- }
- }
-#else
+ if ((status = hssl_read(sock, &buffer[totalRead], (size_t)total - totalRead, &count)) != H_OK)
+ {
+ log_warn("hssl_read failed (%s)", herror_message(status));
+ return status;
}
- if (status == -1)
- return herror_new("hsocket_read", HSOCKET_ERROR_RECEIVE,
- "Socket error: %d", errno);
-#endif
-
if (!force)
{
- *received = status;
- /*
- log_verbose3("Leaving !force (received=%d)(status=%d)", *received,
- status); */
+ /* log_verbose3("Leaving !force (received=%d)(status=%d)", *received, status);
+ */
+ *received = count;
return H_OK;
}
- totalRead += status;
+ totalRead += count;
if (totalRead == total)
{
@@ -595,34 +464,32 @@ hsocket_read(hsocket_t sock, byte_t * buffer, int total, int force,
}
-herror_t
-hsocket_block(hsocket_t sock, int block)
-{
-#ifdef WIN32
- unsigned long iMode;
-#endif
-
- if (sock.sock <= 0)
- return herror_new("hsocket_block", HSOCKET_ERROR_NOT_INITIALIZED,
- "Called hsocket_listen() before initializing!");
-
-#ifdef WIN32
-/*#define HSOCKET_BLOCKMODE 0
-#define HSOCKET_NONBLOCKMODE 1
-*/
-
- iMode = (block == 0) ? 1 : 0; /* Non block mode */
- if (ioctlsocket(sock.sock, FIONBIO, (u_long FAR *) & iMode) ==
- INVALID_SOCKET)
- {
- int err = WSAGetLastError();
- log_error2("ioctlsocket error %d", err);
- return herror_new("hsocket_block", HSOCKET_ERROR_IOCTL,
- "Socket error: %d", err);
- }
-#else /* fcntl(sock, F_SETFL, O_NONBLOCK); */
-/* TODO (#1#): check for *nix the non blocking sockets */
-
-#endif
- return H_OK;
-}
+// #ifdef WIN32
+// herror_t
+// hsocket_block(hsocket_t *sock, int block)
+// {
+// unsigned long iMode;
+//
+// if (sock->sock < 0)
+// return herror_new("hsocket_block", HSOCKET_ERROR_NOT_INITIALIZED,
+// "Called hsocket_listen() before initializing!");
+//
+// iMode = (block == 0) ? 1 : 0; /* Non block mode */
+// if (ioctlsocket(sock.sock, FIONBIO, (u_long FAR *) & iMode) ==
+// INVALID_SOCKET)
+// {
+// int err = WSAGetLastError();
+// log_error2("ioctlsocket error %d", err);
+// return herror_new("hsocket_block", HSOCKET_ERROR_IOCTL,
+// "Socket error %d", err);
+// }
+//
+// return H_OK;
+// }
+// #else
+// herror_t
+// hsocket_block(hsocket_t *sock, int block)
+// {
+// return H_OK;
+// }
+// #endif
diff --git a/nanohttp/nanohttp-socket.h b/nanohttp/nanohttp-socket.h
index 63d55dd..bbe5692 100644
--- a/nanohttp/nanohttp-socket.h
+++ b/nanohttp/nanohttp-socket.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: nanohttp-socket.h,v 1.24 2006/02/27 22:26:02 snowdrop Exp $
+ * $Id: nanohttp-socket.h,v 1.25 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -24,9 +24,11 @@
#ifndef NANO_HTTP_SOCKET_H
#define NANO_HTTP_SOCKET_H
-#include <time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
-#include <nanohttp/nanohttp-common.h>
+#include <time.h>
#ifdef HAVE_SSL
#include <openssl/ssl.h>
@@ -36,6 +38,8 @@
#include <winsock2.h>
#endif
+#include <nanohttp/nanohttp-common.h>
+
#define HSOCKET_FREE -1
/*
@@ -43,44 +47,33 @@
*/
typedef struct hsocket_t
{
-
-#ifdef HAVE_SSL
- SSL *ssl;
- SSL_CTX *sslCtx;
-#endif
-
#ifdef WIN32
SOCKET sock;
#else
- volatile int sock;
+ int sock;
#endif
- int block;
-
+ struct sockaddr_in addr;
+ void *ssl;
} hsocket_t; /* end of socket definition */
-#ifdef WIN32
-typedef int socklen_t;
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
-
/**
Initializes the socket modul. This should be called only
once for an application.
@returns This function should always return H_OK.
*/
-herror_t hsocket_module_init();
+herror_t hsocket_module_init(int argc, char **argv);
/**
Destroys the socket modul. This should be called after
finishing an application.
*/
-void hsocket_module_destroy();
+void hsocket_module_destroy(void);
/**
@@ -93,34 +86,14 @@ void hsocket_module_destroy();
@see hsocket_init_ssl
@returns This function should always return H_OK.
*/
-herror_t hsocket_init(hsocket_t * sock);
-
-
-/**
- Initializes a given socket object with ssl context.
- To initialize the socket without ssl, you should use
- hsocket_init()
-
- @param sock the destination socket to initialize.
- @param sslCert keyfile
- @param sslPass passwort
- @param sslCA calist
-
- @see hsocket_init
- @returns HSOCKET_ERROR_SSLCTX if failed. H_OK otherwise
- */
-herror_t
-hsocket_init_ssl(hsocket_t * sock,
- const char* sslCert,
- const char* sslPass,
- const char* sslCA);
+herror_t hsocket_init(hsocket_t *sock);
/**
Destroys and releases a given socket.
@param sock the socket to destroy
*/
-void hsocket_free(hsocket_t sock);
+void hsocket_free(hsocket_t *sock);
/**
@@ -130,13 +103,14 @@ void hsocket_free(hsocket_t sock);
@param sock the destonation socket object to use
@param host hostname
@param port port number to connect to
+ @param ssl whether to open a SSL connection
@returns H_OK if success. One of the followings if fails:<P>
<BR>HSOCKET_ERROR_CREATE
<BR>HSOCKET_ERROR_GET_HOSTNAME
<BR>HSOCKET_ERROR_CONNECT
*/
-herror_t hsocket_open(hsocket_t * sock, const char *host, int port);
+herror_t hsocket_open(hsocket_t *sock, const char *host, int port, int ssl);
/**
@@ -160,7 +134,7 @@ void hsocket_close(hsocket_t *sock);
@see hsocket_listen
*/
-herror_t hsocket_bind(hsocket_t * sock, int port);
+herror_t hsocket_bind(hsocket_t *sock, int port);
/**
@@ -174,7 +148,7 @@ herror_t hsocket_bind(hsocket_t * sock, int port);
<BR>HSOCKET_ERROR_NOT_INITIALIZED
<BR>HSOCKET_ERROR_LISTEN
*/
-herror_t hsocket_listen(hsocket_t sock);
+herror_t hsocket_listen(hsocket_t *sock);
/**
@@ -188,7 +162,7 @@ herror_t hsocket_listen(hsocket_t sock);
<BR>HSOCKET_ERROR_NOT_INITIALIZED
<BR>HSOCKET_ERROR_ACCEPT
*/
-herror_t hsocket_accept(hsocket_t sock, hsocket_t * dest);
+herror_t hsocket_accept(hsocket_t *sock, hsocket_t * dest);
/**
@@ -202,7 +176,7 @@ herror_t hsocket_accept(hsocket_t sock, hsocket_t * dest);
<BR>HSOCKET_ERROR_NOT_INITIALIZED
<BR>HSOCKET_ERROR_SEND
*/
-herror_t hsocket_nsend(hsocket_t sock, const byte_t * bytes, int size);
+herror_t hsocket_nsend(hsocket_t *sock, const byte_t * bytes, int size);
/**
@@ -215,7 +189,7 @@ herror_t hsocket_nsend(hsocket_t sock, const byte_t * bytes, int size);
<BR>HSOCKET_ERROR_NOT_INITIALIZED
<BR>HSOCKET_ERROR_SEND
*/
-herror_t hsocket_send(hsocket_t sock, const char *str);
+herror_t hsocket_send(hsocket_t *sock, const char *str);
/**
@@ -234,7 +208,7 @@ herror_t hsocket_send(hsocket_t sock, const char *str);
the socket.
*/
-herror_t hsocket_read(hsocket_t sock, byte_t * buffer, int size, int force,
+herror_t hsocket_read(hsocket_t *sock, byte_t * buffer, int size, int force,
int *readed);
/**
@@ -246,7 +220,7 @@ herror_t hsocket_read(hsocket_t sock, byte_t * buffer, int size, int force,
<BR>HSOCKET_ERROR_NOT_INITIALIZED
<BR>HSOCKET_ERROR_IOCTL
*/
-herror_t hsocket_block(hsocket_t sock, int block);
+// herror_t hsocket_block(hsocket_t *sock, int block);
#ifdef __cplusplus
}
diff --git a/nanohttp/nanohttp-ssl.c b/nanohttp/nanohttp-ssl.c
index 63bf0f7..a365e64 100644
--- a/nanohttp/nanohttp-ssl.c
+++ b/nanohttp/nanohttp-ssl.c
@@ -1,4 +1,7 @@
-/*
+/*************************************************************************
+ * $Id: nanohttp-ssl.c,v 1.18 2006/03/06 13:37:38 m0gg Exp $
+ *
+ * CSOAP Project: A http client/server library in C
* Copyright (C) 2001-2005 Rochester Institute of Technology
*
* This program is free software; you can redistribute it and/or modify
@@ -21,9 +24,6 @@
* Descrip: SSL connection routines
*/
-/* Enter only if --with-ssl was specified to the configure script */
-#ifdef HAVE_SSL
-
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -36,16 +36,6 @@
#include <netinet/in.h>
#endif
-#if HAVE_INTTYPES_H
-#include <inttypes.h>
-#else
-# if HAVE_STDINT_H
-# include <stdint.h>
-# else
-typedef unsigned int uint32_t;
-# endif
-#endif
-
#ifdef HAVE_STRING_H
#include <string.h>
#endif
@@ -54,6 +44,10 @@ typedef unsigned int uint32_t;
#include <stdlib.h>
#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
#ifdef HAVE_TIME_H
#include <time.h>
#endif
@@ -66,12 +60,11 @@ typedef unsigned int uint32_t;
#include <unistd.h>
#endif
-#ifdef WIN32
+#ifdef HAVE_IO_H
#include <io.h>
-typedef unsigned int uint32_t;
-#else
#endif
+#ifdef HAVE_SSL
#ifdef HAVE_OPENSSL_RAND_H
#include <openssl/rand.h>
#endif
@@ -79,24 +72,25 @@ typedef unsigned int uint32_t;
#ifdef HAVE_OPENSSL_ERR_H
#include <openssl/err.h>
#endif
+#endif
#include "nanohttp-common.h"
#include "nanohttp-socket.h"
#include "nanohttp-ssl.h"
-#define MAXCHUNK 1024
-#define HEADER_LEN 5
-char HEADER[HEADER_LEN] = { 186, 84, 202, 86, 224 };
-static char *pass;
+#ifdef HAVE_SSL
-/*
- * superseed
- * Creates a 1k random seed and uses it to seed
- * the SSL random number generator
- */
+static char *certificate = NULL;
+static char *certpass = NULL;
+static char *ca_list = NULL;
+static SSL_CTX *context = NULL;
-void
-superseed ()
+static int enabled = 0;
+static int initialized = 0;
+
+
+static void
+_hssl_superseed (void)
{
int buf[256], i;
@@ -107,18 +101,47 @@ superseed ()
buf[i] = rand ();
}
RAND_seed ((unsigned char *) buf, sizeof (buf));
+
+ return;
}
+
+static char *
+_hssl_get_error(SSL *ssl, int ret)
+{
+ switch(SSL_get_error(ssl, ret))
+ {
+ case SSL_ERROR_NONE:
+ return "None";
+ case SSL_ERROR_ZERO_RETURN:
+ return "Zero return";
+ case SSL_ERROR_WANT_READ:
+ return "Want read";
+ case SSL_ERROR_WANT_WRITE:
+ return "Want write";
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ return "Want x509 lookup";
+ case SSL_ERROR_SYSCALL:
+ return "Syscall failed";
+ case SSL_ERROR_SSL:
+ return "SSL error";
+ default:
+ return "Unkown";
+ }
+}
+
+
static int
pw_cb (char *buf, int num, int rwflag, void *userdata)
{
- if (num < (int) strlen (pass) + 1)
+ if (num < (int) strlen (certpass) + 1)
return (0);
- strcpy (buf, pass);
- return strlen (pass);
+ strcpy(buf, certpass);
+ return strlen(certpass);
}
+
int
verify_sn (X509 * cert, int who, int nid, char *str)
{
@@ -152,6 +175,7 @@ verify_sn (X509 * cert, int who, int nid, char *str)
}
}
+
#ifdef NOUSER_VERIFY
static int
user_verify (X509 * cert)
@@ -190,262 +214,331 @@ verify_cb (int prev_ok, X509_STORE_CTX * ctx)
#endif
}
-void
-start_ssl( void )
+
+static void
+_hssl_parse_arguments(int argc, char **argv)
+{
+
+ int i;
+
+ for (i=1; i<argc; i++)
+ {
+ if (!strcmp(argv[i-1], NHTTP_ARG_CERT))
+ {
+ certificate = argv[i];
+ }
+ else if (!strcmp(argv[i-1], NHTTP_ARG_CERTPASS))
+ {
+ certpass = argv[i];
+ }
+ else if (!strcmp(argv[i-1], NHTTP_ARG_CA))
+ {
+ ca_list = argv[i];
+ }
+ else if (!strcmp(argv[i-1], NHTTP_ARG_HTTPS))
+ {
+ enabled = 1;
+ }
+ }
+
+ return;
+}
+
+
+static void
+_hssl_library_init(void)
{
/* Global system initialization */
log_verbose1 ("Initializing library");
- SSL_library_init ();
- SSL_load_error_strings ();
- ERR_load_crypto_strings ();
- OpenSSL_add_ssl_algorithms ();
+
+ SSL_library_init();
+
+ SSL_load_error_strings();
+ ERR_load_crypto_strings();
+
+ OpenSSL_add_ssl_algorithms();
+
+ initialized = 1;
return;
}
-SSL_CTX *
-initialize_ctx (const char *keyfile, const char *password, const char *calist)
+
+static herror_t
+hssl_context_init(void)
{
- SSL_CTX *ctx = NULL;
+ log_verbose3("enabled=%i, certificate=%p", enabled, certificate);
+
+ if (!enabled || !certificate)
+ return H_OK;
- if (password == NULL)
- password = "";
+ if (certpass == NULL)
+ certpass = "";
/* Create our context */
- ctx = SSL_CTX_new (SSLv23_method ());
-
- if (ctx == NULL)
+ if (!(context = SSL_CTX_new(SSLv23_method())))
{
log_error1 ("Cannot create SSL context");
- return NULL;
+ return herror_new("hssl_context_init", HSSL_ERROR_CONTEXT, "Unable to create SSL context");
}
- log_verbose1 ("SSL context created ok");
- /* Load our keys and certificates */
- if (keyfile != NULL && password != NULL)
+ if (!(SSL_CTX_use_certificate_file (context, certificate, SSL_FILETYPE_PEM)))
{
+ SSL_CTX_free(context);
+ log_error2 ("Cannot read certificate file: \"%s\"", certificate);
+ return herror_new("hssl_context_init", HSSL_ERROR_CERTIFICATE, "Unable to use SSL certificate \"%s\"", certificate);
+ }
- if (!(SSL_CTX_use_certificate_file (ctx, keyfile, SSL_FILETYPE_PEM)))
- {
- log_error2 ("Couldn't read certificate file: %s", keyfile);
- SSL_CTX_free (ctx);
- return ctx = NULL;
- }
-
- log_verbose1 ("Certificate file read ok");
+ SSL_CTX_set_default_passwd_cb(context, pw_cb);
- pass = strdup(password);
- SSL_CTX_set_default_passwd_cb (ctx, pw_cb);
+ if (!(SSL_CTX_use_PrivateKey_file(context, certificate, SSL_FILETYPE_PEM)))
+ {
+ SSL_CTX_free(context);
+ log_error2 ("Cannot read key file: \"%s\"", certificate);
+ return herror_new("hssl_context_init", HSSL_ERROR_PEM, "Unable to use private key");
+ }
- if (!(SSL_CTX_use_PrivateKey_file (ctx, keyfile, SSL_FILETYPE_PEM)))
+ if (ca_list != NULL && *ca_list != '\0')
+ {
+ if (!(SSL_CTX_load_verify_locations(context, ca_list, NULL)))
{
- log_error2 ("Couldn't read key file: %s", keyfile);
- SSL_CTX_free (ctx);
- return ctx = NULL;
+ SSL_CTX_free(context);
+ log_error2 ("Cannot read CA list: \"%s\"", ca_list);
+ return herror_new("hssl_context_init", HSSL_ERROR_CA_LIST, "Unable to read certification authorities \"%s\"");
}
- log_verbose1 ("Keyfile read ok");
+ SSL_CTX_set_client_CA_list (context, SSL_load_client_CA_file (ca_list));
+ log_verbose1 ("Certification authority contacted");
}
- if (calist != NULL && *calist != '\0')
- {
+ SSL_CTX_set_verify(context, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_cb);
- /* Load the CAs we trust */
- if (!(SSL_CTX_load_verify_locations (ctx, calist, NULL)))
- {
- log_error2 ("Couldn't read CA list: %s", calist);
- SSL_CTX_free (ctx);
- return ctx = NULL;
- }
+ log_verbose1("Verify callback registered");
+
+ SSL_CTX_set_mode(context, SSL_MODE_AUTO_RETRY);
+
+ SSL_CTX_set_session_cache_mode(context, SSL_SESS_CACHE_OFF);
+
+ _hssl_superseed();
+
+ return H_OK;
+}
- SSL_CTX_set_client_CA_list (ctx, SSL_load_client_CA_file (calist));
- log_verbose1 ("Certificate Authority contacted");
+static void
+_hssl_context_destroy(void)
+{
+ if (context)
+ {
+ SSL_CTX_free(context);
+ context = NULL;
}
- SSL_CTX_set_verify (ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE,
- verify_cb);
- log_verbose1 ("Verify callback registered");
+ return;
+}
- SSL_CTX_set_session_cache_mode (ctx, SSL_SESS_CACHE_OFF);
+herror_t
+hssl_module_init(int argc, char **argv)
+{
+ _hssl_parse_arguments(argc, argv);
- /* Load randomness */
- superseed ();
+ if (!initialized)
+ {
+ if (enabled)
+ {
+ _hssl_library_init();
+ log_verbose1("SSL enabled");
+ }
+ else
+ {
+ log_verbose1("SSL _not_ enabled");
+ }
+ }
- return ctx;
+ return hssl_context_init();
}
+
void
-log_ssl_error (SSL * ssl, int ret)
+hssl_module_destroy(void)
{
- int errqueue;
- char errorbuf[256] = "Error: ";
+ _hssl_context_destroy();
- if (ret == 0)
+ return;
+}
+
+
+herror_t
+hssl_client_ssl(hsocket_t *sock)
+{
+ SSL *ssl;
+ int ret;
+
+ log_verbose1 ("Starting SSL client initialization");
+
+ if (!(ssl = SSL_new(context)))
{
- log_error1 ("SSL handshake was not successful, contolled shutdown");
+ log_error1("Cannot create new SSL object");
+ return herror_new("hssl_client_ssl", HSSL_ERROR_CLIENT, "SSL_new failed");
}
- else if (ret == -1)
+
+ SSL_set_fd (ssl, sock->sock);
+
+ if ((ret = SSL_connect(ssl)) <= 0)
{
- log_error1 ("SSL handshake was not successful, fatal error at protocol");
- }
+ herror_t err;
- errqueue = SSL_get_error (ssl, ret);
+ log_error2 ("SSL connect error (%s)", _hssl_get_error(ssl, -1));
+ err = herror_new("hssl_client_ssl", HSSL_ERROR_CONNECT, "SSL_connect failed (%s)", _hssl_get_error(ssl, ret));
+ SSL_free (ssl);
+ return err;
+ }
- switch (errqueue)
+ /* SSL_connect should take care of this for us.
+ if (SSL_get_peer_certificate(ssl) == NULL)
{
- case SSL_ERROR_NONE:
- strcat (errorbuf, "None");
- break;
- case SSL_ERROR_ZERO_RETURN:
- strcat (errorbuf, "Zero return");
- break;
- case SSL_ERROR_WANT_READ:
- strcat (errorbuf, "Want read");
- break;
- case SSL_ERROR_WANT_WRITE:
- strcat (errorbuf, "Want write");
- break;
- case SSL_ERROR_WANT_X509_LOOKUP:
- strcat (errorbuf, "Want x509 lookup");
- break;
- case SSL_ERROR_SYSCALL:
- strcat (errorbuf, "Syscall:");
- if (ret == 0)
- {
- strcat (errorbuf, "Protocol violation");
- }
- else if (ret == -1)
- {
- strcat (errorbuf, "BIO reported an I/O error");
- }
- else
- {
- strcat (errorbuf, "Unknown syscall error");
- } /* if */
+ log_error1("No certificate provided");
+ SSL_free(ssl);
+ return herror_new("hssl_client_ssl", HSSL_ERROR_CERTIFICATE, "No certificate provided");
+ }
- break;
- case SSL_ERROR_SSL:
- strcat (errorbuf, "SSL library");
- while ((errqueue = ERR_get_error()))
- {
- log_error2 ("SSL %s", ERR_error_string (errqueue, NULL));
- }
- break;
- } /* switch code */
+ if (SSL_get_verify_result(ssl) != X509_V_OK)
+ {
+ log_error1("Certificate did not verify");
+ SSL_free(ssl);
+ return herror_new("hssl_client_ssl", HSSL_ERROR_CERTIFICATE, "Verfiy certificate failed");
+ } */
- log_error1 (errorbuf);
+ log_verbose1 ("SSL client initialization completed");
+
+ /* XXX: why???
+ if ((status = hsocket_block(sock, sock->block)) != H_OK)
+ {
+ log_error2("Cannot make socket non-blocking (%s)", herror_message(status));
+ SSL_free(ssl);
+ return status;
+ } */
+
+ sock->ssl = ssl;
+
+ return H_OK;
}
-SSL *
-init_ssl (SSL_CTX * ctx, int sock, int type)
+
+herror_t
+hssl_server_ssl(hsocket_t *sock)
{
- int ret;
SSL *ssl;
-#if 0
-#ifdef WIN32
- BIO *rbio;
- BIO *wbio;
-#else
- BIO *sbio;
-#endif
-#endif
+ int ret;
- log_verbose1 ("Starting SSL Initialization");
+ if (!enabled)
+ return H_OK;
- ssl = SSL_new (ctx);
+ log_verbose2("Starting SSL initialization for socket %d", sock->sock);
- if (ssl == NULL)
+ if (!(ssl = SSL_new(context)))
{
- log_error1 ("Cannot create new ssl object");
- return NULL;
+ log_warn1("SSL_new failed");
+ return herror_new("hssl_server_ssl", HSSL_ERROR_SERVER, "Cannot create SSL object");
}
+ SSL_set_fd(ssl, sock->sock);
-#if 0
-#ifdef WIN32
- log_error1 ("Setting up BIO with socket");
- rbio = BIO_new_socket (sock, BIO_NOCLOSE);
- if (rbio == NULL)
+ if ((ret = SSL_accept(ssl)) <= 0)
{
- log_error1 ("BIO_new_socket failed");
- return NULL;
+ herror_t err;
+
+ log_error2 ("SSL_accept failed (%s)", _hssl_get_error(ssl, ret));
+
+ err = herror_new("hssl_server_ssl", HSSL_ERROR_SERVER, "SSL_accept failed (%s)", _hssl_get_error(ssl, ret));
+ SSL_free (ssl);
+
+ return err;
}
- SSL_set_bio (ssl, rbio, rbio);
-#else
- sbio = BIO_new_socket (sock, BIO_NOCLOSE);
+ sock->ssl = ssl;
- if (sbio == NULL)
+ return H_OK;
+}
+
+
+void
+hssl_cleanup(hsocket_t *sock)
+{
+
+ if (sock->ssl)
{
- log_error1 ("BIO_new_socket failed");
- return NULL;
+ SSL_shutdown (sock->ssl);
+ SSL_free (sock->ssl);
+ sock->ssl = NULL;
}
- SSL_set_bio (ssl, sbio, sbio);
-#endif
-#endif
- SSL_set_fd (ssl, sock);
- if (type == SSL_SERVER)
+ return;
+}
+
+
+herror_t hssl_read(hsocket_t *sock, char *buf, size_t len, size_t *received)
+{
+ int count;
+
+ log_verbose4("sock->sock=%d sock->ssl=%p, len=%li", sock->sock, sock->ssl, len);
+
+ if (sock->ssl)
{
- hsocket_t sock_t;
- sock_t.sock = sock;
- hsocket_block (sock_t, 1);
- ret = SSL_accept (ssl);
- hsocket_block (sock_t, 0);
- if (ret <= 0)
- {
- log_error1 ("SSL accept error");
- log_ssl_error (ssl, ret);
- SSL_free (ssl);
- return NULL;
- } /* if error */
+ if ((count = SSL_read(sock->ssl, buf, len)) == -1)
+ return herror_new("SSL_read", HSOCKET_ERROR_RECEIVE, "SSL_read failed (%s)", _hssl_get_error(sock->ssl, count));
}
else
- { /* client */
- ret = SSL_connect (ssl);
- if (ret <= 0)
- {
- log_error1 ("SSL connect error");
- log_ssl_error (ssl, ret);
- SSL_free (ssl);
- return NULL;
- } /* if error */
- /* SSL_connect should take care of this for us.
- if(SSL_get_peer_certificate(ssl) == NULL) { log_error1( "No
- certificate provided"); SSL_free(ssl); return ssl = NULL; }
- if(SSL_get_verify_result(ssl) != X509_V_OK) { log_error1( "Certificate
- did not verify"); SSL_free(ssl); return ssl = NULL; } */
+ {
+ if ((count = recv(sock->sock, buf, len, 0)) == -1)
+ return herror_new("hssl_read", HSOCKET_ERROR_RECEIVE, "recv failed (%s)", strerror(errno));
}
+ *received = count;
- log_verbose1 ("Completed SSL Initialization");
- return ssl;
+ return H_OK;
}
-void
-ssl_cleanup (SSL * ssl)
+
+herror_t hssl_write(hsocket_t *sock, const char *buf, size_t len, size_t *sent)
{
- /* does nothing to context */
+ int count;
- if (ssl != NULL)
- {
+ log_verbose4("sock->sock=%d, sock->ssl=%p, len=%li", sock->sock, sock->ssl, len);
- SSL_shutdown (ssl);
-// SSL_clear(ssl);
- SSL_free (ssl);
- ssl = NULL;
+ if (sock->ssl)
+ {
+ if ((count = SSL_write(sock->ssl, buf, len)) == -1)
+ return herror_new("SSL_write", HSOCKET_ERROR_SEND, "SSL_write failed (%s)", _hssl_get_error(sock->ssl, count));
+ }
+ else
+ {
+ if ((count = send(sock->sock, buf, len, 0)) == -1)
+ return herror_new("hssl_write", HSOCKET_ERROR_SEND, "send failed (%s)", strerror(errno));
}
+ *sent = count;
+
+ return H_OK;
}
-int
-ssl_checkFatal( SSL *ssl, int status ){
- switch (SSL_get_error(ssl, status)) {
- case SSL_ERROR_ZERO_RETURN:
- case SSL_ERROR_SSL:
- case SSL_ERROR_SYSCALL:
- return 1;
- break;
- default:
- return 0;
- }
+#else
+
+herror_t hssl_read(hsocket_t *sock, char *buf, size_t len, size_t *received)
+{
+ int count;
+
+ if ((count = recv(sock->sock, buf, len, 0)) == -1)
+ return herror_new("hssl_read", HSOCKET_ERROR_RECEIVE, "recv failed (%s)", strerror(errno));
+ *received = count;
+ return H_OK;
+}
+
+
+herror_t hssl_write(hsocket_t *sock, const char *buf, size_t len, size_t *sent)
+{
+ int count;
+
+ if ((count = send(sock->sock, buf, len, 0)) == -1)
+ return herror_new("hssl_write", HSOCKET_ERROR_SEND, "send failed (%s)", strerror(errno));
+ *sent = count;
+ return H_OK;
}
-#endif /* end of ifdef HAVE_SSL */
+#endif
diff --git a/nanohttp/nanohttp-ssl.h b/nanohttp/nanohttp-ssl.h
index 1cdafb2..82a7db7 100644
--- a/nanohttp/nanohttp-ssl.h
+++ b/nanohttp/nanohttp-ssl.h
@@ -18,68 +18,53 @@
/*
* Author: Matt Campbell
- * Contrib:
- * Descrip: Common ssl routines
*/
-
-/* Do enter only if --with-ssl was specified by the configure script */
-#ifdef HAVE_SSL
-
-#ifdef TRU64
-#include <arpa/inet.h>
-typedef unsigned int uint32_t;
-#endif
-
#ifndef __NANOHTTP_SSL_H_
#define __NANOHTTP_SSL_H_
-#include <openssl/ssl.h>
-
-#ifdef WIN32
-typedef unsigned int uint32_t;
-#else
-#include <unistd.h>
+#ifdef HAVE_CONFIG_H
+#include <config.h>
#endif
-#define SSL_SERVER 0
-#define SSL_CLIENT 1
-
-#define CERT_SUBJECT 0
-#define CERT_ISSUER 1
-
-typedef struct Con
-{
- SSL *ssl;
- int sock;
-} Con;
+#ifdef HAVE_SSL
-/*
- * Callback for password checker
- */
+#ifdef HAVE_OPENSSL_SSL_H
+#include <openssl/ssl.h>
+#endif
#ifdef __cplusplus
extern "C" {
#endif
-//static int pw_cb(char* buf, int num, int rwflag, void *userdata);
+/**
+ *
+ * Initialization and shutdown of the SSL module
+ *
+ */
+herror_t hssl_module_init(int argc, char **argv);
+void hssl_module_destroy(void);
-/*
- * Start the ssl library
+/**
+ *
+ * Socket initialization and shutdown
+ *
*/
-void start_ssl( void );
+herror_t hssl_client_ssl(hsocket_t *sock);
+herror_t hssl_server_ssl(hsocket_t *sock);
+
+void hssl_cleanup(hsocket_t *sock);
+
/*
- * Initialize the context
+ * Callback for password checker
*/
-
-SSL_CTX *initialize_ctx(const char *keyfile,
- const char *password,
- const char *calist);
+//static int pw_cb(char* buf, int num, int rwflag, void *userdata);
/*
* Quick function for verifying a portion of the cert
* nid is any NID_ defined in <openssl/objects.h>
* returns non-zero if everything went ok
*/
+#define CERT_SUBJECT 1
int verify_sn(X509 * cert, int who, int nid, char *str);
@@ -95,33 +80,31 @@ int verify_sn(X509 * cert, int who, int nid, char *str);
int user_verify(X509 * cert);
-/*
- * Create the ssl socket and return it
- * pass in the context and an open socket
- */
+#ifdef __cplusplus
+}
+#endif
-SSL *init_ssl(SSL_CTX * ctx, int sock, int type);
+#else /* HAVE_SSL */
-/*
- * Close the ssl connection (socket is still left open)
- */
+static inline herror_t hssl_module_init(int argc, char **argv) { return H_OK; }
+static inline void hssl_module_destroy(void) { return; }
-void ssl_cleanup();
+static inline herror_t hssl_client_ssl(hsocket_t *sock) { return H_OK; }
+static inline herror_t hssl_server_ssl(hsocket_t *sock) { return H_OK; }
-/**
- Log funtion to report ssl failures
- @param ssl
- @param ret
- */
-void
-log_ssl_error (SSL * ssl, int ret);
+static inline void hssl_cleanup(hsocket_t *sock) { return; }
-int ssl_checkFatal( SSL *ssl, int status );
+#endif /* HAVE_SSL */
+#ifdef __cplusplus
+extern "C" {
#endif
+herror_t hssl_read(hsocket_t *sock, char *buf, size_t len, size_t *received);
+herror_t hssl_write(hsocket_t *sock, const char *buf, size_t len, size_t *sent);
+
#ifdef __cplusplus
}
#endif
-#endif /* HAVE_SSL */
+#endif
diff --git a/nanohttp/nanohttp-stream.c b/nanohttp/nanohttp-stream.c
index 0d8188a..ba36725 100755
--- a/nanohttp/nanohttp-stream.c
+++ b/nanohttp/nanohttp-stream.c
@@ -1,5 +1,5 @@
/******************************************************************
-* $Id: nanohttp-stream.c,v 1.11 2006/02/27 22:26:02 snowdrop Exp $
+* $Id: nanohttp-stream.c,v 1.12 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003-2004 Ferhat Ayaz
@@ -43,17 +43,6 @@
#include "nanohttp-stream.h"
-void
-_log_str(char *fn, char *str, int size)
-{
-/* FILE *f = fopen(fn, "ab");
- if (!f) f=fopen(fn,"wb");
- fwrite(str, size, 1, f);
- fflush(f);
- fclose(f);
-*/
-}
-
/*
-------------------------------------------------------------------
@@ -88,7 +77,7 @@ _http_stream_is_chunked(hpair_t * header)
Creates a new input stream.
*/
http_input_stream_t *
-http_input_stream_new(hsocket_t sock, hpair_t * header)
+http_input_stream_new(hsocket_t *sock, hpair_t * header)
{
http_input_stream_t *result;
char *content_length;
@@ -195,7 +184,6 @@ static int
_http_input_stream_is_chunked_ready(http_input_stream_t * stream)
{
return stream->chunk_size != 0;
-
}
static int
@@ -312,9 +300,7 @@ _http_input_stream_chunked_read(http_input_stream_t * stream, byte_t * dest,
counter = 100; /* maximum for stop infinity */
while (1)
{
- err = hsocket_read(stream->sock, &ch, 1, 1, &status);
-
- if (err != H_OK)
+ if ((err = hsocket_read(stream->sock, &ch, 1, 1, &status)) != H_OK)
{
stream->err = err;
return -1;
@@ -356,8 +342,7 @@ _http_input_stream_chunked_read(http_input_stream_t * stream, byte_t * dest,
if (remain < size)
{
/* read from socket */
- err = hsocket_read(stream->sock, &(dest[read]), remain, 1, &status);
- if (err != H_OK)
+ if ((err = hsocket_read(stream->sock, &(dest[read]), remain, 1, &status)) != H_OK)
{
stream->err = err;
return -1;
@@ -407,8 +392,7 @@ _http_input_stream_connection_closed_read(http_input_stream_t * stream,
herror_t err;
/* read from socket */
- err = hsocket_read(stream->sock, dest, size, 0, &status);
- if (err != H_OK)
+ if ((err = hsocket_read(stream->sock, dest, size, 0, &status)) != H_OK)
{
stream->err = err;
return -1;
@@ -418,7 +402,6 @@ _http_input_stream_connection_closed_read(http_input_stream_t * stream,
stream->connection_closed = 1;
stream->received += status;
- _log_str("stream.in", dest, size);
return status;
}
@@ -481,7 +464,7 @@ http_input_stream_read(http_input_stream_t * stream, byte_t * dest, int size)
return -1;
}
- /* reset error flag */
+ /* XXX: possible memleak! reset error flag */
stream->err = H_OK;
switch (stream->type)
@@ -523,7 +506,7 @@ HTTP OUTPUT STREAM
Creates a new output stream. Transfer code will be found from header.
*/
http_output_stream_t *
-http_output_stream_new(hsocket_t sock, hpair_t * header)
+http_output_stream_new(hsocket_t *sock, hpair_t * header)
{
http_output_stream_t *result;
char *content_length;
@@ -599,7 +582,6 @@ http_output_stream_write(http_output_stream_t * stream,
if (size > 0)
{
- _log_str("stream.out", (char *) bytes, size);
if ((status = hsocket_nsend(stream->sock, bytes, size)) != H_OK)
return status;
}
diff --git a/nanohttp/nanohttp-stream.h b/nanohttp/nanohttp-stream.h
index ac78603..88e5f97 100755
--- a/nanohttp/nanohttp-stream.h
+++ b/nanohttp/nanohttp-stream.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: nanohttp-stream.h,v 1.9 2006/02/27 22:26:02 snowdrop Exp $
+ * $Id: nanohttp-stream.h,v 1.10 2006/03/06 13:37:38 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003-2004 Ferhat Ayaz
@@ -29,12 +29,6 @@
#include <nanohttp/nanohttp-socket.h>
#include <nanohttp/nanohttp-common.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void _log_str(char *fn, char *str, int size);
-
/*
HTTP Stream modul:
@@ -88,7 +82,7 @@ typedef enum http_transfer_type
*/
typedef struct http_input_stream
{
- hsocket_t sock;
+ hsocket_t *sock;
herror_t err;
http_transfer_type_t type;
int received;
@@ -109,13 +103,17 @@ typedef struct http_input_stream
*/
typedef struct http_output_stream
{
- hsocket_t sock;
+ hsocket_t *sock;
http_transfer_type_t type;
int content_length;
int sent;
} http_output_stream_t;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
--------------------------------------------------------------
HTTP INPUT STREAM
@@ -136,7 +134,7 @@ typedef struct http_output_stream
@see http_input_stream_free
*/
-http_input_stream_t *http_input_stream_new(hsocket_t sock, hpair_t * header);
+http_input_stream_t *http_input_stream_new(hsocket_t *sock, hpair_t *header);
/**
@@ -218,7 +216,7 @@ int http_input_stream_read(http_input_stream_t * stream,
@see http_output_stream_free
*/
-http_output_stream_t *http_output_stream_new(hsocket_t sock,
+http_output_stream_t *http_output_stream_new(hsocket_t *sock,
hpair_t * header);