summaryrefslogtreecommitdiffstats
path: root/nanohttp
diff options
context:
space:
mode:
Diffstat (limited to 'nanohttp')
-rw-r--r--nanohttp/Makefile.am29
-rw-r--r--nanohttp/nanohttp-client.c494
-rw-r--r--nanohttp/nanohttp-client.h88
-rw-r--r--nanohttp/nanohttp-common.c357
-rw-r--r--nanohttp/nanohttp-common.h142
-rw-r--r--nanohttp/nanohttp-socket.c324
-rw-r--r--nanohttp/nanohttp-socket.h138
-rw-r--r--nanohttp/readme.txt2
8 files changed, 1574 insertions, 0 deletions
diff --git a/nanohttp/Makefile.am b/nanohttp/Makefile.am
new file mode 100644
index 0000000..c290ff6
--- /dev/null
+++ b/nanohttp/Makefile.am
@@ -0,0 +1,29 @@
+## Source directory
+
+
+h_sources = nanohttp-common.h\
+nanohttp-client.h\
+nanohttp-socket.h
+
+cc_sources = nanohttp-common.c\
+nanohttp-client.c\
+nanohttp-socket.c
+
+library_includedir=$(includedir)/$(NANOHTTP_LIBRARY_NAME)-$(NANOHTTP_API_VERSION)/$(NANOHTTP_LIBRARY_NAME)
+library_include_HEADERS = $(h_sources)
+
+INCLUDES = -I$(top_srcdir)
+
+# GENERIC_API_VERSION is 1.0
+lib_LTLIBRARIES= libnanohttp-1.0.la
+libnanohttp_1_0_la_SOURCES= $(h_sources) $(cc_sources)
+libnanohttp_1_0_la_LDFLAGS= -version-info $(NANOHTTP_LIBRARY_VERSION) -release $(NANOHTTP_RELEASE)
+
+
+
+
+
+
+
+
+
diff --git a/nanohttp/nanohttp-client.c b/nanohttp/nanohttp-client.c
new file mode 100644
index 0000000..72af32e
--- /dev/null
+++ b/nanohttp/nanohttp-client.c
@@ -0,0 +1,494 @@
+/******************************************************************
+ * $Id: nanohttp-client.c,v 1.1 2003/12/11 14:51:04 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-client.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <time.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/*--------------------------------------------------
+ STRUCTURES
+----------------------------------------------------*/
+typedef struct httpc_cb_userdata
+{
+ httpc_conn_t *conn;
+ void *userdata;
+ httpc_response_callback callback;
+ int counter;
+}httpc_cb_userdata_t;
+
+
+/*--------------------------------------------------
+ FUNCTION: httpc_new
+----------------------------------------------------*/
+httpc_conn_t* httpc_new()
+{
+ httpc_conn_t* res = (httpc_conn_t*)malloc(sizeof(httpc_conn_t));
+
+ hsocket_init(&res->sock);
+ res->header = NULL;
+ res->url = NULL;
+
+ return res;
+}
+
+
+/*--------------------------------------------------
+ FUNCTION: httpc_free
+----------------------------------------------------*/
+void httpc_free(httpc_conn_t* conn)
+{
+ const char *FUNC = "httpc_free";
+ hpair_t *tmp;
+
+ if (conn != NULL) {
+ hsocket_free(conn->sock);
+
+
+
+ while (conn->header != NULL) {
+ tmp = conn->header;
+ conn->header = conn->header->next;
+ hpairnode_free(tmp);
+ }
+
+ free(conn);
+ }
+}
+
+
+/*--------------------------------------------------
+ FUNCTION: httpc_add_header
+----------------------------------------------------*/
+void httpc_add_header(httpc_conn_t *conn, const char* key, const char* value)
+{
+ const char *FUNC = "httpc_add_header";
+
+ if (conn == NULL) {
+ log_warn(FUNC, "Connection object is NULL");
+ return;
+ }
+
+ conn->header = hpairnode_new(key, value, conn->header);
+}
+
+
+/*--------------------------------------------------
+ FUNCTION: httpc_set_header
+----------------------------------------------------*/
+int httpc_set_header(httpc_conn_t *conn, const char* key, const char* value)
+{
+ const char *FUNC = "httpc_set_header";
+ hpair_t *p;
+
+ if (conn == NULL) {
+ log_warn(FUNC, "Connection object is NULL");
+ return 0;
+ }
+
+ p = conn->header;
+ while (p != NULL) {
+ if (p->key != NULL) {
+ if (!strcmp(p->key, key)) {
+ free(p->value);
+ p->value = (char*)malloc(strlen(value)+1);
+ strcpy(p->value, value);
+ return 1;
+ }
+ }
+ p = p->next;
+ }
+
+ conn->header = hpairnode_new(key, value, conn->header);
+ return 0;
+}
+
+
+
+/*--------------------------------------------------
+ FUNCTION: httpc_build_header
+----------------------------------------------------*/
+static
+void httpc_build_header(httpc_conn_t *conn)
+{
+ char buffer[255];
+ time_t nw;
+ struct tm stm;
+
+ /* Set date */
+ nw = time(NULL);
+ localtime_r(&nw, &stm);
+ strftime(buffer, 255, "%a, %d %b %y %T GMT", &stm);
+ httpc_set_header(conn, HEADER_DATE, buffer);
+
+}
+
+/*--------------------------------------------------
+ FUNCTION: httpc_get
+----------------------------------------------------*/
+hresponse_t *httpc_get(httpc_conn_t *conn, const char* urlstr)
+{
+ const char *FUNC = "httpc_get";
+
+ hurl_t *url;
+ char buffer[255];
+ int status;
+ char *response;
+ int rsize;
+ hresponse_t *res;
+ char *rest;
+ int restsize;
+
+ if (conn == NULL) {
+ log_error(FUNC, "Connection object is NULL");
+ return NULL;
+ }
+
+ /* set response to 0 to allocate
+ it in hsocket_recv */
+ response = 0;
+
+ /* Build request header */
+ httpc_build_header(conn);
+
+ /* Create url */
+ url = hurl_new(urlstr);
+ if (url == NULL) {
+ log_error(FUNC, "Can not parse URL '%s'", SAVE_STR(urlstr));
+ return NULL;
+ }
+
+ /* Set hostname */
+ httpc_set_header(conn, HEADER_HOST, url->host);
+
+ /* Open connection */
+ status = hsocket_open(&conn->sock, url->host, url->port);
+ if (status != HSOCKET_OK) {
+ log_error(FUNC, "Can not open connection to '%s' (status:%d)",
+ SAVE_STR(url->host), status);
+ return NULL;
+ }
+
+ /* Send GET */
+ sprintf(buffer, "GET %s HTTP/1.1\r\n",
+ (url->context)?url->context:("/"));
+ status = hsocket_send(conn->sock, buffer);
+ if (status != HSOCKET_OK) {
+ log_error(FUNC, "Can not send GET (status:%d)", status);
+ hsocket_close(conn->sock);
+ return NULL;
+ }
+
+ /* Send Header */
+ status = httpc_send_header(conn);
+ if (status != HSOCKET_OK) {
+ log_error(FUNC, "Can not send header (status:%d)", status);
+ hsocket_close(conn->sock);
+ return NULL;
+ }
+
+ /* Receive Response */
+ status = hsocket_recv(conn->sock, &response, &rsize);
+ if (status != HSOCKET_OK) {
+ log_error(FUNC, "Can not receive response (status:%d)", status);
+ return NULL;
+ }
+
+
+ /*status = hsocket_recv_limit(conn->sock, &response,
+ "\r\n\r\n", &rest, &rsize, &restsize);
+ if (status != HSOCKET_OK) {
+ log_error(FUNC, "Can not receive response (status:%d)", status);
+ return NULL;
+ }
+ */
+ res = hresponse_new(response);
+
+ if (res == NULL) {
+ free(response);
+ return NULL;
+ }
+
+ /*res->body = rest;*/
+ return res;
+}
+
+
+/*--------------------------------------------------
+ FUNCTION: httpc_send_header
+----------------------------------------------------*/
+int httpc_send_header(httpc_conn_t *conn)
+{
+ hpair_t *p;
+ int status;
+ char buffer[1024];
+
+ p = conn->header;
+ while (p != NULL) {
+ if (p->key && p->value) {
+ sprintf(buffer, "%s: %s\r\n", p->key, p->value);
+ status = hsocket_send(conn->sock, buffer);
+ if (status != HSOCKET_OK)
+ return status;
+ }
+ p = p->next;
+ }
+
+ status = hsocket_send(conn->sock, "\r\n");
+ return status;
+}
+
+/*--------------------------------------------------
+ FUNCTION: httpc_post
+----------------------------------------------------*/
+hresponse_t *httpc_post(httpc_conn_t *conn, const char *urlstr, const char *content)
+{
+ const char *FUNC = "httpc_post";
+ int content_length;
+ hurl_t *url;
+ char buffer[255];
+ int status;
+ char *response;
+ hresponse_t *res;
+ int rsize;
+
+ if (conn == NULL) {
+ log_error(FUNC, "Connection object is NULL");
+ return NULL;
+ }
+
+ if (content == NULL) {
+ log_error(FUNC, "Content is NULL");
+ return NULL;
+ }
+
+ /* set response to 0 to allocate
+ it in hsocket_recv */
+ response = 0;
+
+ /* Build request header */
+ httpc_build_header(conn);
+
+ /* Create url */
+ url = hurl_new(urlstr);
+ if (url == NULL) {
+ log_error(FUNC, "Can not parse URL '%s'", SAVE_STR(urlstr));
+ return NULL;
+ }
+
+ /* Set content length */
+ content_length = strlen(content);
+ sprintf(buffer, "%d", content_length);
+ httpc_set_header(conn, HEADER_CONTENT_LENGTH, buffer);
+
+ /* Set hostname */
+ httpc_set_header(conn, HEADER_HOST, url->host);
+
+ /* Open connection */
+ status = hsocket_open(&conn->sock, url->host, url->port);
+ if (status != HSOCKET_OK) {
+ log_error(FUNC, "Can not open connection to '%s' (status:%d)",
+ SAVE_STR(url->host), status);
+ return NULL;
+ }
+
+ /* Send POST */
+ sprintf(buffer, "POST %s HTTP/1.1\r\n",
+ (url->context)?url->context:("/"));
+ status = hsocket_send(conn->sock, buffer);
+ if (status != HSOCKET_OK) {
+ log_error(FUNC, "Can not send POST (status:%d)", status);
+ hsocket_close(conn->sock);
+ return NULL;
+ }
+
+ /* Send Header */
+ status = httpc_send_header(conn);
+ if (status != HSOCKET_OK) {
+ log_error(FUNC, "Can not send header (status:%d)", status);
+ hsocket_close(conn->sock);
+ return NULL;
+ }
+
+ /* Send Content */
+ status = hsocket_send(conn->sock, content);
+ if (status != HSOCKET_OK) {
+ log_error(FUNC, "Can not send content (status:%d)", status);
+ return NULL;
+ }
+
+ /* Receive Response */
+ status = hsocket_recv(conn->sock, &response, &rsize);
+ if (status != HSOCKET_OK) {
+ log_error(FUNC, "Can not receive response (status:%d)", status);
+ return NULL;
+ }
+
+ res = hresponse_new(response);
+ if (res == NULL) {
+ free(response);
+ return NULL;
+ }
+
+ return res;
+}
+
+
+/*--------------------------------------------------
+ FUNCTION: httpc_recv_cb_callback
+----------------------------------------------------*/
+int httpc_recv_cb_callback(hsocket_t sock, char *buffer,
+ int size, void *userdata)
+{
+ httpc_cb_userdata_t *cbdata = (httpc_cb_userdata_t*)userdata;
+
+ cbdata->callback(cbdata->counter++, cbdata->conn,
+ cbdata->userdata, size, buffer);
+ return 1;
+}
+
+
+/*--------------------------------------------------
+ FUNCTION: httpc_get_cb
+----------------------------------------------------*/
+int httpc_get_cb(httpc_conn_t *conn, const char *urlstr,
+ httpc_response_start_callback start_cb,
+ httpc_response_callback cb, void *userdata)
+{
+ hurl_t *url;
+ char buffer[255];
+ int status;
+ char *response;
+ int rsize;
+ hresponse_t *res;
+ char *rest;
+ int restsize;
+ httpc_cb_userdata_t cbdata;
+
+ if (conn == NULL) {
+ log_error1("Connection object is NULL");
+ return 1;
+ }
+
+ /* set response to 0 to allocate
+ it in hsocket_recv */
+ response = 0;
+
+ /* Build request header */
+ httpc_build_header(conn);
+
+ /* Create url */
+ url = hurl_new(urlstr);
+ if (url == NULL) {
+ log_error2("Can not parse URL '%s'", SAVE_STR(urlstr));
+ return 2;
+ }
+
+ /* Set hostname */
+ httpc_set_header(conn, HEADER_HOST, url->host);
+
+ /* Open connection */
+ status = hsocket_open(&conn->sock, url->host, url->port);
+ if (status != HSOCKET_OK) {
+ log_error3("Can not open connection to '%s' (status:%d)",
+ SAVE_STR(url->host), status);
+ return 3;
+ }
+
+ /* Send GET */
+ sprintf(buffer, "GET %s HTTP/1.1\r\n",
+ (url->context)?url->context:("/"));
+ status = hsocket_send(conn->sock, buffer);
+ if (status != HSOCKET_OK) {
+ log_error2("Can not send GET (status:%d)", status);
+ hsocket_close(conn->sock);
+ return 4;
+ }
+
+ /* Send Header */
+ status = httpc_send_header(conn);
+ if (status != HSOCKET_OK) {
+ log_error2("Can not send header (status:%d)", status);
+ hsocket_close(conn->sock);
+ return 5;
+ }
+
+ /* Receive Response */
+
+ status = hsocket_recv_limit(conn->sock, &response,
+ "\r\n\r\n", &rest, &rsize, &restsize);
+ if (status != HSOCKET_OK) {
+ log_error2("Can not receive response (status:%d)", status);
+ return NULL;
+ }
+
+ res = hresponse_new(response);
+ if (res == NULL) {
+ log_error2("Can't create response (url:'%s')", urlstr);
+ return 6;
+ }
+
+ /* Invoke callback */
+ start_cb(conn, userdata, res->header, res->spec, res->errcode, res->desc);
+
+ /* Invoke callback for rest */
+ cb(0, conn, userdata, restsize, rest);
+
+ /* rest and response are no longer required */
+ free(rest);
+ free(response);
+
+ /* Invoke with callback */
+ cbdata.conn = conn;
+ cbdata.userdata = userdata;
+ cbdata.callback = cb;
+ cbdata.counter = 1;
+
+ hsocket_recv_cb(conn->sock, httpc_recv_cb_callback, &cbdata);
+
+ return 0;
+}
+
+
+/*--------------------------------------------------
+ FUNCTION: httpc_post_cb
+----------------------------------------------------*/
+int httpc_post_cb(httpc_conn_t *conn, const char *url,
+ httpc_response_start_callback start_cb,
+ httpc_response_callback cb, void *userdata)
+{
+ return 1;
+}
+
+
+
+
+
+
diff --git a/nanohttp/nanohttp-client.h b/nanohttp/nanohttp-client.h
new file mode 100644
index 0000000..60abc57
--- /dev/null
+++ b/nanohttp/nanohttp-client.h
@@ -0,0 +1,88 @@
+/******************************************************************
+ * $Id: nanohttp-client.h,v 1.1 2003/12/11 14:51:04 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_CLIENT_H
+#define NANO_HTTP_CLIENT_H
+
+
+#include <nanohttp/nanohttp-common.h>
+#include <nanohttp/nanohttp-socket.h>
+
+
+typedef struct httpc_conn
+{
+ hsocket_t sock;
+ hpair_t *header;
+ hurl_t *url;
+}httpc_conn_t;
+
+/*
+ PROTOTYPE:
+ void my_callback(int counter, httpc_conn_t* conn,
+ void *userdata, int size, char *buffer)
+ */
+typedef void (*httpc_response_callback)(int, httpc_conn_t*, void*,int,char*);
+
+/*
+ void my_start_callback(httpc_conn_t *conn, void *userdata,
+ hpair_t *header, const char *spec,
+ int errcode, const char *desc)
+ */
+typedef void (*httpc_response_start_callback)(httpc_conn_t*, void*, hpair_t*,
+ const char*, int, const char*);
+
+httpc_conn_t* httpc_new();
+void httpc_free(httpc_conn_t* conn);
+
+void httpc_add_header(httpc_conn_t *conn, const char* key, const char* value);
+int httpc_set_header(httpc_conn_t *conn, const char* key, const char* value);
+
+hresponse_t *httpc_get(httpc_conn_t *conn, const char *url);
+hresponse_t *httpc_post(httpc_conn_t *conn, const char *url, const char *content);
+
+int httpc_get_cb(httpc_conn_t *conn, const char *url,
+ httpc_response_start_callback start_cb,
+ httpc_response_callback cb, void *userdata);
+
+int httpc_post_cb(httpc_conn_t *conn, const char *url,
+ httpc_response_start_callback start_cb,
+ httpc_response_callback cb, void *userdata);
+
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nanohttp/nanohttp-common.c b/nanohttp/nanohttp-common.c
new file mode 100644
index 0000000..9efe0ac
--- /dev/null
+++ b/nanohttp/nanohttp-common.c
@@ -0,0 +1,357 @@
+/******************************************************************
+ * $Id: nanohttp-common.c,v 1.1 2003/12/11 14:51:04 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-common.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+
+static log_level_t loglevel = HLOG_DEBUG;
+
+log_level_t log_set_level(log_level_t level)
+{
+ log_level_t old = loglevel;
+ loglevel = level;
+ return old;
+}
+
+
+log_level_t log_get_level()
+{
+ return loglevel;
+}
+
+
+static
+void log_write(log_level_t level, const char *prefix,
+ const char* func, const char *format, va_list ap)
+{
+ char buffer[1054];
+ char buffer2[1054];
+
+ if (level < loglevel) return;
+
+ sprintf(buffer, "*%s*: [%s] %s\n", prefix, func, format);
+ vsprintf(buffer2, buffer, ap);
+ printf(buffer2);
+ fflush(stdout);
+}
+
+void log_debug(const char* FUNC, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ log_write(HLOG_DEBUG, "DEBUG", FUNC, format, ap);
+ va_end(ap);
+}
+
+void log_info(const char* FUNC, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ log_write(HLOG_INFO, "INFO", FUNC, format, ap);
+ va_end(ap);
+}
+
+void log_warn(const char* FUNC, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ log_write(HLOG_WARN, "WARN", FUNC, format, ap);
+ va_end(ap);
+}
+
+void log_error(const char* FUNC, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ log_write(HLOG_ERROR, "ERROR", FUNC, format, ap);
+ va_end(ap);
+}
+
+
+hpair_t *hpairnode_new(const char* key, const char* value, hpair_t *next)
+{
+ hpair_t *pair;
+
+ pair = (hpair_t*)malloc(sizeof(hpair_t));
+ pair->key = (char*)malloc(strlen(key)+1);
+ pair->value = (char*)malloc(strlen(value)+1);
+ pair->next = next;
+
+ strcpy(pair->key, key);
+ strcpy(pair->value, value);
+
+ return pair;
+}
+
+hpair_t *hpairnode_parse(const char *str, const char *delim, hpair_t *next)
+{
+ hpair_t *pair;
+ char *key, *value;
+
+ pair = (hpair_t*)malloc(sizeof(hpair_t));
+ pair->key = "";
+ pair->value = "";
+ pair->next = next;
+
+ key = strtok_r(str, delim, &value);
+
+ if (key != NULL) {
+ pair->key = (char*)malloc(strlen(key)+1);
+ strcpy(pair->key, key);
+ }
+
+ if (value != NULL) {
+ pair->value = (char*)malloc(strlen(value)+1);
+ strcpy(pair->value, value);
+ }
+
+ return pair;
+}
+
+void hpairnode_free(hpair_t *pair)
+{
+ if (pair == NULL) return;
+
+ free(pair->key);
+ free(pair->value);
+
+ free(pair);
+}
+
+
+static
+void hurl_dump(const hurl_t *url)
+{
+ const char *FUNC = "hurl_dump";
+
+ if (url == NULL) {
+ printf("(null)\n");
+ return ;
+ }
+
+ log_debug(FUNC, "PROTOCOL : %s", url->protocol?url->protocol:"(null)");
+ log_debug(FUNC, " HOST : %s", url->host?url->host:"(null)");
+ log_debug(FUNC, " PORT : %d", url->port);
+ log_debug(FUNC, " CONTEXT : %s", url->context?url->context:"(null)");
+}
+
+
+hurl_t* hurl_new(const char* urlstr)
+{
+ int iprotocol;
+ int ihost;
+ int iport;
+ int len;
+ int size;
+ hurl_t *url;
+ char tmp[8];
+ const char *FUNC = "hurl_create";
+
+ iprotocol = 0;
+ len = strlen(urlstr);
+
+ /* find protocol */
+ while (urlstr[iprotocol] != ':' && urlstr[iprotocol] != '\0')
+ {
+ iprotocol++;
+ }
+
+ if (iprotocol == 0) {
+ log_error(FUNC, "no protocol");
+ return NULL;
+ }
+
+ if (iprotocol + 3 >= len) {
+ log_error(FUNC, "no host");
+ return NULL;
+ }
+
+ if ( urlstr[iprotocol] != ':'
+ && urlstr[iprotocol+1] != '/'
+ && urlstr[iprotocol+2] != '/')
+ {
+ log_error(FUNC, "no protocol");
+ return NULL;
+ }
+
+ /* find host */
+ ihost = iprotocol + 3;
+ while (urlstr[ihost] != ':'
+ && urlstr[ihost] != '/'
+ && urlstr[ihost] != '\0')
+ {
+ ihost++;
+ }
+
+ if (ihost == iprotocol + 1) {
+ log_error(FUNC, "no host");
+ return NULL;
+ }
+
+ /* find port */
+ iport = ihost;
+ if (ihost + 1 < len) {
+ if (urlstr[ihost] == ':') {
+ while (urlstr[iport] != '/' && urlstr[iport] != '\0') {
+ iport++;
+ }
+ }
+ }
+
+ url = (hurl_t*)malloc(sizeof(hurl_t));
+
+ url->protocol = (char*)malloc(sizeof(char)*iprotocol+1);
+ strncpy(url->protocol, urlstr, iprotocol);
+ url->protocol[iprotocol] = '\0';
+
+ size = ihost - iprotocol - 3;
+ url->host = (char*)malloc(sizeof(char)*size);
+ strncpy(url->host, &urlstr[iprotocol+3], size);
+ url->host[size] = '\0';
+
+ if (iport > ihost)
+ {
+ size = iport - ihost;
+ strncpy(tmp, &urlstr[ihost+1], size);
+ url->port = atoi(tmp);
+ } else {
+ url->port = 80;
+ }
+
+ len = strlen(urlstr);
+ if (len > iport )
+ {
+ size = len - iport;
+ url->context = (char*)malloc(sizeof(char)*size+1);
+ strncpy(url->context, &urlstr[iport], size);
+ url->context[size]='\0';
+ } else {
+ url->context = NULL;
+ }
+
+ hurl_dump(url);
+
+ return url;
+}
+
+
+void hurl_free(hurl_t *url)
+{
+ if (url == NULL) return;
+
+ free(url->protocol);
+ free(url->host);
+ free(url->context);
+
+ free(url);
+}
+
+
+/* response stuff */
+
+/* -------------------------------------------
+ FUNCTION: hresponse_new
+ ---------------------------------------------*/
+hresponse_t *hresponse_new(const char* buffer)
+{
+ hresponse_t *res;
+ char *s1, *s2, *str;
+ hpair_t *pair;
+
+ const char *FUNC = "hresponse_new";
+
+ /* create response object */
+ res = (hresponse_t*)malloc(sizeof(hresponse_t));
+ res->desc = "";
+ res->header = NULL;
+ res->body = "";
+
+ /* *** parse spec *** */
+ /* [HTTP/1.1 | 1.2] [CODE] [DESC] */
+
+ /* stage 1: HTTP spec */
+ str = (char*)strtok_r(buffer, " ", &s2);
+ s1 = s2;
+ if (str == NULL) { log_error(FUNC, "Parse error"); return NULL; }
+
+ strncpy(res->spec, str, 10);
+
+ /* stage 2: http code */
+ str = (char*)strtok_r(s1, " ", &s2);
+ s1 = s2;
+ if (str == NULL) { log_error(FUNC, "Parse error"); return NULL; }
+
+ res->errcode = atoi(str);
+
+ /* stage 3: description text */
+ str = (char*)strtok_r(s1, "\r\n", &s2);
+ s1 = s2;
+ if (str == NULL) { log_error(FUNC, "Parse error"); return NULL; }
+
+ res->desc = (char*)malloc(strlen(str)+1);
+ strcpy(res->desc, str);
+ res->desc[strlen(str)] = '\0';
+
+ /* *** parse header *** */
+ /* [key]: [value] */
+ for (;;) {
+ str = strtok_r(s1, "\n", &s2);
+ s1 = s2;
+
+ /* check if header ends without body */
+ if (str == NULL) {
+ return res;
+ }
+
+ /* check also for end of header */
+ if (!strcmp(str, "\r")) {
+ break;
+ }
+
+ str[strlen(str)-1] = '\0';
+ res->header = hpairnode_parse(str, ": ", res->header);
+ }
+
+ /* *** Save body *** */
+ res->body = s1;
+
+ /* return response object */
+ return res;
+}
+
+
+void hresponse_free(hresponse_t *res)
+{
+ /* not implemented yet!*/
+}
+
+
diff --git a/nanohttp/nanohttp-common.h b/nanohttp/nanohttp-common.h
new file mode 100644
index 0000000..d3bb702
--- /dev/null
+++ b/nanohttp/nanohttp-common.h
@@ -0,0 +1,142 @@
+/******************************************************************
+ * $Id: nanohttp-common.h,v 1.1 2003/12/11 14:51:04 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_COMMON_H
+#define NANO_HTTP_COMMON_H
+
+
+#define HEADER_CONTENT_LENGTH "Content-Length"
+#define HEADER_CONTENT_TYPE "Content-Type"
+#define HEADER_HOST "Host"
+#define HEADER_DATE "Date"
+
+
+#ifndef SAVE_STR
+#define SAVE_STR(str) ((str==0)?("(null)"):(str))
+#endif
+
+/*
+ hpairnode_t represents a pair (key, value) pair.
+ This is also a linked list.
+ */
+typedef struct hpair hpair_t;
+struct hpair
+{
+ char *key;
+ char *value;
+ hpair_t *next;
+};
+
+
+hpair_t *hpairnode_new(const char* key, const char* value, hpair_t* next);
+void hpairnode_free(hpair_t *pair);
+
+
+
+typedef enum hreq_method
+{
+ HTTP_REQUESET_POST,
+ HTTP_REQUESET_GET
+}hreq_method ;
+
+
+typedef struct hurl
+{
+ char *protocol;
+ char *host;
+ int port;
+ char *context;
+}hurl_t;
+
+
+hurl_t* hurl_new(const char* urlstr);
+void hurl_free(hurl_t *url);
+
+
+/* response object */
+
+typedef struct hresponse
+{
+ char spec[10];
+ int errcode;
+ char *desc;
+ hpair_t *header;
+ char *body;
+}hresponse_t;
+
+/*
+ PARAMS
+ buffer: The hole received data from socket.
+ */
+hresponse_t *hresponse_new(const char* buffer);
+void hresponse_free(hresponse_t *res);
+
+/* logging stuff*/
+typedef enum log_level
+{
+ HLOG_DEBUG,
+ HLOG_INFO,
+ HLOG_WARN,
+ HLOG_ERROR,
+ HLOG_FATAL
+}log_level_t;
+
+log_level_t log_set_level(log_level_t level);
+log_level_t log_get_level();
+
+#define log_debug1(a1) log_debug(__FUNCTION__, a1)
+#define log_debug2(a1,a2) log_debug(__FUNCTION__, a1,a2)
+#define log_debug3(a1,a2,a3) log_debug(__FUNCTION__, a1,a2,a3)
+#define log_debug4(a1,a2,a3,a4) log_debug(__FUNCTION__, a1,a2,a3,a4)
+#define log_debug5(a1,a2,a3,a4,a5) log_debug(__FUNCTION__, a1,a2,a3,a4,a5)
+
+#define log_info1(a1) log_info(__FUNCTION__, a1)
+#define log_info2(a1,a2) log_info(__FUNCTION__, a1,a2)
+#define log_info3(a1,a2,a3) log_info(__FUNCTION__, a1,a2,a3)
+#define log_info4(a1,a2,a3,a4) log_info(__FUNCTION__, a1,a2,a3,a4)
+#define log_info5(a1,a2,a3,a4,a5) log_info(__FUNCTION__, a1,a2,a3,a4,a5)
+
+#define log_warn1(a1) log_warn(__FUNCTION__, a1)
+#define log_warn2(a1,a2) log_warn(__FUNCTION__, a1,a2)
+#define log_warn3(a1,a2,a3) log_warn(__FUNCTION__, a1,a2,a3)
+#define log_warn4(a1,a2,a3,a4) log_warn(__FUNCTION__, a1,a2,a3,a4)
+#define log_warn5(a1,a2,a3,a4,a5) log_warn(__FUNCTION__, a1,a2,a3,a4,a5)
+
+#define log_error1(a1) log_error(__FUNCTION__, a1)
+#define log_error2(a1,a2) log_error(__FUNCTION__, a1,a2)
+#define log_error3(a1,a2,a3) log_error(__FUNCTION__, a1,a2,a3)
+#define log_error4(a1,a2,a3,a4) log_error(__FUNCTION__, a1,a2,a3,a4)
+#define log_error5(a1,a2,a3,a4,a5) log_error(__FUNCTION__, a1,a2,a3,a4,a5)
+
+void log_debug(const char* FUNC, const char *format, ...);
+void log_info(const char* FUNC, const char *format, ...);
+void log_warn(const char* FUNC, const char *format, ...);
+void log_error(const char* FUNC, const char *format, ...);
+
+#endif
+
+
+
+
+
+
diff --git a/nanohttp/nanohttp-socket.c b/nanohttp/nanohttp-socket.c
new file mode 100644
index 0000000..1a9742b
--- /dev/null
+++ b/nanohttp/nanohttp-socket.c
@@ -0,0 +1,324 @@
+/******************************************************************
+ * $Id: nanohttp-socket.c,v 1.1 2003/12/11 14:51:04 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 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>
+
+
+/*--------------------------------------------------
+ FUNCTION: hsocket_module_init
+----------------------------------------------------*/
+int hsocket_module_init()
+{
+ /* nothing to init for unix sockets */
+ return 0;
+}
+
+/*--------------------------------------------------
+ FUNCTION: hsocket_module_destroy
+----------------------------------------------------*/
+void hsocket_module_destroy()
+{
+ /* nothing to destroy for unix sockets */
+}
+
+
+/*--------------------------------------------------
+ FUNCTION: hsocket_init
+----------------------------------------------------*/
+int hsocket_init(hsocket_t *sock)
+{
+ /* nothing to init for unix sockets */
+ /* 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)
+{
+ int sock;
+ struct sockaddr_in address;
+ struct hostent* host;
+
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock <= 0) return HSOCKET_CAN_NOT_CREATE_SOCKET;
+
+ /* Get host data */
+ host = gethostbyname(hostname);
+ if (host == NULL) return HSOCKET_CAN_NOT_GET_HOSTNAME;
+
+ /* set server addresss */
+ address.sin_family = host->h_addrtype;
+ address.sin_port = htons(port);
+ memcpy((char*)&address.sin_addr.s_addr,
+ host->h_addr_list[0], host->h_length);
+
+ /* 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_close
+----------------------------------------------------*/
+void hsocket_close(hsocket_t sock)
+{
+ close(sock);
+}
+
+
+/*--------------------------------------------------
+ FUNCTION: hsocket_send
+----------------------------------------------------*/
+int hsocket_send(hsocket_t sock, const char* buffer)
+{
+ int size;
+
+ size = send((int)sock, buffer, strlen(buffer), 0);
+ if (size == -1)
+ return HSOCKET_CAN_NOT_SEND;
+
+ return HSOCKET_OK;
+}
+
+
+/*--------------------------------------------------
+ FUNCTION: hsocket_recv_limit (DON'T USE!)
+----------------------------------------------------*/
+int hsocket_recv_limit(hsocket_t sock, char** buffer,
+ const char* delim, char **rest,
+ int *totalBuffer, int *totalRest)
+{
+ ssize_t size;
+ int chunk=1;
+ char tmp[HSOCKET_MAX_BUFSIZE+1];
+ int delimlen;
+ int fsize;
+ int i;
+
+ *totalBuffer = 0;
+ *totalRest = 0;
+ delimlen = strlen(delim);
+
+ /* calculate first size for realloc */
+ if (*buffer) {
+ fsize = strlen(*buffer);
+ } else {
+ fsize = 0;
+ }
+
+ do {
+
+ size = recv(sock, tmp, HSOCKET_MAX_BUFSIZE, 0);
+
+ if (size == -1) {
+ log_error1("Error reading from socket\n");
+ return HSOCKET_CAN_NOT_RECEIVE;
+ }
+
+ if (size == 0) {
+ break;
+ }
+
+ /* section 1: find delimiter if exist */
+ for (i=0;i<size-delimlen;i++) {
+ if (!strncmp(&tmp[i],delim,delimlen)) {
+
+ /* ** split to buffer and rest ** */
+
+ /* fill buffer until i */
+ *totalBuffer += i;
+ if (*buffer) {
+ *buffer = (char*)realloc(*buffer, *totalBuffer+fsize+1+HSOCKET_MAX_BUFSIZE);
+ strncat(*buffer, tmp, i);
+ *buffer[*totalBuffer+fsize] = '\0';
+ } else {
+ *buffer = (char*)realloc(NULL, *totalBuffer+1);
+ strncpy(*buffer, tmp, i);
+ (*buffer)[*totalBuffer] = '\0';
+ }
+
+
+ /* fill rest from i to size */
+ if (size - (i+delimlen)+1 > 0) {
+ *rest = (char*)realloc(NULL, size - (i+delimlen)+1 + HSOCKET_MAX_BUFSIZE);
+ strcpy(*rest, &tmp[i+delimlen]);
+ *totalRest = size - (i+delimlen);
+ (*rest)[*totalRest] = '\0';
+ } else {
+ *rest = NULL;
+ }
+
+ return HSOCKET_OK;
+ }
+ }
+
+ /* section 2: no delimiter found. so add tmp to buffer */
+ *totalBuffer += size;
+ if (*buffer) {
+ *buffer = (char*)realloc(*buffer, *totalBuffer+fsize+1);
+ strcat(*buffer, tmp);
+ } else {
+ *buffer = (char*)realloc(NULL, *totalBuffer+1);
+ strcpy(*buffer, tmp);
+ }
+
+ (*buffer)[*totalBuffer] = '\0';
+
+ chunk++;
+ } while (size > 0);
+
+ return HSOCKET_OK;
+}
+
+/*--------------------------------------------------
+ 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;
+
+ *totalSize = 0;
+
+ /* calculate first size for realloc */
+ if (*buffer) {
+ fsize = strlen(*buffer);
+ } else {
+ fsize = 0;
+ }
+
+ do {
+
+ size = recv(sock, tmp, HSOCKET_MAX_BUFSIZE, 0);
+
+ if (size == -1) {
+ log_error1("Error reading from socket\n");
+ return HSOCKET_CAN_NOT_RECEIVE;
+ }
+
+ if (size == 0) {
+ break;
+ }
+
+ *totalSize += size;
+ if (*buffer) {
+ log_debug2("reallocation %d bytes",*totalSize+fsize+1);
+ *buffer = (char*)realloc((char*)*buffer, (*totalSize)+fsize+HSOCKET_MAX_BUFSIZE);
+ strcat(*buffer, tmp);
+ } else {
+ log_debug1("Allocating");
+ *buffer = (char*)realloc(NULL, *totalSize+1);
+ strcpy(*buffer, tmp);
+ }
+
+ log_debug1("Assigning");
+ (*buffer)[*totalSize+fsize] = '\0';
+ chunk++;
+ } while (size > 0);
+
+ log_debug1("Returning");
+ 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\n");
+ 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;
+}
+
+
+
diff --git a/nanohttp/nanohttp-socket.h b/nanohttp/nanohttp-socket.h
new file mode 100644
index 0000000..92e92e2
--- /dev/null
+++ b/nanohttp/nanohttp-socket.h
@@ -0,0 +1,138 @@
+/******************************************************************
+ * $Id: nanohttp-socket.h,v 1.1 2003/12/11 14:51:04 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_SOCKET 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_MAX_BUFSIZE 1024
+
+typedef int hsocket_t;
+
+/*
+ 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
+ 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_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);
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nanohttp/readme.txt b/nanohttp/readme.txt
new file mode 100644
index 0000000..b0e04be
--- /dev/null
+++ b/nanohttp/readme.txt
@@ -0,0 +1,2 @@
+nanohttp is a http client/server library
+