From 1a7fd033326ff93f68a80cce0bc30565251d22e0 Mon Sep 17 00:00:00 2001 From: snowdrop Date: Tue, 14 Sep 2004 13:23:10 +0000 Subject: optimizing code and extracting some long functions into little functions --- nanohttp/nanohttp-common.h | 10 +- nanohttp/nanohttp-server.c | 157 +++++-- nanohttp/nanohttp-socket.c | 1072 +++++++++++++++++++++---------------------- nanohttp/nanohttp-socket.h | 427 +++++++++-------- 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 -#include - -#ifdef WIN32 -#include "wsockcompat.h" -#include -#include -#define close(s) closesocket(s) -typedef int ssize_t; -#else -#include -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_SYS_SOCKET_H -#include -#endif - -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#ifdef HAVE_NETDB_H -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#include - -/*-------------------------------------------------- -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 +#include + + + + +#ifdef WIN32 + #include "wsockcompat.h" + #include + #include + +#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 +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#ifdef HAVE_NETDB_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include + +/*-------------------------------------------------- +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 -#ifdef WIN32 -#include -#include -#include -typedef SOCKET hsocket_t; -typedef int socklen_t; -#define close(s) closesocket(s) -#else -#include -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 +#ifdef WIN32 +#include +#include +#include +typedef SOCKET hsocket_t; +typedef int socklen_t; +#define close(s) closesocket(s) +#else +#include +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 + -- cgit v1.1-32-gdbae