diff options
Diffstat (limited to 'nanohttp')
-rw-r--r-- | nanohttp/nanohttp-common.h | 10 | ||||
-rw-r--r-- | nanohttp/nanohttp-server.c | 157 | ||||
-rw-r--r-- | nanohttp/nanohttp-socket.c | 1072 | ||||
-rw-r--r-- | nanohttp/nanohttp-socket.h | 427 | ||||
-rw-r--r-- | nanohttp/nanohttp-windows.h | 3 |
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 + |