00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
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
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
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
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
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 }