From cef76c0a0932ebf036f7334aa9c2d21410ccbfed Mon Sep 17 00:00:00 2001 From: snowdrop Date: Wed, 21 Jan 2004 12:28:20 +0000 Subject: added server functionality --- config.h.in | 6 ++ examples/nanohttp/Makefile.am | 10 ++- nanohttp/Makefile.am | 6 +- nanohttp/nanohttp-common.c | 151 +++++++++++++++++++++++++++++++++++++++++- nanohttp/nanohttp-common.h | 16 ++++- nanohttp/nanohttp-socket.c | 75 ++++++++++++++++++++- nanohttp/nanohttp-socket.h | 23 ++++++- 7 files changed, 275 insertions(+), 12 deletions(-) diff --git a/config.h.in b/config.h.in index 0356f7c..2e100bd 100644 --- a/config.h.in +++ b/config.h.in @@ -51,6 +51,9 @@ /* Define to 1 if you have the `vprintf' function. */ #undef HAVE_VPRINTF +/* Name of package */ +#undef PACKAGE + /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT @@ -75,6 +78,9 @@ /* Define to 1 if your declares `struct tm'. */ #undef TM_IN_SYS_TIME +/* Version number of package */ +#undef VERSION + /* Define to empty if `const' does not conform to ANSI C. */ #undef const diff --git a/examples/nanohttp/Makefile.am b/examples/nanohttp/Makefile.am index 2901d25..dde2691 100644 --- a/examples/nanohttp/Makefile.am +++ b/examples/nanohttp/Makefile.am @@ -1,8 +1,8 @@ -bin_PROGRAMS=httpget httpgetcb httppost +bin_PROGRAMS=httpget httpgetcb httppost httpcpost helloserver INCLUDES=-I$(top_srcdir)/ LDFLAGS=-L$(top_builddir)/nanohttp -lnanohttp-$(GENERIC_API_VERSION) \ - $(LIBSOCKET) $(LIBNSL) + $(LIBSOCKET) $(LIBNSL) -lpthread httpget_SOURCES=httpget.c httpget_LDFLAGS=$(LDFLAGS) @@ -13,6 +13,12 @@ httpgetcb_LDFLAGS=$(LDFLAGS) httppost_SOURCES=httppost.c httppost_LDFLAGS=$(LDFLAGS) +httpcpost_SOURCES=httpcpost.c +httpcpost_LDFLAGS=$(LDFLAGS) + +helloserver_SOURCES=helloserver.c +helloserver_LDFLAGS=$(LDFLAGS) + diff --git a/nanohttp/Makefile.am b/nanohttp/Makefile.am index c290ff6..c8ba204 100644 --- a/nanohttp/Makefile.am +++ b/nanohttp/Makefile.am @@ -2,12 +2,14 @@ h_sources = nanohttp-common.h\ +nanohttp-socket.h\ nanohttp-client.h\ -nanohttp-socket.h +nanohttp-server.h cc_sources = nanohttp-common.c\ +nanohttp-socket.c\ nanohttp-client.c\ -nanohttp-socket.c +nanohttp-server.c library_includedir=$(includedir)/$(NANOHTTP_LIBRARY_NAME)-$(NANOHTTP_API_VERSION)/$(NANOHTTP_LIBRARY_NAME) library_include_HEADERS = $(h_sources) diff --git a/nanohttp/nanohttp-common.c b/nanohttp/nanohttp-common.c index 29c237a..55a9f7f 100644 --- a/nanohttp/nanohttp-common.c +++ b/nanohttp/nanohttp-common.c @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-common.c,v 1.6 2003/12/18 15:32:09 snowdrop Exp $ + * $Id: nanohttp-common.c,v 1.7 2004/01/21 12:28:20 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -419,6 +419,155 @@ void hurl_free(hurl_t *url) } +/* request stuff */ + +/* ----------------------------------------------------- + FUNCTION: hrequest_new_from_buffer +----------------------------------------------------- */ +hrequest_t *hrequest_new_from_buffer(char *data) +{ + hrequest_t *req; + hpair_t *hpair = NULL, *qpair = NULL, *tmppair = NULL; + + char *tmp; + char *tmp2; + char *saveptr; + char *saveptr2; + char *saveptr3; + char *result; + char *key; + char *value; + char *opt_key; + char *opt_value; + int firstline = 1; + + req = (hrequest_t*)malloc(sizeof(hrequest_t)); + + req->method = NULL; + req->spec = NULL; + req->path = NULL; + req->query = NULL; + req->header = NULL; + + tmp = data; + + for (;;) { + result = (char*)strtok_r(tmp, "\n", &saveptr); + tmp=saveptr; + + if (result == NULL) + break; + + if (firstline) { + firstline=0; + tmp2 = result; + + /* parse [GET|POST] [PATH] [SPEC] */ + key = (char*)strtok_r(tmp2," ", &saveptr2); + + /* save method (get or post) */ + tmp2 = saveptr2; + if (key != NULL) { + req->method = (char*)malloc(strlen(key)+1); + strcpy(req->method, key); + } + + /* below is key the path and tmp2 the spec */ + key = (char*)strtok_r(tmp2," ", &saveptr2); + + /* save spec */ + tmp2 = saveptr2; + if (tmp2 != NULL) { + req->spec = (char*)malloc(strlen(tmp2)+1); + strcpy(req->spec, tmp2); + } + + /* parse and save path+query + parse: /path/of/target?key1=value1&key2=value2... + */ + + if (key != NULL) { + tmp2 = key; + key = (char*)strtok_r(tmp2,"?", &saveptr2); + tmp2 = saveptr2; + + /* save path */ + req->path = (char*)malloc(strlen(key)+1); + strcpy(req->path, key); + + /* parse options */ + for (;;) { + key = (char*)strtok_r(tmp2,"&",&saveptr2); + tmp2 = saveptr2; + + if (key == NULL) + break; + + opt_key = (char*)strtok_r(key,"=", &saveptr3); + opt_value = saveptr3; + + if (opt_value == NULL) + opt_value = ""; + + /* create option pair */ + if (opt_key != NULL) { + tmppair = (hpair_t*)malloc(sizeof(hpair_t)); + + if (req->query == NULL) { + req->query = qpair = tmppair; + } else { + qpair->next = tmppair; + qpair = tmppair; + } + + /* fill hpairnode_t struct */ + qpair->next = NULL; + qpair->key = (char*)malloc(strlen(opt_key)+1); + qpair->value = (char*)malloc(strlen(opt_value)+1); + + strcpy(qpair->key, opt_key); + strcpy(qpair->value, opt_value); + + } + } + } + + } else { + + /* parse "key: value" */ + tmp2 = result; + key = (char*)strtok_r(tmp2, ": ", &saveptr2); + value = saveptr2; + + /* create pair */ + tmppair = (hpair_t*)malloc(sizeof(hpair_t)); + + if (req->header == NULL) { + req->header = hpair = tmppair; + } else { + hpair->next = tmppair; + hpair = tmppair; + } + + /* fill pairnode_t struct */ + hpair->next = NULL; + hpair->key = (char*)malloc(strlen(key)+1); + hpair->value = (char*)malloc(strlen(value)+1); + + strcpy(hpair->key, key); + strcpy(hpair->value, value); + } + } + + return req; +} + + +void hrequest_free(hrequest_t *req) +{ + log_warn1("hrequest_free() not implemented!"); +} + /* response stuff */ diff --git a/nanohttp/nanohttp-common.h b/nanohttp/nanohttp-common.h index 79db58b..ebde99c 100644 --- a/nanohttp/nanohttp-common.h +++ b/nanohttp/nanohttp-common.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-common.h,v 1.5 2003/12/18 12:23:44 snowdrop Exp $ + * $Id: nanohttp-common.h,v 1.6 2004/01/21 12:28:20 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -87,6 +87,20 @@ typedef struct hurl hurl_t* hurl_new(const char* urlstr); void hurl_free(hurl_t *url); +/* + request object + */ +typedef struct hrequest +{ + char *method; + char *path; + char *spec; + hpair_t *query; + hpair_t *header; +}hrequest_t; + +hrequest_t *hrequest_new_from_buffer(char *data); +void hrequest_free(hrequest_t *req); /* response object */ diff --git a/nanohttp/nanohttp-socket.c b/nanohttp/nanohttp-socket.c index b5ada49..e828992 100644 --- a/nanohttp/nanohttp-socket.c +++ b/nanohttp/nanohttp-socket.c @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-socket.c,v 1.6 2004/01/13 12:31:57 snowdrop Exp $ + * $Id: nanohttp-socket.c,v 1.7 2004/01/21 12:28:20 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -49,7 +49,7 @@ #endif #include - +#include /*-------------------------------------------------- FUNCTION: hsocket_module_init @@ -100,7 +100,7 @@ int hsocket_open(hsocket_t *dsock, const char* hostname, int port) struct hostent* host; sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock <= 0) return HSOCKET_CAN_NOT_CREATE_SOCKET; + if (sock <= 0) return HSOCKET_CAN_NOT_CREATE; /* Get host data */ host = gethostbyname(hostname); @@ -121,6 +121,75 @@ int hsocket_open(hsocket_t *dsock, const char* hostname, int port) } +/*-------------------------------------------------- + FUNCTION: hsocket_close +----------------------------------------------------*/ +int hsocket_bind(hsocket_t *dsock, int port) +{ + int sock; + struct sockaddr_in addr; + + /* create socket */ + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == -1) { + log_error2("Can not create socket: '%s'\n", 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'\n", strerror(errno)); + return HSOCKET_CAN_NOT_BIND; + } + + *dsock = sock; + 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'\n", strerror(errno)); + return HSOCKET_CAN_NOT_LISTEN; + } + return HSOCKET_OK; +} + + +/*-------------------------------------------------- + FUNCTION: hsocket_listen +----------------------------------------------------*/ +int hsocket_accept(hsocket_t sock, hsocket_t *dest) +{ + socklen_t asize; + int sockfd; + struct sockaddr_in addr; + + asize = sizeof(struct sockaddr_in); + sockfd = accept(sock, (struct sockaddr *)&addr, &asize); + + if (sockfd == -1) { + //httpd_log("httpd_run(): '%s'\n", strerror(errno)); + return HSOCKET_CAN_NOT_ACCEPT; + } + + log_debug3("accept new socket (%d) from '%s'\n", sockfd, + SAVE_STR(((char*)inet_ntoa(addr.sin_addr))) ); + + *dest = sockfd; + return HSOCKET_OK; +} + + /*-------------------------------------------------- FUNCTION: hsocket_close ----------------------------------------------------*/ diff --git a/nanohttp/nanohttp-socket.h b/nanohttp/nanohttp-socket.h index d73cf50..12dc5d9 100644 --- a/nanohttp/nanohttp-socket.h +++ b/nanohttp/nanohttp-socket.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-socket.h,v 1.4 2004/01/05 10:42:15 snowdrop Exp $ + * $Id: nanohttp-socket.h,v 1.5 2004/01/21 12:28:20 snowdrop Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -26,11 +26,14 @@ #define HSOCKET_OK 0 -#define HSOCKET_CAN_NOT_CREATE_SOCKET 1001 +#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 @@ -63,13 +66,27 @@ void hsocket_free(hsocket_t sock); /* - hsocket_open + 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); + +int hsocket_accept(hsocket_t sock, hsocket_t *dest); + /* hsocket_nsend -- cgit v1.1-32-gdbae