summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar snowdrop2004-09-14 13:23:10 +0000
committerGravatar snowdrop2004-09-14 13:23:10 +0000
commit1a7fd033326ff93f68a80cce0bc30565251d22e0 (patch)
tree1972166386d32dbfd4865d7aeac041c6565158a7
parent15a7da227539217bc6f1e3f7651b59c9a73ae2aa (diff)
downloadcsoap-1a7fd033326ff93f68a80cce0bc30565251d22e0.tar.gz
csoap-1a7fd033326ff93f68a80cce0bc30565251d22e0.tar.bz2
optimizing code and extracting some long functions into little functions
-rw-r--r--nanohttp/nanohttp-common.h10
-rw-r--r--nanohttp/nanohttp-server.c157
-rw-r--r--nanohttp/nanohttp-socket.c1072
-rw-r--r--nanohttp/nanohttp-socket.h427
-rw-r--r--nanohttp/nanohttp-windows.h3
5 files changed, 844 insertions, 825 deletions
diff --git a/nanohttp/nanohttp-common.h b/nanohttp/nanohttp-common.h
index ea38866..ef70b0f 100644
--- a/nanohttp/nanohttp-common.h
+++ b/nanohttp/nanohttp-common.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: nanohttp-common.h,v 1.8 2004/08/30 07:55:41 snowdrop Exp $
+ * $Id: nanohttp-common.h,v 1.9 2004/09/14 13:23:10 snowdrop Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -38,6 +38,14 @@
#define SAVE_STR(str) ((str==0)?("(null)"):(str))
#endif
+/*
+Set Sleep function platform depended
+*/
+#ifdef WIN32
+ #define system_sleep(seconds) Sleep(seconds*1000);
+#else
+ #define system_sleep(seconds) sleep(seconds);
+#endif
/*
string function to compare strings ignoring case
diff --git a/nanohttp/nanohttp-server.c b/nanohttp/nanohttp-server.c
index 1a1c553..9e81a76 100644
--- a/nanohttp/nanohttp-server.c
+++ b/nanohttp/nanohttp-server.c
@@ -1,5 +1,5 @@
/******************************************************************
-* $Id: nanohttp-server.c,v 1.20 2004/09/13 15:33:32 rans Exp $
+* $Id: nanohttp-server.c,v 1.21 2004/09/14 13:23:10 snowdrop Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -410,18 +410,103 @@ httpd_session_main (void *data)
* -----------------------------------------------------
*/
#ifdef WIN32
-BOOL WINAPI httpd_term(DWORD sig) {
+BOOL WINAPI 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) {
-#endif
+ log_debug2("Got signal %d", sig);
if (sig == _httpd_terminate_signal)
_httpd_run = 0;
+}
+
+#endif
+
+/*
+ * -----------------------------------------------------
+ * FUNCTION: _httpd_register_signal_handler
+ * -----------------------------------------------------
+ */
+static
+void _httpd_register_signal_handler()
+{
+ log_verbose2 ("registering termination signal handler (SIGNAL:%d)",
+ _httpd_terminate_signal);
#ifdef WIN32
- return TRUE;
+ if (SetConsoleCtrlHandler((PHANDLER_ROUTINE)httpd_term, TRUE) == FALSE){
+ log_error1 ("Unable to install console event handler!");
+ }
+
+#else
+ signal (_httpd_terminate_signal, httpd_term);
#endif
-}
+}
+
+
+
+
+/*--------------------------------------------------
+FUNCTION: _httpd_wait_for_empty_conn
+----------------------------------------------------*/
+static
+conndata_t *_httpd_wait_for_empty_conn(int *term_flag)
+{
+ int i;
+ for (i = 0;; i++)
+ {
+ if (!*term_flag)
+ return NULL;
+
+ if (i >= _httpd_max_connections)
+ {
+ system_sleep(1);
+ i = 0;
+ }
+ else if (_httpd_connection[i].sock == 0)
+ {
+ break;
+ }
+ }
+
+ return &_httpd_connection[i];
+}
+
+/*
+ * -----------------------------------------------------
+ * FUNCTION: _httpd_start_thread
+ * -----------------------------------------------------
+ */
+static
+void _httpd_start_thread(conndata_t* conn)
+{
+ int err;
+
+#ifdef WIN32
+ conn->tid =
+ (HANDLE) _beginthreadex (NULL, 65535, httpd_session_main, conn, 0, &err);
+#else
+ pthread_attr_init (&(conn-> attr));
+ #ifdef PTHREAD_CREATE_DETACHED
+ pthread_attr_setdetachstate (&(conn->attr),
+ PTHREAD_CREATE_DETACHED);
+ #endif
+ err = pthread_create (&(conn->tid), &(conn->attr),httpd_session_main,
+ conn);
+ if (err)
+ {
+ log_error2 ("Error creating thread: ('%d')", err);
+ }
+#endif
+}
+
/*
* -----------------------------------------------------
@@ -433,13 +518,9 @@ int
httpd_run ()
{
int err;
- fd_set fds;
- struct timeval timeout;
-
+ conndata_t *conn;
log_verbose1 ("starting run routine");
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
/* listen to port */
err = hsocket_listen (_httpd_socket, 15);
@@ -448,60 +529,42 @@ httpd_run ()
log_error2 ("httpd_run(): '%d'", err);
return err;
}
- log_verbose2 ("registering termination signal handler (SIGNAL:%d)",
- _httpd_terminate_signal);
-#ifdef WIN32
- if (SetConsoleCtrlHandler((PHANDLER_ROUTINE)httpd_term, TRUE) == FALSE){
- log_error1 ("Unable to install console event handler!");
- }
-
-#else
- signal (_httpd_terminate_signal, httpd_term);
-#endif
log_verbose2 ("listening to port '%d'", _httpd_port);
-
+ /* register signal handler */
+ _httpd_register_signal_handler();
+
+ /* make the socket non blocking */
err = hsocket_makenonblock (_httpd_socket);
if (err != HSOCKET_OK)
{
log_error2 ("httpd_run(): '%d'", err);
return err;
}
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
+
while (_httpd_run)
{
-
- FD_ZERO (&fds);
- FD_SET (_httpd_socket, &fds);
-
-#ifndef WIN32
- select (1, &fds, NULL, NULL, &timeout);
-#else
- if (select (1, &fds, NULL, NULL, &timeout) == SOCKET_ERROR)
+ /* Get an empty connection struct */
+ conn = _httpd_wait_for_empty_conn(&_httpd_run);
+ if (conn == NULL) break;
+
+ /* Accept a socket */
+ err = hsocket_accept(_httpd_socket, &(conn->sock));
+ if (err != HSOCKET_OK)
{
- err = WSAGetLastError ();
- log_error1 ("select error");
- return -1;
- }
-#endif
-
- while (_httpd_run && (FD_ISSET (_httpd_socket, &fds)))
- if (!_httpd_run)
- break;
-
- if (hsocket_accept
- (_httpd_socket, httpd_session_main, _httpd_connection,
- _httpd_max_connections, &_httpd_run) != 0)
- {
- continue;
- }
+ log_error2("Can not accept socket: %d", err);
+ return -1; /* this is hard core! */
+ }
+
+ /* Now start a thread */
+ _httpd_start_thread(conn);
}
free (_httpd_connection);
return 0;
}
+
char *
httpd_get_postdata (httpd_conn_t * conn, hrequest_t * req, long *received,
long max)
diff --git a/nanohttp/nanohttp-socket.c b/nanohttp/nanohttp-socket.c
index 79a9568..d28456f 100644
--- a/nanohttp/nanohttp-socket.c
+++ b/nanohttp/nanohttp-socket.c
@@ -1,561 +1,513 @@
-/******************************************************************
-* $Id: nanohttp-socket.c,v 1.17 2004/09/13 15:33:32 rans Exp $
-*
-* CSOAP Project: A http client/server library in C
-* Copyright (C) 2003 Ferhat Ayaz
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Library General Public
-* License as published by the Free Software Foundation; either
-* version 2 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Library General Public License for more details.
-*
-* You should have received a copy of the GNU Library General Public
-* License along with this library; if not, write to the
-* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-* Boston, MA 02111-1307, USA.
-*
-* Email: ayaz@jprogrammer.net
-******************************************************************/
-#include <nanohttp/nanohttp-socket.h>
-#include <nanohttp/nanohttp-common.h>
-
-#ifdef WIN32
-#include "wsockcompat.h"
-#include <winsock2.h>
-#include <process.h>
-#define close(s) closesocket(s)
-typedef int ssize_t;
-#else
-#include <fcntl.h>
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-
-/*--------------------------------------------------
-FUNCTION: hsocket_module_init
-NOTE: This will be called from httpd_init()
- for server and from httpc_init() for client
-----------------------------------------------------*/
-int
-hsocket_module_init ()
-{
-#ifdef WIN32
- //WSACleanup();
- struct WSAData info;
- WSAStartup (MAKEWORD (2, 2), &info);
-
-#else /* */
- /* nothing to init for unix sockets */
-#endif /* */
- return 0;
-}
-
-/*--------------------------------------------------
-FUNCTION: hsocket_module_destroy
-----------------------------------------------------*/
-void
-hsocket_module_destroy ()
-{
-#ifdef WIN32
- WSACleanup ();
-
-#else /* */
- /* nothing to destroy for unix sockets */
-#endif /* */
-}
-
-
-/*--------------------------------------------------
-FUNCTION: hsocket_init
-----------------------------------------------------*/
-int
-hsocket_init (hsocket_t * sock)
-{
- /* just set the descriptor to -1 */
- *sock = -1;
- return 0;
-}
-
-
-/*--------------------------------------------------
-FUNCTION: hsocket_free
-----------------------------------------------------*/
-void
-hsocket_free (hsocket_t sock)
-{
- /* nothing to free for unix sockets */
-}
-
-
-/*--------------------------------------------------
-FUNCTION: hsocket_open
-----------------------------------------------------*/
-int
-hsocket_open (hsocket_t * dsock, const char *hostname, int port)
-{
- hsocket_t sock;
- char *ip;
- struct sockaddr_in address;
- struct hostent *host;
-
- sock = socket (AF_INET, SOCK_STREAM, 0);
- if (sock <= 0)
- return HSOCKET_CAN_NOT_CREATE;
-
- /* Get host data */
- host = gethostbyname (hostname);
- if (host == NULL)
- return HSOCKET_CAN_NOT_GET_HOSTNAME;
-
- ip = inet_ntoa (*(struct in_addr *) *host->h_addr_list);
- address.sin_addr.s_addr = inet_addr (ip);
-
- /* set server addresss */
- address.sin_family = host->h_addrtype;
- address.sin_port = htons (port);
- /* connect to the server */
- if (connect (sock, (struct sockaddr *) &address, sizeof (address)) != 0)
- return HSOCKET_CAN_NOT_CONNECT;
-
- *dsock = sock;
- return HSOCKET_OK;
-}
-
-
-/*--------------------------------------------------
-FUNCTION: hsocket_bind
-----------------------------------------------------*/
-int
-hsocket_bind (hsocket_t * dsock, int port)
-{
- hsocket_t sock;
- struct sockaddr_in addr;
-
- /* create socket */
- sock = socket (AF_INET, SOCK_STREAM, 0);
- if (sock == -1)
- {
- log_error2 ("Can not create socket: '%s'", strerror (errno));
- return HSOCKET_CAN_NOT_CREATE;
- }
- /* bind socket */
- addr.sin_family = AF_INET;
- addr.sin_port = htons (port); /* short, network byte order */
- addr.sin_addr.s_addr = INADDR_ANY;
- memset (&(addr.sin_zero), '\0', 8); /* zero the rest of the
- * struct */
-
- if (bind (sock, (struct sockaddr *) &addr, sizeof (struct sockaddr)) == -1)
- {
- log_error2 ("Can not bind: '%s'", strerror (errno));
- return HSOCKET_CAN_NOT_BIND;
- }
- *dsock = sock;
-#ifdef WIN32
- //setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *) true, sizeof(BOOL));
- //setsockopt(sock, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, (char *) true, sizeof(BOOL));
-#endif
- return HSOCKET_OK;
-}
-
-#ifdef WIN32
-int
-hsocket_accept (hsocket_t sock, unsigned (__stdcall * func) (void *),
- conndata_t * conns, int max_conn, int *termsig)
-#else
-int
-hsocket_accept (hsocket_t sock, void (*func) (void *), conndata_t * conns,
- int max_conn, int *termsig)
-#endif
-{
- int i;
- int err;
- socklen_t asize;
- struct sockaddr_in addr;
-
- asize = sizeof (struct sockaddr_in);
- while (1)
- {
- for (i = 0;; i++)
- {
- if (i >= max_conn)
- {
-#ifdef WIN32
- Sleep (1000);
-#else
- log_verbose2 ("max connection i=%d", i);
- sleep (1);
-#endif
- i = 0;
- continue;
- }
- if (conns[i].sock == 0)
- break;
- }
- conns[i].sock = accept (sock, (struct sockaddr *) &addr, &asize);
-#ifndef WIN32
- if (conns[i].sock == -1)
- {
- conns[i].sock = 0;
- if(*termsig==0)
- return 0;
- continue;
- }
-#else
- if (conns[i].sock == INVALID_SOCKET)
- {
- if (WSAGetLastError () != WSAEWOULDBLOCK)
- {
- log_error1 ("accept() died... restarting...");
- closesocket (sock);
- WSACleanup ();
- return INVALID_SOCKET;
- }
- else
- {
- conns[i].sock = 0;
- if(*termsig==0)
- return 0;
- Sleep(10);
- continue;
- }
- }
-#endif
- else
- {
- log_verbose3 ("accept new socket (%d) from '%s'", conns[i].sock,
- SAVE_STR (((char *) inet_ntoa (addr.sin_addr))));
-
-#ifdef WIN32
- conns[i].tid =
- (HANDLE) _beginthreadex (NULL, 65535, func, &conns[i], 0, &err);
-#else
- pthread_attr_init (&(conns[i].attr));
-#ifdef PTHREAD_CREATE_DETACHED
- pthread_attr_setdetachstate (&(conns[i].attr),
- PTHREAD_CREATE_DETACHED);
-#endif
-
- err =
- pthread_create (&(conns[i].tid), &(conns[i].attr), func,
- &conns[i]);
- if (err)
- {
- log_error2 ("Error creating thread: ('%d')", err);
- }
+/******************************************************************
+* $Id: nanohttp-socket.c,v 1.18 2004/09/14 13:23:10 snowdrop Exp $
+*
+* CSOAP Project: A http client/server library in C
+* Copyright (C) 2003 Ferhat Ayaz
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Library General Public
+* License as published by the Free Software Foundation; either
+* version 2 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Library General Public License for more details.
+*
+* You should have received a copy of the GNU Library General Public
+* License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*
+* Email: ayaz@jprogrammer.net
+******************************************************************/
+#include <nanohttp/nanohttp-socket.h>
+#include <nanohttp/nanohttp-common.h>
+
+
+
+
+#ifdef WIN32
+ #include "wsockcompat.h"
+ #include <winsock2.h>
+ #include <process.h>
+
+#ifndef __MINGW32__
+ typedef int ssize_t;
#endif
- }
- }
- return 0;
-}
-
-/*--------------------------------------------------
-FUNCTION: hsocket_listen
-----------------------------------------------------*/
-int
-hsocket_listen (hsocket_t sock, int n)
-{
- if (listen (sock, n) == -1)
- {
- log_error2 ("Can not listen: '%s'", strerror (errno));
- return HSOCKET_CAN_NOT_LISTEN;
- }
- return HSOCKET_OK;
-}
-
-/*--------------------------------------------------
-FUNCTION: hsocket_close
-----------------------------------------------------*/
-void
-hsocket_close (hsocket_t sock)
-{
- close (sock);
-}
-
-
-/*--------------------------------------------------
-FUNCTION: hsocket_send
-----------------------------------------------------*/
-int
-hsocket_nsend (hsocket_t sock, const char *buffer, int n)
-{
- int size;
-
- size = send ((int) sock, buffer, n, 0);
- if (size == -1)
- return HSOCKET_CAN_NOT_SEND;
-
- return HSOCKET_OK;
-}
-
-/*--------------------------------------------------
-FUNCTION: hsocket_send
-----------------------------------------------------*/
-int
-hsocket_send (hsocket_t sock, const char *buffer)
-{
- return hsocket_nsend(sock, buffer, strlen(buffer));
-}
-
-
-int
-hsocket_read (hsocket_t sock, char *buffer, int total, int force)
-{
- int status;
- int totalRead;
-
- totalRead = 0;
-
- do
- {
- status = recv (sock, &buffer[totalRead], total - totalRead, 0);
- if (!force)
- {
-#ifdef WIN32
- if (WSAGetLastError () != WSAEWOULDBLOCK)
- {
- return status;
- }
-#else
- return status;
-#endif
- }
- if (status > 0)
- {
- totalRead += status;
- }
- else
- {
-#ifdef WIN32
- if (WSAGetLastError () != WSAEWOULDBLOCK)
- {
- return status;
- }
-#else
- return status;
-#endif
- }
- if (totalRead >= total)
- return 0;
- }
- while (1);
-}
-
-/*--------------------------------------------------
-FUNCTION: hsocket_recv
-----------------------------------------------------*/
-int
-hsocket_recv (hsocket_t sock, char **buffer, int *totalSize)
-{
- ssize_t size;
- int chunk = 1;
- char tmp[HSOCKET_MAX_BUFSIZE + 1];
- int fsize;
- int bufSize;
-
- if (*totalSize > 0)
- {
- bufSize = *totalSize;
- }
- else
- {
- bufSize = HSOCKET_MAX_BUFSIZE;
- }
-
- *totalSize = 0;
-
- /* calculate first size for realloc */
- if (*buffer)
- {
- fsize = strlen (*buffer);
- }
- else
- {
- fsize = 0;
- }
-
- do
- {
-
- size = recv (sock, tmp, bufSize, 0);
- bufSize = HSOCKET_MAX_BUFSIZE;
-
- if (size == -1)
- {
- log_error1 ("Error reading from socket");
- return HSOCKET_CAN_NOT_RECEIVE;
- }
- if (size == 0)
- {
- break;
- }
- *totalSize += size;
- if (*buffer)
- {
- log_verbose2 ("reallocation %d bytes", *totalSize + fsize + 1);
- *buffer = (char *) realloc ((char *) *buffer,
- (*totalSize) + fsize +
- HSOCKET_MAX_BUFSIZE);
- strcat (*buffer, tmp);
- }
- else
- {
- *buffer = (char *) realloc (NULL, *totalSize + 1);
- strcpy (*buffer, tmp);
- }
-
- (*buffer)[*totalSize + fsize] = '\0';
- chunk++;
- }
- while (size > 0);
-
- return HSOCKET_OK;
-}
-
-
-
-/*--------------------------------------------------
-FUNCTION: hsocket_recv
-----------------------------------------------------*/
-int
-hsocket_recv_cb (hsocket_t sock, hsocket_recv_callback cb, void *userdata)
-{
- ssize_t size;
- char tmp[HSOCKET_MAX_BUFSIZE + 1];
-
- do
- {
-
- size = recv (sock, tmp, HSOCKET_MAX_BUFSIZE, 0);
-
- if (size == -1)
- {
- log_error1 ("Error reading from socket");
- return HSOCKET_CAN_NOT_RECEIVE;
- }
- if (size == 0)
- {
- break;
- }
- tmp[size] = '\0';
- if (!cb (sock, tmp, size, userdata))
- {
- break;
- }
- }
- while (size > 0);
-
- return HSOCKET_OK;
-}
-
-
-
-/*--------------------------------------------------
-FUNCTION: hbufsocket_read
-----------------------------------------------------*/
-int
-hbufsocket_read (hbufsocket_t * bufsock, char *buffer, int size)
-{
- int status;
- int tmpsize;
-
- if (bufsock->bufsize - bufsock->cur >= size)
- {
-
- log_verbose1 ("no need to read from socket");
- strncpy (buffer, &(bufsock->buffer[bufsock->cur]), size);
- bufsock->cur += size;
- return HSOCKET_OK;
-
- }
- else
- {
-
- tmpsize = bufsock->bufsize - bufsock->cur;
- log_verbose2 ("tmpsize = %d", tmpsize);
-
- if (tmpsize > 0)
- strncpy (buffer, &(bufsock->buffer[bufsock->cur]), tmpsize);
-
- size -= tmpsize;
-
- free (bufsock->buffer);
-
- status = hsocket_read (bufsock->sock, &buffer[tmpsize], size, 1);
- if (status == size)
- {
- bufsock->buffer = (char *) malloc (size + 1);
- strncpy (bufsock->buffer, &buffer[tmpsize], size);
- bufsock->cur = size;
- }
- else
- {
- return status;
- }
-
- return HSOCKET_OK;
- }
-}
-
-int
-hsocket_makenonblock (hsocket_t sock)
-{
-#ifdef WIN32
- unsigned long iMode;
- iMode = HSOCKET_NONBLOCKMODE;
- if (ioctlsocket (sock, FIONBIO, (u_long FAR *) & iMode) == INVALID_SOCKET)
- {
- log_error1 ("ioctlsocket error");
- return -1;
- }
-#else /* fcntl(sock, F_SETFL, O_NONBLOCK); */
-#endif
- return HSOCKET_OK;
-}
-
-#ifdef WIN32
-
-struct tm *
-localtime_r (const time_t * const timep, struct tm *p_tm)
-{
- static struct tm *tmp;
- tmp = localtime (timep);
- if (tmp)
- {
- memcpy (p_tm, tmp, sizeof (struct tm));
- tmp = p_tm;
- }
- return tmp;
-}
-
-#endif /* */
+
+#else
+ #include <fcntl.h>
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+
+/*--------------------------------------------------
+FUNCTION: hsocket_module_init
+NOTE: This will be called from httpd_init()
+ for server and from httpc_init() for client
+----------------------------------------------------*/
+int
+hsocket_module_init ()
+{
+#ifdef WIN32
+ struct WSAData info;
+ WSAStartup (MAKEWORD (2, 2), &info);
+
+#else /* */
+ /* nothing to init for unix sockets */
+#endif /* */
+ return 0;
+}
+
+/*--------------------------------------------------
+FUNCTION: hsocket_module_destroy
+----------------------------------------------------*/
+void
+hsocket_module_destroy ()
+{
+#ifdef WIN32
+ WSACleanup ();
+
+#else /* */
+ /* nothing to destroy for unix sockets */
+#endif /* */
+}
+
+
+/*--------------------------------------------------
+FUNCTION: hsocket_init
+----------------------------------------------------*/
+int
+hsocket_init (hsocket_t * sock)
+{
+ /* just set the descriptor to -1 */
+ *sock = -1;
+ return 0;
+}
+
+
+/*--------------------------------------------------
+FUNCTION: hsocket_free
+----------------------------------------------------*/
+void
+hsocket_free (hsocket_t sock)
+{
+ /* nothing to free for unix sockets */
+}
+
+
+/*--------------------------------------------------
+FUNCTION: hsocket_open
+----------------------------------------------------*/
+int
+hsocket_open (hsocket_t * dsock, const char *hostname, int port)
+{
+ hsocket_t sock;
+ char *ip;
+ struct sockaddr_in address;
+ struct hostent *host;
+
+ sock = socket (AF_INET, SOCK_STREAM, 0);
+ if (sock <= 0)
+ return HSOCKET_CAN_NOT_CREATE;
+
+ /* Get host data */
+ host = gethostbyname (hostname);
+ if (host == NULL)
+ return HSOCKET_CAN_NOT_GET_HOSTNAME;
+
+ ip = inet_ntoa (*(struct in_addr *) *host->h_addr_list);
+ address.sin_addr.s_addr = inet_addr (ip);
+
+ /* set server addresss */
+ address.sin_family = host->h_addrtype;
+ address.sin_port = htons (port);
+ /* connect to the server */
+ if (connect (sock, (struct sockaddr *) &address, sizeof (address)) != 0)
+ return HSOCKET_CAN_NOT_CONNECT;
+
+ *dsock = sock;
+ return HSOCKET_OK;
+}
+
+
+/*--------------------------------------------------
+FUNCTION: hsocket_bind
+----------------------------------------------------*/
+int
+hsocket_bind (hsocket_t * dsock, int port)
+{
+ hsocket_t sock;
+ struct sockaddr_in addr;
+
+ /* create socket */
+ sock = socket (AF_INET, SOCK_STREAM, 0);
+ if (sock == -1)
+ {
+ log_error2 ("Can not create socket: '%s'", strerror (errno));
+ return HSOCKET_CAN_NOT_CREATE;
+ }
+ /* bind socket */
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons (port); /* short, network byte order */
+ addr.sin_addr.s_addr = INADDR_ANY;
+ memset (&(addr.sin_zero), '\0', 8); /* zero the rest of the
+ * struct */
+
+ if (bind (sock, (struct sockaddr *) &addr, sizeof (struct sockaddr)) == -1)
+ {
+ log_error2 ("Can not bind: '%s'", strerror (errno));
+ return HSOCKET_CAN_NOT_BIND;
+ }
+ *dsock = sock;
+ return HSOCKET_OK;
+}
+
+
+/*----------------------------------------------------------
+FUNCTION: hsocket_accept
+----------------------------------------------------------*/
+int hsocket_accept(hsocket_t sock, hsocket_t *dest)
+{
+ socklen_t asize;
+ SOCKET sockfd;
+ struct sockaddr_in addr;
+
+ asize = sizeof(struct sockaddr_in);
+#ifdef WIN32
+ while(1)
+ {
+ sockfd = accept(sock, (struct sockaddr *)&addr, &asize);
+ if (sockfd == INVALID_SOCKET)
+ {
+ if(WSAGetLastError()!=WSAEWOULDBLOCK)
+ return HSOCKET_CAN_NOT_ACCEPT;
+ }
+ else
+ {
+ break;
+ }
+ }
+#else
+ sockfd = accept(sock, (struct sockaddr *)&addr, &asize);
+ if (sockfd == -1) {
+ return HSOCKET_CAN_NOT_ACCEPT;
+ }
+#endif
+ log_verbose3("accept new socket (%d) from '%s'", sockfd,
+ SAVE_STR(((char*)inet_ntoa(addr.sin_addr))) );
+
+ *dest = sockfd;
+ return HSOCKET_OK;
+}
+
+/*--------------------------------------------------
+FUNCTION: hsocket_listen
+----------------------------------------------------*/
+int
+hsocket_listen (hsocket_t sock, int n)
+{
+ if (listen (sock, n) == -1)
+ {
+ log_error2 ("Can not listen: '%s'", strerror (errno));
+ return HSOCKET_CAN_NOT_LISTEN;
+ }
+ return HSOCKET_OK;
+}
+
+/*--------------------------------------------------
+FUNCTION: hsocket_close
+----------------------------------------------------*/
+void
+hsocket_close (hsocket_t sock)
+{
+#ifdef WIN32
+ closesocket (sock);
+#else
+ close (sock);
+#endif
+}
+
+
+/*--------------------------------------------------
+FUNCTION: hsocket_send
+----------------------------------------------------*/
+int
+hsocket_nsend (hsocket_t sock, const char *buffer, int n)
+{
+ int size;
+
+ size = send ((int) sock, buffer, n, 0);
+ if (size == -1)
+ return HSOCKET_CAN_NOT_SEND;
+
+ return HSOCKET_OK;
+}
+
+/*--------------------------------------------------
+FUNCTION: hsocket_send
+----------------------------------------------------*/
+int
+hsocket_send (hsocket_t sock, const char *buffer)
+{
+ return hsocket_nsend(sock, buffer, strlen(buffer));
+}
+
+
+int
+hsocket_read (hsocket_t sock, char *buffer, int total, int force)
+{
+ int status;
+ int totalRead;
+
+ totalRead = 0;
+
+ do
+ {
+ status = recv (sock, &buffer[totalRead], total - totalRead, 0);
+ if (!force)
+ {
+#ifdef WIN32
+ if (WSAGetLastError () != WSAEWOULDBLOCK)
+ {
+ return status;
+ }
+#else
+ return status;
+#endif
+ }
+ if (status > 0)
+ {
+ totalRead += status;
+ }
+ else
+ {
+#ifdef WIN32
+ if (WSAGetLastError () != WSAEWOULDBLOCK)
+ {
+ return status;
+ }
+#else
+ return status;
+#endif
+ }
+ if (totalRead >= total)
+ return 0;
+ }
+ while (1);
+}
+
+/*--------------------------------------------------
+FUNCTION: hsocket_recv
+----------------------------------------------------*/
+int
+hsocket_recv (hsocket_t sock, char **buffer, int *totalSize)
+{
+ ssize_t size;
+ int chunk = 1;
+ char tmp[HSOCKET_MAX_BUFSIZE + 1];
+ int fsize;
+ int bufSize;
+
+ if (*totalSize > 0)
+ {
+ bufSize = *totalSize;
+ }
+ else
+ {
+ bufSize = HSOCKET_MAX_BUFSIZE;
+ }
+
+ *totalSize = 0;
+
+ /* calculate first size for realloc */
+ if (*buffer)
+ {
+ fsize = strlen (*buffer);
+ }
+ else
+ {
+ fsize = 0;
+ }
+
+ do
+ {
+
+ size = recv (sock, tmp, bufSize, 0);
+ bufSize = HSOCKET_MAX_BUFSIZE;
+
+ if (size == -1)
+ {
+ log_error1 ("Error reading from socket");
+ return HSOCKET_CAN_NOT_RECEIVE;
+ }
+ if (size == 0)
+ {
+ break;
+ }
+ *totalSize += size;
+ if (*buffer)
+ {
+ log_verbose2 ("reallocation %d bytes", *totalSize + fsize + 1);
+ *buffer = (char *) realloc ((char *) *buffer,
+ (*totalSize) + fsize +
+ HSOCKET_MAX_BUFSIZE);
+ strcat (*buffer, tmp);
+ }
+ else
+ {
+ *buffer = (char *) realloc (NULL, *totalSize + 1);
+ strcpy (*buffer, tmp);
+ }
+
+ (*buffer)[*totalSize + fsize] = '\0';
+ chunk++;
+ }
+ while (size > 0);
+
+ return HSOCKET_OK;
+}
+
+
+
+/*--------------------------------------------------
+FUNCTION: hsocket_recv
+----------------------------------------------------*/
+int
+hsocket_recv_cb (hsocket_t sock, hsocket_recv_callback cb, void *userdata)
+{
+ ssize_t size;
+ char tmp[HSOCKET_MAX_BUFSIZE + 1];
+
+ do
+ {
+
+ size = recv (sock, tmp, HSOCKET_MAX_BUFSIZE, 0);
+
+ if (size == -1)
+ {
+ log_error1 ("Error reading from socket");
+ return HSOCKET_CAN_NOT_RECEIVE;
+ }
+ if (size == 0)
+ {
+ break;
+ }
+ tmp[size] = '\0';
+ if (!cb (sock, tmp, size, userdata))
+ {
+ break;
+ }
+ }
+ while (size > 0);
+
+ return HSOCKET_OK;
+}
+
+
+
+/*--------------------------------------------------
+FUNCTION: hbufsocket_read
+----------------------------------------------------*/
+int
+hbufsocket_read (hbufsocket_t * bufsock, char *buffer, int size)
+{
+ int status;
+ int tmpsize;
+
+ if (bufsock->bufsize - bufsock->cur >= size)
+ {
+
+ log_verbose1 ("no need to read from socket");
+ strncpy (buffer, &(bufsock->buffer[bufsock->cur]), size);
+ bufsock->cur += size;
+ return HSOCKET_OK;
+
+ }
+ else
+ {
+
+ tmpsize = bufsock->bufsize - bufsock->cur;
+ log_verbose2 ("tmpsize = %d", tmpsize);
+
+ if (tmpsize > 0)
+ strncpy (buffer, &(bufsock->buffer[bufsock->cur]), tmpsize);
+
+ size -= tmpsize;
+
+ free (bufsock->buffer);
+
+ status = hsocket_read (bufsock->sock, &buffer[tmpsize], size, 1);
+ if (status == size)
+ {
+ bufsock->buffer = (char *) malloc (size + 1);
+ strncpy (bufsock->buffer, &buffer[tmpsize], size);
+ bufsock->cur = size;
+ }
+ else
+ {
+ return status;
+ }
+
+ return HSOCKET_OK;
+ }
+}
+
+int
+hsocket_makenonblock (hsocket_t sock)
+{
+#ifdef WIN32
+ unsigned long iMode;
+ iMode = HSOCKET_NONBLOCKMODE;
+ if (ioctlsocket (sock, FIONBIO, (u_long FAR *) & iMode) == INVALID_SOCKET)
+ {
+ log_error1 ("ioctlsocket error");
+ return -1;
+ }
+#else /* fcntl(sock, F_SETFL, O_NONBLOCK); */
+#endif
+ return HSOCKET_OK;
+}
+
+#ifdef WIN32
+
+struct tm *
+localtime_r (const time_t * const timep, struct tm *p_tm)
+{
+ static struct tm *tmp;
+ tmp = localtime (timep);
+ if (tmp)
+ {
+ memcpy (p_tm, tmp, sizeof (struct tm));
+ tmp = p_tm;
+ }
+ return tmp;
+}
+
+#endif /* */
diff --git a/nanohttp/nanohttp-socket.h b/nanohttp/nanohttp-socket.h
index 4380866..117a5b2 100644
--- a/nanohttp/nanohttp-socket.h
+++ b/nanohttp/nanohttp-socket.h
@@ -1,219 +1,214 @@
-/******************************************************************
- * $Id: nanohttp-socket.h,v 1.10 2004/09/13 15:33:32 rans Exp $
- *
- * CSOAP Project: A http client/server library in C
- * Copyright (C) 2003 Ferhat Ayaz
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Email: ayaz@jprogrammer.net
- ******************************************************************/
-#ifndef NANO_HTTP_SOCKET_H
-#define NANO_HTTP_SOCKET_H
-
-#define HSOCKET_OK 0
-#define HSOCKET_CAN_NOT_CREATE 1001
-#define HSOCKET_CAN_NOT_GET_HOSTNAME 1002
-#define HSOCKET_CAN_NOT_CONNECT 1003
-#define HSOCKET_CAN_NOT_SEND 1004
-#define HSOCKET_CAN_NOT_RECEIVE 1005
-#define HSOCKET_CAN_NOT_BIND 1006
-#define HSOCKET_CAN_NOT_LISTEN 1007
-#define HSOCKET_CAN_NOT_ACCEPT 1008
-
-#define HSOCKET_MAX_BUFSIZE 1024
+/******************************************************************
+ * $Id: nanohttp-socket.h,v 1.11 2004/09/14 13:23:10 snowdrop Exp $
+ *
+ * CSOAP Project: A http client/server library in C
+ * Copyright (C) 2003 Ferhat Ayaz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Email: ayaz@jprogrammer.net
+ ******************************************************************/
+#ifndef NANO_HTTP_SOCKET_H
+#define NANO_HTTP_SOCKET_H
+
+#define HSOCKET_OK 0
+#define HSOCKET_CAN_NOT_CREATE 1001
+#define HSOCKET_CAN_NOT_GET_HOSTNAME 1002
+#define HSOCKET_CAN_NOT_CONNECT 1003
+#define HSOCKET_CAN_NOT_SEND 1004
+#define HSOCKET_CAN_NOT_RECEIVE 1005
+#define HSOCKET_CAN_NOT_BIND 1006
+#define HSOCKET_CAN_NOT_LISTEN 1007
+#define HSOCKET_CAN_NOT_ACCEPT 1008
+
+#define HSOCKET_MAX_BUFSIZE 1024
#define HSOCKET_BLOCKMODE 0
#define HSOCKET_NONBLOCKMODE 1
-
-#include <time.h>
-#ifdef WIN32
-#include <winsock2.h>
-#include <process.h>
-#include <string.h>
-typedef SOCKET hsocket_t;
-typedef int socklen_t;
-#define close(s) closesocket(s)
-#else
-#include <pthread.h>
-typedef int hsocket_t;
-#endif
-/*
- PROTOTYPE:
- int my_recv_cb(hsocket_t sock, char *buffer, int size, void *userdata);
- returns 1 to continue 0 to stop receiving.
- */
-typedef int (*hsocket_recv_callback)(hsocket_t, char *, int, void*);
-
-
-/*
- hsocket_module_init
- Returns 0 if success.
- >0 if fail.
- */
-int hsocket_module_init();
-void hsocket_module_destroy();
-
-
-/*
- hsocket_init
- Returns 0 if success.
- >0 if fail.
- */
-int hsocket_init(hsocket_t *sock);
-void hsocket_free(hsocket_t sock);
-
-
-/*
- hsocket_open: create and connect a socket
- Returns 0 if success
- >0 if fail.
- */
-int hsocket_open(hsocket_t *sock, const char* host, int port);
-void hsocket_close(hsocket_t sock);
-
-/*
- hsocket_bind: create and bind a socket
- Returns 0 if success
- >0 if fail.
- */
-int hsocket_bind(hsocket_t *sock, int port);
-
-/*
- Listen to socket. Must be called after bind
- */
-int hsocket_listen(hsocket_t sock, int n);
-
-typedef struct tag_conndata
-{
- hsocket_t sock;
-#ifdef WIN32
- HANDLE tid;
-#else
- pthread_t tid;
- pthread_attr_t attr;
-#endif
- time_t atime;
-}conndata_t;
-
-#ifdef WIN32
-int hsocket_accept(hsocket_t sock, unsigned ( __stdcall *func )( void * ), conndata_t *conns,
- int max_conn, int *termsig);
-#else
-int hsocket_accept(hsocket_t sock, void(*func) (void *), conndata_t *conns,
- int max_conn, int *termsig);
-#endif
-
-
-/*
- hsocket_nsend
- sends n bytes of data
- Returns 0 if success
- >0 if fail
- */
-int hsocket_nsend(hsocket_t sock, const char* buffer, int n);
-
-/*
- hsocket_send
- sends strlen(buffer) bytes of data
- Returns 0 if success
- >0 if fail
- */
-int hsocket_send(hsocket_t sock, const char* buffer);
-
-
-/*
- hsocket_recv
- receives everything quequed on the socket.
- Sets *buffer to the received buffer.
- Sets size to the received size.
- You must free the buffer manually with free().
- If buffer is non zero, this functions assumes that
- buffer is valid and just reallocates the given buffer.
- If buffer is zero (like in the following example),
- the buffer will be allocated first.
-
- Example:
-
- int size;
- char *buffer;
- hsocket_t sock;
-
- buffer = 0;
- sock = ...
-
- if (!hsocket_recv(sock, &buffer, &size)) {
- printf("Received total: %d\n", size);
- printf("Received: '%s'\n", buffer);
-
- free(buffer);
- } else {
- printf("Error receiving data\n");
- }
-
- Returns 0 if success
- >0 if fail
- */
-int hsocket_recv(hsocket_t sock, char** buffer, int *size);
-
-int hsocket_recv_limit(hsocket_t sock, char** buffer,
- const char* delim, char **rest,
- int *totalBuffer, int *totalRest);
-
-/*
- returns 1 to continue, 0 to break;
- */
-int hsocket_recv_cb(hsocket_t sock,
- hsocket_recv_callback cb, void *userdata);
-
-int hsocket_read(hsocket_t sock, char* buffer, int total, int force);
-
-
-/* ======================================== */
-/* Buffered socket */
-/* ======================================== */
-typedef struct _bufsocket
-{
- hsocket_t sock;
- char *buffer;
- int bufsize;
- int cur;
-}hbufsocket_t;
-
-
-int hbufsocket_read(hbufsocket_t *bufsock, char *buffer, int size);
-
-/*--------------------------------------------------
-FUNCTION: hsocket_makenonblock
-----------------------------------------------------*/
-int hsocket_makenonblock(hsocket_t sock);
-
-#ifdef WIN32
-
-struct tm *localtime_r(const time_t *const timep, struct tm *p_tm);
- #endif
-#endif
-
-
-
-
-
-
-
-
-
-
-
+
+#include <time.h>
+#ifdef WIN32
+#include <winsock2.h>
+#include <process.h>
+#include <string.h>
+typedef SOCKET hsocket_t;
+typedef int socklen_t;
+#define close(s) closesocket(s)
+#else
+#include <pthread.h>
+typedef int hsocket_t;
+#endif
+/*
+ PROTOTYPE:
+ int my_recv_cb(hsocket_t sock, char *buffer, int size, void *userdata);
+ returns 1 to continue 0 to stop receiving.
+ */
+typedef int (*hsocket_recv_callback)(hsocket_t, char *, int, void*);
+
+
+/*
+ hsocket_module_init
+ Returns 0 if success.
+ >0 if fail.
+ */
+int hsocket_module_init();
+void hsocket_module_destroy();
+
+
+/*
+ hsocket_init
+ Returns 0 if success.
+ >0 if fail.
+ */
+int hsocket_init(hsocket_t *sock);
+void hsocket_free(hsocket_t sock);
+
+
+/*
+ hsocket_open: create and connect a socket
+ Returns 0 if success
+ >0 if fail.
+ */
+int hsocket_open(hsocket_t *sock, const char* host, int port);
+void hsocket_close(hsocket_t sock);
+
+/*
+ hsocket_bind: create and bind a socket
+ Returns 0 if success
+ >0 if fail.
+ */
+int hsocket_bind(hsocket_t *sock, int port);
+
+/*
+ Listen to socket. Must be called after bind
+ */
+int hsocket_listen(hsocket_t sock, int n);
+
+typedef struct tag_conndata
+{
+ hsocket_t sock;
+#ifdef WIN32
+ HANDLE tid;
+#else
+ pthread_t tid;
+ pthread_attr_t attr;
+#endif
+ time_t atime;
+}conndata_t;
+
+int hsocket_accept(hsocket_t sock, hsocket_t *dest);
+
+
+/*
+ hsocket_nsend
+ sends n bytes of data
+ Returns 0 if success
+ >0 if fail
+ */
+int hsocket_nsend(hsocket_t sock, const char* buffer, int n);
+
+/*
+ hsocket_send
+ sends strlen(buffer) bytes of data
+ Returns 0 if success
+ >0 if fail
+ */
+int hsocket_send(hsocket_t sock, const char* buffer);
+
+
+/*
+ hsocket_recv
+ receives everything quequed on the socket.
+ Sets *buffer to the received buffer.
+ Sets size to the received size.
+ You must free the buffer manually with free().
+ If buffer is non zero, this functions assumes that
+ buffer is valid and just reallocates the given buffer.
+ If buffer is zero (like in the following example),
+ the buffer will be allocated first.
+
+ Example:
+
+ int size;
+ char *buffer;
+ hsocket_t sock;
+
+ buffer = 0;
+ sock = ...
+
+ if (!hsocket_recv(sock, &buffer, &size)) {
+ printf("Received total: %d\n", size);
+ printf("Received: '%s'\n", buffer);
+
+ free(buffer);
+ } else {
+ printf("Error receiving data\n");
+ }
+
+ Returns 0 if success
+ >0 if fail
+ */
+int hsocket_recv(hsocket_t sock, char** buffer, int *size);
+
+int hsocket_recv_limit(hsocket_t sock, char** buffer,
+ const char* delim, char **rest,
+ int *totalBuffer, int *totalRest);
+
+/*
+ returns 1 to continue, 0 to break;
+ */
+int hsocket_recv_cb(hsocket_t sock,
+ hsocket_recv_callback cb, void *userdata);
+
+int hsocket_read(hsocket_t sock, char* buffer, int total, int force);
+
+
+/* ======================================== */
+/* Buffered socket */
+/* ======================================== */
+typedef struct _bufsocket
+{
+ hsocket_t sock;
+ char *buffer;
+ int bufsize;
+ int cur;
+}hbufsocket_t;
+
+
+int hbufsocket_read(hbufsocket_t *bufsock, char *buffer, int size);
+
+/*--------------------------------------------------
+FUNCTION: hsocket_makenonblock
+----------------------------------------------------*/
+int hsocket_makenonblock(hsocket_t sock);
+
+#ifdef WIN32
+
+struct tm *localtime_r(const time_t *const timep, struct tm *p_tm);
+
+#endif
+#endif
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nanohttp/nanohttp-windows.h b/nanohttp/nanohttp-windows.h
index 9e15fbb..f8cf99b 100644
--- a/nanohttp/nanohttp-windows.h
+++ b/nanohttp/nanohttp-windows.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: nanohttp-windows.h,v 1.1 2004/08/31 16:34:57 rans Exp $
+ * $Id: nanohttp-windows.h,v 1.2 2004/09/14 13:23:10 snowdrop Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -61,3 +61,4 @@ static void WSAReaper(void *x)
#endif
#endif
+