From 46ec9aea1caadcec41ff5637c0bb2b906a2a2041 Mon Sep 17 00:00:00 2001 From: m0gg Date: Fri, 8 Dec 2006 21:21:41 +0000 Subject: hurl_t moved to nanohttp-url.[ch] --- TODO | 10 ++- libcsoap.pc.in | 2 +- libcsoap/Makefile.am | 4 +- nanohttp/Makefile.am | 8 +- nanohttp/nanohttp-client.c | 27 ++++--- nanohttp/nanohttp-client.h | 125 +++++++++++++++++++++++++++++- nanohttp/nanohttp-common.c | 164 +--------------------------------------- nanohttp/nanohttp-common.h | 169 +++++++++++------------------------------ nanohttp/nanohttp-url.c | 184 +++++++++++++++++++++++++++++++++++++++++++++ nanohttp/nanohttp-url.h | 120 +++++++++++++++++++++++++++++ 10 files changed, 508 insertions(+), 305 deletions(-) create mode 100644 nanohttp/nanohttp-url.c create mode 100644 nanohttp/nanohttp-url.h diff --git a/TODO b/TODO index 27aef0b..ba36121 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,4 @@ -$Id: TODO,v 1.9 2006/11/30 14:23:58 m0gg Exp $ +$Id: TODO,v 1.10 2006/12/08 21:21:41 m0gg Exp $ =============================================================================== Things to do _before_ 1.2 release: @@ -24,6 +24,14 @@ csoap: - Add reference to http://www.w3.org/TR/SOAP-attachments - Write README.xmlsec like README.ssl +Things to do _after_ 1.2 release: +================================= + +additional: +----------- +- publish {Open,Net,Free,Dragonfly}BSD port +- publish Debian package + Additional things that could be done: ===================================== diff --git a/libcsoap.pc.in b/libcsoap.pc.in index edc3c78..c210155 100644 --- a/libcsoap.pc.in +++ b/libcsoap.pc.in @@ -5,7 +5,7 @@ includedir=@includedir@ Name: csoap Description: C API for SOAP applications -Version: @csoap_version_dotted@ +Version: @csoap_major@.@csoap_minor@.@csoap_patch@ Libs: -L${libdir} -lcsoap-@csoap_release@ -lnanohttp-@nanohttp_release@ @XML_LIBS@ Cflags: @XML_CPPFLAGS@ -I${includedir}/libcsoap-@csoap_release@ -I${includedir}/nanohttp-@nanohttp_release@ diff --git a/libcsoap/Makefile.am b/libcsoap/Makefile.am index bb00615..abcde74 100644 --- a/libcsoap/Makefile.am +++ b/libcsoap/Makefile.am @@ -1,5 +1,5 @@ # -# $Revision: 1.14 $ +# $Revision: 1.15 $ # lib_LTLIBRARIES=libcsoap.la @@ -8,7 +8,7 @@ libcsoap_ladir=$(includedir)/libcsoap-@csoap_release@/libcsoap libcsoap_la_SOURCES=soap-xml.c soap-fault.c soap-env.c soap-service.c \ soap-router.c soap-client.c soap-server.c soap-ctx.c \ soap-admin.c soap-addressing.c soap-transport.c \ - soap-nudp.c soap-nhttp.c soap-wsil.c \ + soap-nudp.c soap-nhttp.c soap-wsil.c libcsoap_la_HEADERS=soap-fault.h soap-env.h soap-service.h soap-router.h \ soap-client.h soap-server.h soap-ctx.h soap-addressing.h \ 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 #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 [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; +}; /** * @@ -305,6 +310,21 @@ typedef enum _http_version } http_version_t; +/** + * + * 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 @@ -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" { @@ -694,36 +671,6 @@ extern hpair_t *hpairnode_copy_deep(const hpair_t * src); extern void hpairnode_dump_deep(hpair_t * pair); 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. @@ -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 +#endif + +#ifdef HAVE_STDIO_H +#include +#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 -- cgit v1.1-32-gdbae