summaryrefslogtreecommitdiffstats
path: root/nanohttp
diff options
context:
space:
mode:
Diffstat (limited to 'nanohttp')
-rw-r--r--nanohttp/Makefile.am8
-rw-r--r--nanohttp/nanohttp-client.c27
-rw-r--r--nanohttp/nanohttp-client.h125
-rw-r--r--nanohttp/nanohttp-common.c164
-rw-r--r--nanohttp/nanohttp-common.h169
-rw-r--r--nanohttp/nanohttp-url.c184
-rw-r--r--nanohttp/nanohttp-url.h120
7 files changed, 496 insertions, 301 deletions
diff --git a/nanohttp/Makefile.am b/nanohttp/Makefile.am
index f52cce0..04933d3 100644
--- a/nanohttp/Makefile.am
+++ b/nanohttp/Makefile.am
@@ -1,5 +1,5 @@
#
-# $Revision: 1.15 $
+# $Revision: 1.16 $
#
lib_LTLIBRARIES=libnanohttp.la
@@ -8,12 +8,14 @@ libnanohttp_ladir=$(includedir)/nanohttp-@nanohttp_release@/nanohttp
libnanohttp_la_SOURCES=nanohttp-common.c nanohttp-socket.c nanohttp-client.c \
nanohttp-server.c nanohttp-stream.c nanohttp-mime.c \
nanohttp-request.c nanohttp-response.c nanohttp-base64.c \
- nanohttp-logging.c nanohttp-admin.c nanohttp-error.c
+ nanohttp-logging.c nanohttp-admin.c nanohttp-error.c \
+ nanohttp-url.c
libnanohttp_la_HEADERS=nanohttp-common.h nanohttp-socket.h nanohttp-client.h \
nanohttp-server.h nanohttp-stream.h nanohttp-mime.h \
nanohttp-request.h nanohttp-response.h nanohttp-logging.h \
- nanohttp-error.h nanohttp-base64.h nanohttp-admin.h
+ nanohttp-error.h nanohttp-base64.h nanohttp-admin.h \
+ nanohttp-url.h
if BUILD_WITH_SSL
libnanohttp_la_SOURCES+=nanohttp-ssl.c
diff --git a/nanohttp/nanohttp-client.c b/nanohttp/nanohttp-client.c
index 53aba83..e4a0337 100644
--- a/nanohttp/nanohttp-client.c
+++ b/nanohttp/nanohttp-client.c
@@ -1,5 +1,5 @@
/******************************************************************
-* $Id: nanohttp-client.c,v 1.49 2006/12/02 21:50:47 m0gg Exp $
+* $Id: nanohttp-client.c,v 1.50 2006/12/08 21:21:41 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -73,6 +73,7 @@
#include "nanohttp-request.h"
#include "nanohttp-response.h"
#include "nanohttp-base64.h"
+#include "nanohttp-url.h"
#include "nanohttp-client.h"
herror_t
@@ -109,6 +110,14 @@ httpc_new(void)
return NULL;
}
+ if (!(res->url = (struct hurl_t *)malloc(sizeof(struct hurl_t))))
+ {
+ log_error2("malloc failed (%s)", strerror(errno));
+ free(res->sock);
+ free(res);
+ return NULL;
+ }
+
if ((status = hsocket_init(res->sock)) != H_OK)
{
log_warn2("hsocket_init failed (%s)", herror_message(status));
@@ -146,6 +155,8 @@ httpc_free(httpc_conn_t * conn)
}
hsocket_free(conn->sock);
+ hurl_free(conn->url);
+
free(conn->sock);
free(conn);
@@ -352,8 +363,6 @@ static herror_t
_httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn,
const char *urlstr)
{
-
- hurl_t url;
char buffer[4096];
herror_t status;
int ssl;
@@ -366,7 +375,7 @@ _httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn,
/* Build request header */
httpc_header_set_date(conn);
- if ((status = hurl_parse(&url, urlstr)) != H_OK)
+ if ((status = hurl_parse(conn->url, urlstr)) != H_OK)
{
log_error2("Can not parse URL '%s'", SAVE_STR(urlstr));
return status;
@@ -374,12 +383,12 @@ _httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn,
/* TODO (#1#): Check for HTTP protocol in URL */
/* Set hostname */
- httpc_set_header(conn, HEADER_HOST, url.host);
+ httpc_set_header(conn, HEADER_HOST, conn->url->host);
- ssl = url.protocol == PROTOCOL_HTTPS ? 1 : 0;
+ ssl = conn->url->protocol == PROTOCOL_HTTPS ? 1 : 0;
/* Open connection */
- if ((status = hsocket_open(conn->sock, url.host, url.port, ssl)) != H_OK)
+ if ((status = hsocket_open(conn->sock, conn->url->host, conn->url->port, ssl)) != H_OK)
return status;
switch(method)
@@ -387,14 +396,14 @@ _httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn,
case HTTP_REQUEST_GET:
sprintf(buffer, "GET %s HTTP/%s\r\n",
- (url.context[0] != '\0') ? url.context : ("/"),
+ (conn->url->context[0] != '\0') ? conn->url->context : ("/"),
(conn->version == HTTP_1_0) ? "1.0" : "1.1");
break;
case HTTP_REQUEST_POST:
sprintf(buffer, "POST %s HTTP/%s\r\n",
- (url.context[0] != '\0') ? url.context : ("/"),
+ (conn->url->context[0] != '\0') ? conn->url->context : ("/"),
(conn->version == HTTP_1_0) ? "1.0" : "1.1");
break;
diff --git a/nanohttp/nanohttp-client.h b/nanohttp/nanohttp-client.h
index 69807f7..72cba96 100644
--- a/nanohttp/nanohttp-client.h
+++ b/nanohttp/nanohttp-client.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: nanohttp-client.h,v 1.29 2006/12/02 21:50:47 m0gg Exp $
+ * $Id: nanohttp-client.h,v 1.30 2006/12/08 21:21:41 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -34,11 +34,132 @@
#include <nanohttp/nanohttp-logging.h>
#endif
+/** @file
+ *
+ * Writing an HTTP client using nanoHTTP
+ *
+ * - Client initialization
+ * - Connection initialization
+ * -- SSL related functions
+ * - Setting HTTP headers (optional)
+ * -- Setting an HTTP header with uniq key
+ * -- Setting multiple headers
+ * - Fetch the network resource
+ * -- HTTP GET command
+ * -- HTTP POST command
+ * -- MIME attachments
+ * - Print out the result
+ * - Connection cleanup
+ * - Client cleanup
+ *
+ * Client initialization
+ *
+ * int main(int argc, char **argv)
+ * {
+ * herror_t status;
+ * size_t len;
+ * httpc_conn_t conn;
+ *
+ * if (argc < 2)
+ * {
+ * fprintf(stderr, "usage: %s <url> [nanoHTTP params]\n", argv[0]);
+ * exit(1);
+ * }
+ *
+ * if ((status = httpc_init(argc, argv)) != H_OK)
+ * {
+ * fprintf(stderr, "Cannot init nanoHTTP client (%s)\n", herror_message(status));
+ * herror_release(status);
+ * exit(1);
+ * }
+ *
+ * Connection initialization
+ *
+ * if (!(conn = httpc_new()))
+ * {
+ * fprintf(stderr, "Cannot create nanoHTTP client connection\n");
+ * httpc_destroy();
+ * exit(1);
+ * }
+ *
+ * SSL related functions
+ *
+ * T.B.D.
+ *
+ * Setting HTTP headers (optional)
+ *
+ * httpc_set_header(conn, "my-key", "my-value");
+ *
+ * httpc_add_header(conn, "Cookie", "name1:value1");
+ * httpc_add_header(conn, "Cookie", "name2:value2");
+ *
+ * Fetch the network resource
+ *
+ * HTTP GET command
+ *
+ * if ((status = httpc_get(conn, &result, argv[1])) != H_OK)
+ * {
+ * fprintf(stderr, "nanoHTTP client connection failed (%s)\n", herror_message(status));
+ * herror_release(status);
+ * httpc_destroy();
+ * exit(1);
+ * }
+ *
+ * HTTP POST command
+ *
+ * if ((status = httpc_post_begin(conn, argv[1])) != H_OK)
+ * {
+ * fprintf(stderr, "nanoHTTP client connection failed (%s)\n", herror_message(status));
+ * herror_release(status);
+ * httpc_destroy();
+ * exit(1);
+ * }
+ *
+ * if ((status = http_output_stream_write(conn->out, buffer, len)) != H_OK)
+ * {
+ * fprintf(stderr, "nanoHTTP client sending POST data failed (%s)\n", herror_message(status));
+ * herror_release(status);
+ * httpc_destroy();
+ * exit(1);
+ * }
+ *
+ * if ((status = httpc_post_end(conn, &result)) != H_OK)
+ * {
+ * fprintf(stderr, "nanoHTTP client POST failed (%s)\n", herror_message(status));
+ * herror_release(status);
+ * httpc_destroy();
+ * exit(1);
+ * }
+ *
+ * MIME attachments
+ *
+ * T.B.D.
+ *
+ * Print out the result
+ *
+ * while (http_input_stream_is_read(res->in))
+ * {
+ * len = http_input_stream_read(res->in, buffer, MAX_BUFFER_SIZE);
+ * fwrite(buffer, len, 1, stdout);
+ * }
+ *
+ * Connection cleanup
+ *
+ * hresponse_free(res);
+ *
+ * Client cleanup
+ *
+ * httpc_free(conn);
+ *
+ * }
+ *
+ */
+
typedef struct httpc_conn
{
struct hsocket_t *sock;
hpair_t *header;
- hurl_t url;
+ struct hurl_t *url;
http_version_t version;
int errcode;
diff --git a/nanohttp/nanohttp-common.c b/nanohttp/nanohttp-common.c
index 212de01..1d22eed 100644
--- a/nanohttp/nanohttp-common.c
+++ b/nanohttp/nanohttp-common.c
@@ -1,5 +1,5 @@
/******************************************************************
-* $Id: nanohttp-common.c,v 1.33 2006/11/25 15:06:58 m0gg Exp $
+* $Id: nanohttp-common.c,v 1.34 2006/12/08 21:21:41 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003 Ferhat Ayaz
@@ -57,29 +57,6 @@
#include "nanohttp-error.h"
#include "nanohttp-common.h"
-static int
-strcmpigcase(const char *s1, const char *s2)
-{
- int l1, l2, i;
-
- if (s1 == NULL && s2 == NULL)
- return 1;
- if (s1 == NULL || s2 == NULL)
- return 0;
-
- l1 = strlen(s1);
- l2 = strlen(s2);
-
- if (l1 != l2)
- return 0;
-
- for (i = 0; i < l1; i++)
- if (toupper(s1[i]) != toupper(s2[i]))
- return 0;
-
- return 1;
-}
-
hpair_t *
hpairnode_new(const char *key, const char *value, hpair_t * next)
{
@@ -260,7 +237,7 @@ hpairnode_get_ignore_case(hpair_t * pair, const char *key)
{
if (pair->key != NULL)
{
- if (strcmpigcase(pair->key, key))
+ if (strcasecmp(pair->key, key))
{
return pair->value;
}
@@ -294,143 +271,6 @@ hpairnode_get(hpair_t * pair, const char *key)
return NULL;
}
-static void
-hurl_dump(const hurl_t * url)
-{
-
- if (url == NULL)
- {
- log_error1("url is NULL!");
- return;
- }
- log_verbose2("PROTOCOL : %d", url->protocol);
- log_verbose2(" HOST : %s", url->host);
- log_verbose2(" PORT : %d", url->port);
- log_verbose2(" CONTEXT : %s", url->context);
-}
-
-herror_t
-hurl_parse(hurl_t * url, const char *urlstr)
-{
- int iprotocol;
- int ihost;
- int iport;
- int len;
- int size;
- char tmp[8];
- char protocol[1024];
-
- iprotocol = 0;
- len = strlen(urlstr);
-
- /* find protocol */
- while (urlstr[iprotocol] != ':' && urlstr[iprotocol] != '\0')
- {
- iprotocol++;
- }
-
- if (iprotocol == 0)
- {
- log_error1("no protocol");
- return herror_new("hurl_parse", URL_ERROR_NO_PROTOCOL, "No protocol");
- }
- if (iprotocol + 3 >= len)
- {
- log_error1("no host");
- return herror_new("hurl_parse", URL_ERROR_NO_HOST, "No host");
- }
- if (urlstr[iprotocol] != ':'
- && urlstr[iprotocol + 1] != '/' && urlstr[iprotocol + 2] != '/')
- {
- log_error1("no protocol");
- return herror_new("hurl_parse", URL_ERROR_NO_PROTOCOL, "No protocol");
- }
- /* find host */
- ihost = iprotocol + 3;
- while (urlstr[ihost] != ':'
- && urlstr[ihost] != '/' && urlstr[ihost] != '\0')
- {
- ihost++;
- }
-
- if (ihost == iprotocol + 1)
- {
- log_error1("no host");
- return herror_new("hurl_parse", URL_ERROR_NO_HOST, "No host");
- }
- /* find port */
- iport = ihost;
- if (ihost + 1 < len)
- {
- if (urlstr[ihost] == ':')
- {
- while (urlstr[iport] != '/' && urlstr[iport] != '\0')
- {
- iport++;
- }
- }
- }
-
- /* find protocol */
- strncpy(protocol, urlstr, iprotocol);
- protocol[iprotocol] = '\0';
- if (strcmpigcase(protocol, "http"))
- url->protocol = PROTOCOL_HTTP;
- else if (strcmpigcase(protocol, "https"))
- url->protocol = PROTOCOL_HTTPS;
- else if (strcmpigcase(protocol, "ftp"))
- url->protocol = PROTOCOL_FTP;
- else
- return herror_new("hurl_parse",
- URL_ERROR_UNKNOWN_PROTOCOL, "Unknown protocol '%s'",
- protocol);
-
- /* TODO (#1#): add max of size and URL_MAX_HOST_SIZE */
- size = ihost - iprotocol - 3;
- 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
- {
- switch (url->protocol)
- {
- case PROTOCOL_HTTP:
- url->port = URL_DEFAULT_PORT_HTTP;
- break;
- case PROTOCOL_HTTPS:
- url->port = URL_DEFAULT_PORT_HTTPS;
- break;
- case PROTOCOL_FTP:
- url->port = URL_DEFAULT_PORT_FTP;
- break;
- }
- }
-
- len = strlen(urlstr);
- if (len > iport)
- {
- /* TODO (#1#): find max of size and URL_MAX_CONTEXT_SIZE */
- size = len - iport;
- strncpy(url->context, &urlstr[iport], size);
- url->context[size] = '\0';
- }
- else
- {
- url->context[0] = '\0';
- }
-
- hurl_dump(url);
-
- return H_OK;
-}
-
-
/* Content-type stuff */
content_type_t *
diff --git a/nanohttp/nanohttp-common.h b/nanohttp/nanohttp-common.h
index ad00750..5b6ac36 100644
--- a/nanohttp/nanohttp-common.h
+++ b/nanohttp/nanohttp-common.h
@@ -1,5 +1,5 @@
/******************************************************************
- * $Id: nanohttp-common.h,v 1.38 2006/11/26 20:13:05 m0gg Exp $
+ * $Id: nanohttp-common.h,v 1.39 2006/12/08 21:21:41 m0gg Exp $
*
* CSOAP Project: A http client/server library in C
* Copyright (C) 2003-2004 Ferhat Ayaz
@@ -284,14 +284,19 @@
#define REQUEST_MAX_PATH_SIZE 1024
#define RESPONSE_MAX_DESC_SIZE 1024
-
-#define URL_MAX_HOST_SIZE 120
-#define URL_MAX_CONTEXT_SIZE 1024
-/* TODO (#1#): find proper ports */
-#define URL_DEFAULT_PORT_HTTP 80
-#define URL_DEFAULT_PORT_HTTPS 81
-#define URL_DEFAULT_PORT_FTP 120
+/**
+ *
+ * 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;
+};
/**
*
@@ -307,6 +312,21 @@ typedef enum _http_version
/**
*
+ * Object representation of the content-type field in a HTTP header:
+ *
+ * Example:
+ *
+ * text/xml; key="value" key2="value2' ...
+ *
+ */
+typedef struct _content_type
+{
+ char type[128];
+ hpair_t *params;
+} content_type_t;
+
+/**
+ *
* The set of common methods for HTTP/1.1 is defined below. Although this set
* can be expanded, additional methods cannot be assumed to share the same
* semantics for separately extended clients and servers.
@@ -503,76 +523,33 @@ typedef enum _hreq_method
/**
*
- * hpairnode_t represents a pair (key, value) pair. This is also a linked list.
+ * part. Attachment
*
*/
-typedef struct hpair hpair_t;
-struct hpair
+struct part_t
{
- char *key;
- char *value;
- hpair_t *next;
+ char id[250];
+ char location[250];
+ hpair_t *header;
+ char content_type[128];
+ char transfer_encoding[128];
+ char filename[250];
+ struct part_t *next;
+ int deleteOnExit; /* default is 0 */
};
/**
*
- * The protocol types in enumeration format. Used in some other nanohttp objects
- * like hurl_t.
- *
- * @see hurl_t
- *
- */
-typedef enum _hprotocol
-{
- PROTOCOL_HTTP,
- PROTOCOL_HTTPS,
- PROTOCOL_FTP
-} hprotocol_t;
-
-/**
- *
- * The URL object. A representation of an URL like:
- *
- * [protocol]://[host]:[port]/[context]
- *
- * @see http://www.ietf.org/rfc/rfc2396.txt
+ * Attachments
*
*/
-typedef struct _hurl
+struct attachments_t
{
- /**
- *
- * The transfer protocol. Note that only PROTOCOL_HTTP and PROTOCOL_HTTPS are
- * supported by nanohttp.
- *
- */
- hprotocol_t protocol;
-
- /**
- *
- * The port number. If no port number was given in the URL, one of the default
- * port numbers will be selected.
- * - URL_HTTP_DEFAULT_PORT
- * - URL_HTTPS_DEFAULT_PORT
- * - URL_FTP_DEFAULT_PORT
- *
- */
- short port;
-
- /**
- *
- * The hostname
- *
- */
- char host[URL_MAX_HOST_SIZE];
+ struct part_t *parts;
+ struct part_t *last;
+ struct part_t *root_part;
+};
- /**
- *
- * The string after the hostname.
- *
- */
- char context[URL_MAX_CONTEXT_SIZE];
-} hurl_t;
#ifdef __cplusplus
extern "C" {
@@ -696,36 +673,6 @@ extern void hpairnode_dump(hpair_t * pair);
/**
*
- * Parses the given 'urlstr' and fills the given hurl_t object.
- *
- * @param obj the destination URL object to fill
- * @param url the URL in string format
- *
- * @returns H_OK on success or one of the following otherwise
- * - URL_ERROR_UNKNOWN_PROTOCOL
- * - URL_ERROR_NO_PROTOCOL
- * - URL_ERROR_NO_HOST
- *
- */
-extern herror_t hurl_parse(hurl_t * obj, const char *url);
-
-/**
- *
- * Object representation of the content-type field in a HTTP header:
- *
- * Example:
- *
- * text/xml; key="value" key2="value2' ...
- *
- */
-typedef struct _content_type
-{
- char type[128];
- hpair_t *params;
-} content_type_t;
-
-/**
- *
* Parses the given string and creates a new ccontent_type_t object.
*
* @param content_type_str the string representation of the content-type field in
@@ -745,38 +692,10 @@ extern content_type_t *content_type_new(const char *content_type_str);
*/
extern void content_type_free(content_type_t * ct);
-/**
- *
- * part. Attachment
- *
- */
-struct part_t
-{
- char id[250];
- char location[250];
- hpair_t *header;
- char content_type[128];
- char transfer_encoding[128];
- char filename[250];
- struct part_t *next;
- int deleteOnExit; /* default is 0 */
-};
-
extern struct part_t *part_new(const char *id, const char *filename, const char *content_type, const char *transfer_encoding, struct part_t * next);
extern void part_free(struct part_t * part);
-/**
- *
- * Attachments
- *
- */
-struct attachments_t
-{
- struct part_t *parts;
- struct part_t *last;
- struct part_t *root_part;
-};
/* should be used internally */
extern struct attachments_t *attachments_new(void);
diff --git a/nanohttp/nanohttp-url.c b/nanohttp/nanohttp-url.c
new file mode 100644
index 0000000..1588590
--- /dev/null
+++ b/nanohttp/nanohttp-url.c
@@ -0,0 +1,184 @@
+/******************************************************************
+* $Id: nanohttp-url.c,v 1.1 2006/12/08 21:21:41 m0gg 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
+******************************************************************/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#include "nanohttp-logging.h"
+#include "nanohttp-error.h"
+#include "nanohttp-url.h"
+
+/* TODO (#1#): find proper ports */
+#define URL_DEFAULT_PORT_HTTP 80
+#define URL_DEFAULT_PORT_HTTPS 81
+#define URL_DEFAULT_PORT_FTP 120
+
+static void
+_hurl_dump(const struct hurl_t * url)
+{
+
+ if (url == NULL)
+ {
+ log_error1("url is NULL!");
+ return;
+ }
+ log_verbose2("PROTOCOL : %d", url->protocol);
+ log_verbose2(" HOST : %s", url->host);
+ log_verbose2(" PORT : %d", url->port);
+ log_verbose2(" CONTEXT : %s", url->context);
+}
+
+herror_t
+hurl_parse(struct hurl_t * url, const char *urlstr)
+{
+ int iprotocol;
+ int ihost;
+ int iport;
+ int len;
+ int size;
+ char tmp[8];
+ char protocol[1024];
+
+ iprotocol = 0;
+ len = strlen(urlstr);
+
+ /* find protocol */
+ while (urlstr[iprotocol] != ':' && urlstr[iprotocol] != '\0')
+ {
+ iprotocol++;
+ }
+
+ if (iprotocol == 0)
+ {
+ log_error1("no protocol");
+ return herror_new("hurl_parse", URL_ERROR_NO_PROTOCOL, "No protocol");
+ }
+ if (iprotocol + 3 >= len)
+ {
+ log_error1("no host");
+ return herror_new("hurl_parse", URL_ERROR_NO_HOST, "No host");
+ }
+ if (urlstr[iprotocol] != ':'
+ && urlstr[iprotocol + 1] != '/' && urlstr[iprotocol + 2] != '/')
+ {
+ log_error1("no protocol");
+ return herror_new("hurl_parse", URL_ERROR_NO_PROTOCOL, "No protocol");
+ }
+ /* find host */
+ ihost = iprotocol + 3;
+ while (urlstr[ihost] != ':'
+ && urlstr[ihost] != '/' && urlstr[ihost] != '\0')
+ {
+ ihost++;
+ }
+
+ if (ihost == iprotocol + 1)
+ {
+ log_error1("no host");
+ return herror_new("hurl_parse", URL_ERROR_NO_HOST, "No host");
+ }
+ /* find port */
+ iport = ihost;
+ if (ihost + 1 < len)
+ {
+ if (urlstr[ihost] == ':')
+ {
+ while (urlstr[iport] != '/' && urlstr[iport] != '\0')
+ {
+ iport++;
+ }
+ }
+ }
+
+ /* find protocol */
+ strncpy(protocol, urlstr, iprotocol);
+ protocol[iprotocol] = '\0';
+ if (strcasecmp(protocol, "http"))
+ url->protocol = PROTOCOL_HTTP;
+ else if (strcasecmp(protocol, "https"))
+ url->protocol = PROTOCOL_HTTPS;
+ else if (strcasecmp(protocol, "ftp"))
+ url->protocol = PROTOCOL_FTP;
+ else
+ return herror_new("hurl_parse", URL_ERROR_UNKNOWN_PROTOCOL, "Unknown protocol '%s'", protocol);
+
+ /* TODO (#1#): add max of size and URL_MAX_HOST_SIZE */
+ size = ihost - iprotocol - 3;
+ 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
+ {
+ switch (url->protocol)
+ {
+ case PROTOCOL_HTTP:
+ url->port = URL_DEFAULT_PORT_HTTP;
+ break;
+ case PROTOCOL_HTTPS:
+ url->port = URL_DEFAULT_PORT_HTTPS;
+ break;
+ case PROTOCOL_FTP:
+ url->port = URL_DEFAULT_PORT_FTP;
+ break;
+ }
+ }
+
+ len = strlen(urlstr);
+ if (len > iport)
+ {
+ /* TODO (#1#): find max of size and URL_MAX_CONTEXT_SIZE */
+ size = len - iport;
+ strncpy(url->context, &urlstr[iport], size);
+ url->context[size] = '\0';
+ }
+ else
+ {
+ url->context[0] = '\0';
+ }
+
+ _hurl_dump(url);
+
+ return H_OK;
+}
+
+void
+hurl_free(struct hurl_t *url)
+{
+ if (!url)
+ return;
+
+ free(url);
+
+ return;
+}
diff --git a/nanohttp/nanohttp-url.h b/nanohttp/nanohttp-url.h
new file mode 100644
index 0000000..ad35c90
--- /dev/null
+++ b/nanohttp/nanohttp-url.h
@@ -0,0 +1,120 @@
+/******************************************************************
+ * $Id: nanohttp-url.h,v 1.1 2006/12/08 21:21:41 m0gg Exp $
+ *
+ * CSOAP Project: A http client/server library in C
+ * Copyright (C) 2003-2004 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: ferhatayaz@yahoo.com
+ ******************************************************************/
+#ifndef __nanohttp_url_h
+#define __nanohttp_url_h
+
+/**
+ *
+ * The protocol types in enumeration format. Used in some other nanohttp objects
+ * like hurl_t.
+ *
+ * @see hurl_t
+ *
+ */
+typedef enum _hprotocol
+{
+ PROTOCOL_HTTP,
+ PROTOCOL_HTTPS,
+ PROTOCOL_FTP
+} hprotocol_t;
+
+#define URL_MAX_HOST_SIZE 120
+#define URL_MAX_CONTEXT_SIZE 1024
+
+/**
+ *
+ * The URL object. A representation of an URL like:
+ *
+ * [protocol]://[host]:[port]/[context]
+ *
+ * @see http://www.ietf.org/rfc/rfc2396.txt
+ *
+ */
+struct hurl_t
+{
+ /**
+ *
+ * The transfer protocol. Note that only PROTOCOL_HTTP and PROTOCOL_HTTPS are
+ * supported by nanohttp.
+ *
+ */
+ hprotocol_t protocol;
+
+ /**
+ *
+ * The port number. If no port number was given in the URL, one of the default
+ * port numbers will be selected.
+ * - URL_HTTP_DEFAULT_PORT
+ * - URL_HTTPS_DEFAULT_PORT
+ * - URL_FTP_DEFAULT_PORT
+ *
+ */
+ short port;
+
+ /**
+ *
+ * The hostname
+ *
+ */
+ char host[URL_MAX_HOST_SIZE];
+
+ /**
+ *
+ * The string after the hostname.
+ *
+ */
+ char context[URL_MAX_CONTEXT_SIZE];
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ *
+ * Parses the given 'urlstr' and fills the given hurl_t object.
+ *
+ * @param obj the destination URL object to fill
+ * @param url the URL in string format
+ *
+ * @returns H_OK on success or one of the following otherwise
+ * - URL_ERROR_UNKNOWN_PROTOCOL
+ * - URL_ERROR_NO_PROTOCOL
+ * - URL_ERROR_NO_HOST
+ *
+ */
+extern herror_t hurl_parse(struct hurl_t * obj, const char *url);
+
+/**
+ *
+ * Frees the resources within a url and the url itself.
+ *
+ */
+extern void hurl_free(struct hurl_t *url);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif