diff options
| -rw-r--r-- | nanohttp/nanohttp-client.c | 46 | ||||
| -rw-r--r-- | nanohttp/nanohttp-client.h | 17 | ||||
| -rw-r--r-- | nanohttp/nanohttp-server.c | 145 | ||||
| -rw-r--r-- | nanohttp/nanohttp-socket.c | 101 | ||||
| -rw-r--r-- | nanohttp/nanohttp-socket.h | 36 | ||||
| -rw-r--r-- | nanohttp/nanohttp-windows.h | 63 | 
6 files changed, 227 insertions, 181 deletions
| diff --git a/nanohttp/nanohttp-client.c b/nanohttp/nanohttp-client.c index 22571c6..20a04a1 100644 --- a/nanohttp/nanohttp-client.c +++ b/nanohttp/nanohttp-client.c @@ -1,5 +1,5 @@  /****************************************************************** -*  $Id: nanohttp-client.c,v 1.16 2004/08/30 15:26:53 snowdrop Exp $ +*  $Id: nanohttp-client.c,v 1.17 2004/08/31 16:34:08 rans Exp $  *  * CSOAP Project:  A http client/server library in C  * Copyright (C) 2003  Ferhat Ayaz @@ -23,12 +23,6 @@  ******************************************************************/  #include <nanohttp/nanohttp-client.h> -#ifdef WIN32 -#include "wsockcompat.h" -#include <winsock2.h> -#define close(s) closesocket(s) -#endif -  #ifdef HAVE_CONFIG_H  #include <config.h>  #endif @@ -38,23 +32,6 @@  #include <stdlib.h> -#ifdef WIN32 - -#include <string.h> - -static 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
 -
  /*--------------------------------------------------
  FUNCTION: httpc_init
  DESC: Initialize http client connection 
 @@ -589,11 +566,6 @@ int httpc_talk_to_server(hreq_method method, httpc_conn_t *conn,  	char buffer[4096];  	int status; -#ifdef WIN32 -	unsigned long iMode = HSOCKET_NONBLOCKMODE; -#endif - -  	if (conn == NULL) {  		log_error1("Connection object is NULL");  		return 1; @@ -620,21 +592,13 @@ int httpc_talk_to_server(hreq_method method, httpc_conn_t *conn,  		return 3;  	} -#ifndef WIN32 -	/* Try always non block mode
 -	#if HSOCKET_BLOCKMODE!=0*/ -		fcntl(conn->sock, F_SETFL, O_NONBLOCK); -	/*#endif*/ -#else
 -	iMode = HSOCKET_NONBLOCKMODE; -	if(ioctlsocket(conn->sock, FIONBIO, (u_long FAR*) &iMode) == INVALID_SOCKET) +	status=hsocket_makenonblock(conn->sock); +	if(status!=HSOCKET_OK)  	{ -		log_error1("ioctlsocket error"); -		return -1; +		log_error1("Cannot make socket non-blocking"); +		return status;  	} -#endif -  	/* check method */  	if (method == HTTP_REQUEST_GET) { diff --git a/nanohttp/nanohttp-client.h b/nanohttp/nanohttp-client.h index 9c5cd64..f937f00 100644 --- a/nanohttp/nanohttp-client.h +++ b/nanohttp/nanohttp-client.h @@ -1,5 +1,5 @@  /****************************************************************** - *  $Id: nanohttp-client.h,v 1.6 2004/08/30 15:26:53 snowdrop Exp $ + *  $Id: nanohttp-client.h,v 1.7 2004/08/31 16:34:08 rans Exp $   *   * CSOAP Project:  A http client/server library in C   * Copyright (C) 2003  Ferhat Ayaz @@ -90,18 +90,3 @@ int httpc_post_finish_cb(httpc_conn_t *conn,  #endif - - - - - - - - - - - - - - - diff --git a/nanohttp/nanohttp-server.c b/nanohttp/nanohttp-server.c index 7823cc5..807ab58 100644 --- a/nanohttp/nanohttp-server.c +++ b/nanohttp/nanohttp-server.c @@ -1,5 +1,5 @@  /****************************************************************** -*  $Id: nanohttp-server.c,v 1.13 2004/08/31 13:57:27 rans Exp $ +*  $Id: nanohttp-server.c,v 1.14 2004/08/31 16:34:08 rans Exp $  *  * CSOAP Project:  A http client/server library in C  * Copyright (C) 2003  Ferhat Ayaz @@ -23,38 +23,15 @@  ******************************************************************/  #include <nanohttp/nanohttp-server.h> -#include <time.h>  #include <stdio.h>  #include <stdlib.h> -#include <string.h>  #include <signal.h> -#ifdef WIN32 -#include "wsockcompat.h" -#include <winsock2.h> -#include <process.h> -#define close(s) closesocket(s) - -static 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; -} - -typedef int socklen_t; -#endif -  #ifdef HAVE_CONFIG_H  #include <config.h>  #endif  #ifndef WIN32 -#include <pthread.h>  /* According to POSIX 1003.1-2001 */  #include <sys/select.h> @@ -63,25 +40,14 @@ typedef int socklen_t;  #include <sys/types.h>  #include <unistd.h> -#include <fcntl.h>  #endif -typedef struct tag_conndata -{ -	hsocket_t sock; -#ifdef WIN32 -	HANDLE tid; -#else -	pthread_t tid; -	pthread_attr_t attr; -#endif -}conndata_t; -  /* -----------------------------------------------------   nano httpd internally globals  ----------------------------------------------------- */  static int _httpd_port = 10000;  static int _httpd_max_connections = 20; +static int _httpd_max_idle = 120;  static hsocket_t _httpd_socket;  static hservice_t *_httpd_services_head = NULL;  static hservice_t *_httpd_services_tail = NULL; @@ -89,6 +55,10 @@ static int _httpd_run = 1;  static int _httpd_terminate_signal = SIGTERM;  static conndata_t *_httpd_connection; +#ifdef WIN32 +#include <nanohttp/nanohttp-windows.h> +#endif +  /* -----------------------------------------------------   FUNCTION: httpd_init
  NOTE: This will be called from soap_server_init_args() @@ -96,12 +66,9 @@ NOTE: This will be called from soap_server_init_args()  int httpd_init(int argc, char *argv[])  {  	int i, status; -
	_httpd_connection=calloc(_httpd_max_connections, sizeof(conndata_t));
	for(i=0; i<_httpd_max_connections; i++)
	{
		_httpd_connection[i].sock=0; -	} -	status = hsocket_module_init();
 +
	status = hsocket_module_init();
  	if (status != 0)
  		return status;
 -
  	/* write argument information */  	log_verbose1("Arguments:");   @@ -123,6 +90,15 @@ int httpd_init(int argc, char *argv[])  	/*  	httpd_register("/httpd/list", service_list);  	*/ +	_httpd_connection=calloc(_httpd_max_connections, sizeof(conndata_t));
	for(i=0; i<_httpd_max_connections; i++)
	{
		memset((char *)&_httpd_connection[i], 0, sizeof(_httpd_connection[i])); +	} + +#ifdef WIN32 +	if (_beginthread(WSAReaper, 0, NULL)==-1) { +		log_error1("Winsock reaper thread failed to start"); +		return(-1); +	} +#endif  	/* create socket */  	hsocket_init(&_httpd_socket); @@ -312,7 +288,7 @@ static void* httpd_session_main(void *data)  	log_verbose1("starting httpd_session_main()"); - +	conn->atime=time((time_t)0);  	while (len < 4064) {  		/*printf("receiving ...\n");*/  		total = recv(conn->sock, ch, 1, 0); @@ -361,6 +337,7 @@ static void* httpd_session_main(void *data)  	hrequest_free(req);  #ifdef WIN32 +	CloseHandle((HANDLE)conn->tid);  	_endthread();  	return 0;  #else @@ -379,65 +356,6 @@ void httpd_term(int sig)  		_httpd_run = 0;  } -static int httpd_accept(hsocket_t sock) -{ -	int i; -	int err; -	socklen_t asize; -	struct sockaddr_in addr; - -	asize = sizeof(struct sockaddr_in); -	while(1) -	{ -		for (i=0;;i++) { -			if (i>=_httpd_max_connections) { -				Sleep(1000); -				i=0; -				continue; -			} -			if (_httpd_connection[i].sock==0) break; -		} -		_httpd_connection[i].sock = accept(sock, (struct sockaddr *)&addr, &asize); -#ifndef WIN32 -		if (_httpd_connection[i].sock == -1) {  -			_httpd_connection[i].sock=0; -			continue; -		} -#else -		if (_httpd_connection[i].sock ==  INVALID_SOCKET) 
 -		{  -			if(WSAGetLastError()!=WSAEWOULDBLOCK) -			{ -				log_error1("accept() died...  restarting..."); -				closesocket(sock); -				WSACleanup(); -				return INVALID_SOCKET; -			} -			else -			{ -				_httpd_connection[i].sock=0; -				continue; -			} -		} -#endif -		else -		{ -			log_verbose3("accept new socket (%d) from '%s'", _httpd_connection[i].sock, -				SAVE_STR(((char*)inet_ntoa(addr.sin_addr))) ); - -#ifdef WIN32 -			_httpd_connection[i].tid=(HANDLE)_beginthreadex(NULL, 65535, httpd_session_main, &_httpd_connection[i], 0, &err); -#else -			err = pthread_create(&(_httpd_connection[i].tid), &(_httpd_connection[i].attr), httpd_session_main, &_httpd_connection[i]);  -#endif -			if (err) { -				log_error2("Error creating thread: ('%d')", err); -			} -		} -	} -	return 0; -} -  /* -----------------------------------------------------   FUNCTION: httpd_run  ----------------------------------------------------- */ @@ -449,9 +367,7 @@ int httpd_run()  	struct timeval timeout; -#ifdef WIN32 -	unsigned long iMode=HSOCKET_NONBLOCKMODE; -#else +#ifndef WIN32  pthread_attr_init(&attr);  #ifdef PTHREAD_CREATE_DETACHED  	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); @@ -474,19 +390,11 @@ pthread_attr_init(&attr);  	log_verbose2("listening to port '%d'", _httpd_port); -#ifndef WIN32 -/* Try always non block mode
 -#if HSOCKET_BLOCKMODE!=0*/ -		fcntl(_httpd_socket, F_SETFL, O_NONBLOCK); -/*#endif*/ -#else
 -	iMode = HSOCKET_NONBLOCKMODE;
 -	if(ioctlsocket(_httpd_socket, FIONBIO, (u_long FAR*) &iMode) == INVALID_SOCKET) -	{ -		log_error1("ioctlsocket error"); -		return -1; +	err=hsocket_makenonblock(_httpd_socket); +	if (err  != HSOCKET_OK) { +		log_error2("httpd_run(): '%d'", err); +		return err;  	} -#endif  	timeout.tv_sec = 1;  	timeout.tv_usec = 0; @@ -512,7 +420,8 @@ pthread_attr_init(&attr);  			if (!_httpd_run)  				break; -		if (httpd_accept(_httpd_socket) != 0) +		if (hsocket_accept(_httpd_socket, httpd_session_main, _httpd_connection,  +			_httpd_max_connections) != 0)  		{  			continue;  		} @@ -521,9 +430,6 @@ pthread_attr_init(&attr);  	return 0;  } - - -  char *httpd_get_postdata(httpd_conn_t *conn, hrequest_t *req, long *received, long max)  {  	char *content_length_str; @@ -570,5 +476,4 @@ char *httpd_get_postdata(httpd_conn_t *conn, hrequest_t *req, long *received, lo  		free (postdata);  		return NULL; -  } diff --git a/nanohttp/nanohttp-socket.c b/nanohttp/nanohttp-socket.c index 12aee6f..844a5ef 100644 --- a/nanohttp/nanohttp-socket.c +++ b/nanohttp/nanohttp-socket.c @@ -1,5 +1,5 @@  /****************************************************************** -*  $Id: nanohttp-socket.c,v 1.12 2004/08/31 13:56:24 rans Exp $ +*  $Id: nanohttp-socket.c,v 1.13 2004/08/31 16:34:08 rans Exp $  *  * CSOAP Project:  A http client/server library in C  * Copyright (C) 2003  Ferhat Ayaz @@ -27,8 +27,11 @@  #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 @@ -141,7 +144,7 @@ int hsocket_open(hsocket_t *dsock, const char* hostname, int port)  /*-------------------------------------------------- -FUNCTION: hsocket_close +FUNCTION: hsocket_bind  ----------------------------------------------------*/  int hsocket_bind(hsocket_t *dsock, int port)  { @@ -175,6 +178,70 @@ int hsocket_bind(hsocket_t *dsock, int port)  		return HSOCKET_OK;  } +#ifdef WIN32 +int hsocket_accept(hsocket_t sock, unsigned ( __stdcall *func )( void * ), conndata_t *conns,  +				   int max_conn) +#else +int hsocket_accept(hsocket_t sock, void(*func) (void *), conndata_t *conns, int max_conn) +#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) { +				Sleep(1000); +				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; +			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; +				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 +			err = pthread_create(&(conns[i].tid), &(conns[i].attr), func, &conns[i]);  +#endif +			if (err) { +				log_error2("Error creating thread: ('%d')", err); +			} +		} +	} +	return 0; +} +  /*--------------------------------------------------  FUNCTION: hsocket_listen  ----------------------------------------------------*/ @@ -394,3 +461,33 @@ int hbufsocket_read(hbufsocket_t *bufsock, char *buffer, int size)  		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 085ae0c..da3f62c 100644 --- a/nanohttp/nanohttp-socket.h +++ b/nanohttp/nanohttp-socket.h @@ -1,5 +1,5 @@  /****************************************************************** - *  $Id: nanohttp-socket.h,v 1.7 2004/08/30 15:26:53 snowdrop Exp $ + *  $Id: nanohttp-socket.h,v 1.8 2004/08/31 16:34:08 rans Exp $   *   * CSOAP Project:  A http client/server library in C   * Copyright (C) 2003  Ferhat Ayaz @@ -39,10 +39,16 @@  #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  /* @@ -91,7 +97,24 @@ int hsocket_bind(hsocket_t *sock, int port);   */  int hsocket_listen(hsocket_t sock, int n); -int hsocket_accept(hsocket_t sock, hsocket_t *dest); +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); +#else +int hsocket_accept(hsocket_t sock, void(*func) (void *), conndata_t *conns, int max_conn); +#endif  /* @@ -172,6 +195,15 @@ typedef struct _bufsocket  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 new file mode 100644 index 0000000..9e15fbb --- /dev/null +++ b/nanohttp/nanohttp-windows.h @@ -0,0 +1,63 @@ +/****************************************************************** + *  $Id: nanohttp-windows.h,v 1.1 2004/08/31 16:34:57 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_WINDOWS_H  +#define NANO_HTTP_WINDOWS_H  + +#ifdef WIN32 + +static void WSAReaper(void *x) +{ +	short int connections; +	short int i; +	char junk[10]; +	int rc; +	time_t ctime; + +	for (;;) { +		connections=0; +		ctime=time((time_t)0); +		for (i=0;i<_httpd_max_connections;i++) { + 			if (_httpd_connection[i].tid==0) continue; +			GetExitCodeThread((HANDLE)_httpd_connection[i].tid, &rc); +			if (rc!=STILL_ACTIVE) continue; +			connections++; +			if ((ctime-_httpd_connection[i].atime<_httpd_max_idle)|| +				(_httpd_connection[i].atime==0)) continue; +			log_verbose3("Reaping socket %u from (runtime ~= %d seconds)",  +				_httpd_connection[i].sock, ctime-_httpd_connection[i].atime); +			shutdown(_httpd_connection[i].sock, 2); +			while (recv(_httpd_connection[i].sock, junk, sizeof(junk), 0)>0) { }; +			closesocket(_httpd_connection[i].sock); +			TerminateThread(_httpd_connection[i].tid, (DWORD)&rc); +			CloseHandle(_httpd_connection[i].tid); +			memset((char *)&_httpd_connection[i], 0, sizeof(_httpd_connection[i])); +		} +		Sleep(100); +	} +	return; +} + +#endif + +#endif | 
