↑ 1 #include <limits.h>
↑ 2 #include "http_host.h"
↑ 3
↑ 4 #define MAP_WANT_HTTP_HOST MAP_HTTP_HOST
↑ 5 #define MAP_WANT_DIGIT MAP_DIGIT
↑ 6 #include "rh_charmap.h"
↑ 7
↑ 8 /*
↑ 9 *
↑ 10 * parse a "hostname:123" value.
↑ 11 *
↑ 12 * valid: "hostname"
↑ 13 * "hostname:123"
↑ 14 *
↑ 15 * invalid: ""
↑ 16 * "hostname:"
↑ 17 * "hostname:0"
↑ 18 * "hostname:0123"
↑ 19 * ".." (dot after dot)
↑ 20 * ".hostname." (dot at begin OR end)
↑ 21 *
↑ 22 */
↑ 23
↑ 24 int http_host_parse (http_host_t *host, const char *src, size_t nsrc)
↑ 25 {
↑ 26 const unsigned char *map;
↑ 27 int is_const;
↑ 28 size_t offset, last_dot;
↑ 29 enum {
↑ 30 HTTP_HOST_STATE_HOST,
↑ 31 HTTP_HOST_STATE_PORT
↑ 32 } state;
↑ 33
↑ 34 if (NULL == src || 0 == nsrc)
↑ 35 return -1;
↑ 36
↑ 37 rh_buffer_set_const (&host->host, src, nsrc);
↑ 38 host->port = 0;
↑ 39 is_const = 1;
↑ 40 last_dot = 0;
↑ 41
↑ 42 map = MAP_HTTP_HOST;
↑ 43 offset = 0;
↑ 44 state = HTTP_HOST_STATE_HOST;
↑ 45
↑ 46 for ( ; nsrc; --nsrc, ++offset) {
↑ 47 unsigned char ch, ch_lower;
↑ 48
↑ 49 ch = src[offset];
↑ 50 ch_lower = map[ch];
↑ 51
↑ 52 switch (state) {
↑ 53 case HTTP_HOST_STATE_HOST:
↑ 54 if (0 == ch_lower)
↑ 55 return -1;
↑ 56
↑ 57 if (ch == ch_lower) {
↑ 58 switch (ch) {
↑ 59 case '.':
↑ 60 /* ".." */
↑ 61 if (last_dot + 1 == offset)
↑ 62 return -1;
↑ 63
↑ 64 /* ".host" || "host." */
↑ 65 if (0 == offset || 1 == nsrc)
↑ 66 return -1;
↑ 67
↑ 68 last_dot = offset;
↑ 69 break;
↑ 70 case ':':
↑ 71 if (nsrc < 2)
↑ 72 return -1;
↑ 73
↑ 74 map = MAP_DIGIT;
↑ 75
↑ 76 state = HTTP_HOST_STATE_PORT;
↑ 77
↑ 78 host->host.used = offset;
↑ 79 break;
↑ 80 }
↑ 81 } else {
↑ 82 if (is_const) {
↑ 83 rh_buffer_init (&host->host);
↑ 84
↑ 85 if (rh_buffer_append(&host->host,
↑ 86 src, nsrc))
↑ 87 {
↑ 88 return -1;
↑ 89 }
↑ 90
↑ 91 is_const = 0;
↑ 92 }
↑ 93
↑ 94 host->host.data[offset] = ch_lower;
↑ 95 }
↑ 96
↑ 97 break;
↑ 98
↑ 99 case HTTP_HOST_STATE_PORT:
↑100 if (0xff == ch_lower)
↑101 return -1;
↑102
↑103 /* is first number '0'? */
↑104 if (0 == ch_lower && 0 == host->port)
↑105 return -1;
↑106
↑107 host->port = host->port * 10 + ch_lower;
↑108
↑109 break;
↑110 }
↑111 }
↑112
↑113 if (host->port && host->port > USHRT_MAX)
↑114 return -1;
↑115
↑116 return 0;
↑117 }
↑118
↑119 void http_host_destroy (http_host_t *host)
↑120 {
↑121 rh_buffer_destroy (&host->host);
↑122 }
↑123
↑124 void http_host_free (void *ptr)
↑125 {
↑126 http_host_t *host = ptr;
↑127
↑128 if (host) {
↑129 http_host_destroy (host);
↑130 free (host);
↑131 }
↑132 }
syntax highlighted by Code2HTML, v. 0.9.1