PageRenderTime 987ms CodeModel.GetById 161ms app.highlight 10ms RepoModel.GetById 80ms app.codeStats 0ms

/js/lib/Socket.IO-node/support/expresso/deps/jscoverage/http-url.c

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs
C | 156 lines | 121 code | 12 blank | 23 comment | 42 complexity | f0a620ab49116a316acfd3650ca33f05 MD5 | raw file
  1/*
  2    http-url.c - URL parsing routines
  3    Copyright (C) 2008 siliconforks.com
  4
  5    This program is free software; you can redistribute it and/or modify
  6    it under the terms of the GNU General Public License as published by
  7    the Free Software Foundation; either version 2 of the License, or
  8    (at your option) any later version.
  9
 10    This program is distributed in the hope that it will be useful,
 11    but WITHOUT ANY WARRANTY; without even the implied warranty of
 12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13    GNU General Public License for more details.
 14
 15    You should have received a copy of the GNU General Public License along
 16    with this program; if not, write to the Free Software Foundation, Inc.,
 17    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 18*/
 19
 20#include <config.h>
 21
 22#include "http-server.h"
 23
 24#include <ctype.h>
 25#include <string.h>
 26
 27#include "util.h"
 28
 29int URL_parse_host_and_port(const char * s, char ** host, uint16_t * port) {
 30  char * colon = strchr(s, ':');
 31  if (colon == NULL) {
 32    *host = xstrdup(s);
 33    *port = 80;
 34  }
 35  else {
 36    if (*(colon + 1) == '\0') {
 37      *port = 80;
 38    }
 39    else {
 40      char * end;
 41      unsigned long p = strtoul(colon + 1, &end, 10);
 42      if (*end == '\0') {
 43        if (p > UINT16_MAX) {
 44          return -1;
 45        }
 46        else {
 47          *port = p;
 48        }
 49      }
 50      else {
 51        return -1;
 52      }
 53    }
 54    *host = xstrndup(s, colon - s);
 55  }
 56  return 0;
 57}
 58
 59int URL_parse_abs_path_and_query(const char * s, char ** abs_path, char ** query) {
 60  if (*s == '\0') {
 61    *abs_path = xstrdup("/");
 62    *query = NULL;
 63  }
 64  else if (*s == '?') {
 65    *abs_path = xstrdup("/");
 66    *query = xstrdup(s + 1);
 67  }
 68  else if (*s == '/') {
 69    char * question = strchr(s, '?');
 70    if (question == NULL) {
 71      *abs_path = xstrdup(s);
 72      *query = NULL;
 73    }
 74    else {
 75      *abs_path = xstrndup(s, question - s);
 76      *query = xstrdup(question + 1);
 77    }
 78  }
 79  else {
 80    return -1;
 81  }
 82  return 0;
 83}
 84
 85int URL_parse(const char * url, char ** host, uint16_t * port, char ** abs_path, char ** query) {
 86  /* check for invalid characters */
 87  for (const char * p = url; *p != '\0'; p++) {
 88    switch (*p) {
 89    case ';':
 90    case '/':
 91    case '?':
 92    case ':':
 93    case '@':
 94    case '&':
 95    case '=':
 96    case '+':
 97    case '$':
 98    case ',':
 99    case '-':
100    case '_':
101    case '.':
102    case '!':
103    case '~':
104    case '*':
105    case '\'':
106    case '(':
107    case ')':
108    case '%':
109      break;
110    default:
111      if (! isalnum(*p)) {
112        return -1;
113      }
114      break;
115    }
116  }
117
118  int result;
119  if (strncasecmp(url, "http://", 7) == 0) {
120    /* absoluteURI */
121
122    /* advance past the http:// */
123    const char * authority_start = url + 7;
124
125    /* look for a slash or question mark */
126    const char * p;
127    for (p = authority_start; *p != '/' && *p != '?' && *p != '\0'; p++) {
128      ;
129    }
130
131    char * host_and_port = xstrndup(authority_start, p - authority_start);
132    result = URL_parse_host_and_port(host_and_port, host, port);
133    free(host_and_port);
134    if (result != 0) {
135      return result;
136    }
137
138    result = URL_parse_abs_path_and_query(p, abs_path, query);
139    if (result != 0) {
140      free(*host);
141      *host = NULL;
142      return result;
143    }
144  }
145  else {
146    /* abs_path */
147    *host = NULL;
148    *port = 80;
149    result = URL_parse_abs_path_and_query(url, abs_path, query);
150    if (result != 0) {
151      return result;
152    }
153  }
154  result = 0;
155  return result;
156}