nanohttp-url.c

Go to the documentation of this file.
00001 /******************************************************************
00002 *  $Id: nanohttp-url.c,v 1.3 2006/12/16 16:09:45 m0gg Exp $
00003 *
00004 * CSOAP Project:  A http client/server library in C
00005 * Copyright (C) 2003  Ferhat Ayaz
00006 *
00007 * This library is free software; you can redistribute it and/or
00008 * modify it under the terms of the GNU Library General Public
00009 * License as published by the Free Software Foundation; either
00010 * version 2 of the License, or (at your option) any later version.
00011 *
00012 * This library is distributed in the hope that it will be useful,
00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 * Library General Public License for more details.
00016 *
00017 * You should have received a copy of the GNU Library General Public
00018 * License along with this library; if not, write to the
00019 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00020 * Boston, MA  02111-1307, USA.
00021 *
00022 * Email: ayaz@jprogrammer.net
00023 ******************************************************************/
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027 
00028 #ifdef HAVE_STDIO_H
00029 #include <stdio.h>
00030 #endif
00031 
00032 #ifdef HAVE_STDLIB_H
00033 #include <stdlib.h>
00034 #endif
00035 
00036 #ifdef HAVE_STRING_H
00037 #include <string.h>
00038 #endif
00039 
00040 #ifdef HAVE_NETINET_IN_H
00041 #include <netinet/in.h>
00042 #endif
00043 
00044 #ifdef HAVE_ERRNO_H
00045 #include <errno.h>
00046 #endif
00047 
00048 #ifdef HAVE_NETDB_H
00049 #include <netdb.h>
00050 #endif
00051 
00052 #include "nanohttp-logging.h"
00053 #include "nanohttp-error.h"
00054 #include "nanohttp-url.h"
00055       
00056 #define HTTP_DEFAULT_PORT               80
00057 #define HTTPS_DEFAULT_PORT              443
00058 
00059 static void
00060 _hurl_dump(const struct hurl_t *url)
00061 {
00062   if (!url)
00063   {
00064     log_error1("parameter url is NULL");
00065     return;
00066   }
00067 
00068   log_verbose2("PROTOCOL: %d", url->protocol);
00069   log_verbose2("    HOST: \"%s\"", url->host);
00070   log_verbose2("    PORT: %d", url->port);
00071   log_verbose2(" CONTEXT: \"%s\"", url->context);
00072 
00073   return;
00074 }
00075 
00076 herror_t
00077 hurl_parse(struct hurl_t *url, const char *urlstr)
00078 {
00079   int iprotocol;
00080   int ihost;
00081   int iport;
00082   int len;
00083   int size;
00084   char tmp[8];
00085   char protocol[1024];
00086   struct servent *entry;
00087 
00088   iprotocol = 0;
00089   len = strlen(urlstr);
00090 
00091   /* find protocol */
00092   while (urlstr[iprotocol] != ':' && urlstr[iprotocol] != '\0')
00093   {
00094     iprotocol++;
00095   }
00096 
00097   if (iprotocol == 0)
00098   {
00099     log_error1("no protocol");
00100     return herror_new("hurl_parse", URL_ERROR_NO_PROTOCOL, "No protocol");
00101   }
00102   if (iprotocol + 3 >= len)
00103   {
00104     log_error1("no host");
00105     return herror_new("hurl_parse", URL_ERROR_NO_HOST, "No host");
00106   }
00107   if (urlstr[iprotocol] != ':'
00108       && urlstr[iprotocol + 1] != '/' && urlstr[iprotocol + 2] != '/')
00109   {
00110     log_error1("no protocol");
00111     return herror_new("hurl_parse", URL_ERROR_NO_PROTOCOL, "No protocol");
00112   }
00113 
00114   /* find host */
00115   ihost = iprotocol + 3;
00116   while (urlstr[ihost] != ':'
00117          && urlstr[ihost] != '/' && urlstr[ihost] != '\0')
00118   {
00119     ihost++;
00120   }
00121 
00122   if (ihost == iprotocol + 1)
00123   {
00124     log_error1("no host");
00125     return herror_new("hurl_parse", URL_ERROR_NO_HOST, "No host");
00126   }
00127 
00128   /* find port */
00129   iport = ihost;
00130   if (ihost + 1 < len)
00131   {
00132     if (urlstr[ihost] == ':')
00133     {
00134       while (urlstr[iport] != '/' && urlstr[iport] != '\0')
00135       {
00136         iport++;
00137       }
00138     }
00139   }
00140 
00141   /* find protocol */
00142   strncpy(protocol, urlstr, iprotocol);
00143   protocol[iprotocol] = '\0';
00144   if (!strncasecmp(protocol, "http", 5))
00145     url->protocol = PROTOCOL_HTTP;
00146   else if (!strncasecmp(protocol, "https", 6))
00147     url->protocol = PROTOCOL_HTTPS;
00148   else
00149     return herror_new("hurl_parse", URL_ERROR_UNKNOWN_PROTOCOL, "Unknown protocol \"%s\"", protocol);
00150 
00151   /* find right port */
00152   if (!(entry = getservbyname(protocol, "tcp")))
00153   {
00154     log_warn2("getservbyname(\"%s\", \"tcp\") returned NULL, please edit services database", protocol);
00155 
00156     switch (url->protocol)
00157     {
00158     case PROTOCOL_HTTP:
00159       url->port = HTTP_DEFAULT_PORT;
00160       break;
00161     case PROTOCOL_HTTPS:
00162       url->port = HTTPS_DEFAULT_PORT;
00163       break;
00164     }
00165   }
00166   else
00167   {
00168     url->port = ntohs(entry->s_port);
00169   }
00170 
00171   size = ihost - iprotocol - 3;
00172   if (!(url->host = (char *)malloc(size + 1)))
00173   {
00174     log_error2("malloc failed (%s)", strerror(errno));
00175     return herror_new("hurl_parse", URL_ERROR, "malloc failed (%s)", strerror(errno));
00176   }
00177   strncpy(url->host, &urlstr[iprotocol + 3], size);
00178   url->host[size] = '\0';
00179 
00180   if (iport > ihost)
00181   {
00182     size = iport - ihost;
00183     strncpy(tmp, &urlstr[ihost + 1], size);
00184     url->port = atoi(tmp);
00185   }
00186 
00187   /* find path */
00188   len = strlen(urlstr);
00189   if (len > iport)
00190   {
00191     size = len - iport;
00192     if (!(url->context = (char *)malloc(size + 1)))
00193     {
00194       log_error2("malloc failed (%s)", strerror(errno));
00195       return herror_new("hurl_parse", URL_ERROR, "malloc failed (%s)", strerror(errno));
00196     }
00197     strncpy(url->context, &urlstr[iport], size);
00198     url->context[size] = '\0';
00199   }
00200   else
00201   {
00202     url->context = strdup("");
00203   }
00204 
00205   _hurl_dump(url);
00206 
00207   return H_OK;
00208 }
00209 
00210 void
00211 hurl_free(struct hurl_t *url)
00212 {
00213   if (url)
00214   {
00215     if (url->host)
00216       free(url->host);
00217 
00218     if (url->context)
00219       free(url->context);
00220 
00221     free(url);
00222   }
00223 
00224   return;
00225 }

Generated on Thu Jan 25 23:36:03 2007 for csoap by  doxygen 1.4.6