summaryrefslogtreecommitdiffstats
path: root/nanohttp/nanohttp-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'nanohttp/nanohttp-common.c')
-rw-r--r--nanohttp/nanohttp-common.c357
1 files changed, 357 insertions, 0 deletions
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!*/
+}
+
+