Free (GPLv2) TCP/IP stack developed by TASS Belgium
Fork of PicoTCP by
modules/pico_http_util.c@1:cfe8984a32b4, 2013-05-17 (annotated)
- Committer:
- tass
- Date:
- Fri May 17 12:09:59 2013 +0000
- Revision:
- 1:cfe8984a32b4
- Parent:
- libraries/picotcp/modules/pico_http_util.c@0:d7f2341ab245
Update for smaller SOCKETQ
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
daniele | 0:d7f2341ab245 | 1 | /********************************************************************* |
daniele | 0:d7f2341ab245 | 2 | PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved. |
daniele | 0:d7f2341ab245 | 3 | See LICENSE and COPYING for usage. |
daniele | 0:d7f2341ab245 | 4 | |
daniele | 0:d7f2341ab245 | 5 | Author: Andrei Carp <andrei.carp@tass.be> |
daniele | 0:d7f2341ab245 | 6 | *********************************************************************/ |
daniele | 0:d7f2341ab245 | 7 | |
daniele | 0:d7f2341ab245 | 8 | #include <stdint.h> |
daniele | 0:d7f2341ab245 | 9 | #include "pico_config.h" |
daniele | 0:d7f2341ab245 | 10 | #include "pico_stack.h" |
daniele | 0:d7f2341ab245 | 11 | #include "pico_protocol.h" |
daniele | 0:d7f2341ab245 | 12 | #include "pico_http_util.h" |
daniele | 0:d7f2341ab245 | 13 | |
daniele | 0:d7f2341ab245 | 14 | #define TRUE 1 |
daniele | 0:d7f2341ab245 | 15 | #define FALSE 0 |
daniele | 0:d7f2341ab245 | 16 | |
daniele | 0:d7f2341ab245 | 17 | #define HTTP_PROTO_TOK "http://" |
daniele | 0:d7f2341ab245 | 18 | #define HTTP_PROTO_LEN 7u |
daniele | 0:d7f2341ab245 | 19 | |
daniele | 0:d7f2341ab245 | 20 | #if defined PICO_SUPPORT_HTTP_CLIENT || defined PICO_SUPPORT_HTTP_SERVER |
daniele | 0:d7f2341ab245 | 21 | |
daniele | 0:d7f2341ab245 | 22 | int pico_itoaHex(uint16_t port, char * ptr) |
daniele | 0:d7f2341ab245 | 23 | { |
daniele | 0:d7f2341ab245 | 24 | int size = 0; |
daniele | 0:d7f2341ab245 | 25 | int index; |
daniele | 0:d7f2341ab245 | 26 | |
daniele | 0:d7f2341ab245 | 27 | // transform to from number to string [ in backwards ] |
daniele | 0:d7f2341ab245 | 28 | while(port) |
daniele | 0:d7f2341ab245 | 29 | { |
daniele | 0:d7f2341ab245 | 30 | ptr[size] = ((port & 0xF) < 10) ? ((port & 0xF) + '0') : ((port & 0xF) - 10 + 'a'); |
daniele | 0:d7f2341ab245 | 31 | port = port>>4u; //divide by 16 |
daniele | 0:d7f2341ab245 | 32 | size++; |
daniele | 0:d7f2341ab245 | 33 | } |
daniele | 0:d7f2341ab245 | 34 | |
daniele | 0:d7f2341ab245 | 35 | // invert positions |
daniele | 0:d7f2341ab245 | 36 | for(index=0 ;index < size>>1u ;index++) |
daniele | 0:d7f2341ab245 | 37 | { |
daniele | 0:d7f2341ab245 | 38 | char c = ptr[index]; |
daniele | 0:d7f2341ab245 | 39 | ptr[index] = ptr[size-index-1]; |
daniele | 0:d7f2341ab245 | 40 | ptr[size-index-1] = c; |
daniele | 0:d7f2341ab245 | 41 | } |
daniele | 0:d7f2341ab245 | 42 | ptr[size] = '\0'; |
daniele | 0:d7f2341ab245 | 43 | return size; |
daniele | 0:d7f2341ab245 | 44 | } |
daniele | 0:d7f2341ab245 | 45 | |
daniele | 0:d7f2341ab245 | 46 | int pico_itoa(uint16_t port, char * ptr) |
daniele | 0:d7f2341ab245 | 47 | { |
daniele | 0:d7f2341ab245 | 48 | int size = 0; |
daniele | 0:d7f2341ab245 | 49 | int index; |
daniele | 0:d7f2341ab245 | 50 | |
daniele | 0:d7f2341ab245 | 51 | // transform to from number to string [ in backwards ] |
daniele | 0:d7f2341ab245 | 52 | while(port) |
daniele | 0:d7f2341ab245 | 53 | { |
daniele | 0:d7f2341ab245 | 54 | ptr[size] = port%10 + '0'; |
daniele | 0:d7f2341ab245 | 55 | port = port/10; |
daniele | 0:d7f2341ab245 | 56 | size++; |
daniele | 0:d7f2341ab245 | 57 | } |
daniele | 0:d7f2341ab245 | 58 | |
daniele | 0:d7f2341ab245 | 59 | // invert positions |
daniele | 0:d7f2341ab245 | 60 | for(index=0 ;index < size>>1u ;index++) |
daniele | 0:d7f2341ab245 | 61 | { |
daniele | 0:d7f2341ab245 | 62 | char c = ptr[index]; |
daniele | 0:d7f2341ab245 | 63 | ptr[index] = ptr[size-index-1]; |
daniele | 0:d7f2341ab245 | 64 | ptr[size-index-1] = c; |
daniele | 0:d7f2341ab245 | 65 | } |
daniele | 0:d7f2341ab245 | 66 | ptr[size] = '\0'; |
daniele | 0:d7f2341ab245 | 67 | return size; |
daniele | 0:d7f2341ab245 | 68 | } |
daniele | 0:d7f2341ab245 | 69 | |
daniele | 0:d7f2341ab245 | 70 | |
daniele | 0:d7f2341ab245 | 71 | int pico_processURI(const char * uri, struct pico_http_uri * urikey) |
daniele | 0:d7f2341ab245 | 72 | { |
daniele | 0:d7f2341ab245 | 73 | |
daniele | 0:d7f2341ab245 | 74 | uint16_t lastIndex = 0, index; |
daniele | 0:d7f2341ab245 | 75 | |
daniele | 0:d7f2341ab245 | 76 | if(!uri || !urikey || uri[0] == '/') |
daniele | 0:d7f2341ab245 | 77 | { |
daniele | 0:d7f2341ab245 | 78 | pico_err = PICO_ERR_EINVAL; |
daniele | 0:d7f2341ab245 | 79 | goto error; |
daniele | 0:d7f2341ab245 | 80 | } |
daniele | 0:d7f2341ab245 | 81 | |
daniele | 0:d7f2341ab245 | 82 | // detect protocol => search for "://" |
daniele | 0:d7f2341ab245 | 83 | if(memcmp(uri,HTTP_PROTO_TOK,HTTP_PROTO_LEN) == 0) // could be optimized |
daniele | 0:d7f2341ab245 | 84 | { // protocol identified, it is http |
daniele | 0:d7f2341ab245 | 85 | urikey->protoHttp = TRUE; |
daniele | 0:d7f2341ab245 | 86 | lastIndex = HTTP_PROTO_LEN; |
daniele | 0:d7f2341ab245 | 87 | } |
daniele | 0:d7f2341ab245 | 88 | else |
daniele | 0:d7f2341ab245 | 89 | { |
daniele | 0:d7f2341ab245 | 90 | if(strstr(uri,"://")) // different protocol specified |
daniele | 0:d7f2341ab245 | 91 | { |
daniele | 0:d7f2341ab245 | 92 | urikey->protoHttp = FALSE; |
daniele | 0:d7f2341ab245 | 93 | goto error; |
daniele | 0:d7f2341ab245 | 94 | } |
daniele | 0:d7f2341ab245 | 95 | // no protocol specified, assuming by default it's http |
daniele | 0:d7f2341ab245 | 96 | urikey->protoHttp = TRUE; |
daniele | 0:d7f2341ab245 | 97 | } |
daniele | 0:d7f2341ab245 | 98 | |
daniele | 0:d7f2341ab245 | 99 | // detect hostname |
daniele | 0:d7f2341ab245 | 100 | index = lastIndex; |
daniele | 0:d7f2341ab245 | 101 | while(uri[index] && uri[index]!='/' && uri[index]!=':') index++; |
daniele | 0:d7f2341ab245 | 102 | |
daniele | 0:d7f2341ab245 | 103 | if(index == lastIndex) |
daniele | 0:d7f2341ab245 | 104 | { |
daniele | 0:d7f2341ab245 | 105 | // wrong format |
daniele | 0:d7f2341ab245 | 106 | urikey->host = urikey->resource = NULL; |
daniele | 0:d7f2341ab245 | 107 | urikey->port = urikey->protoHttp = 0u; |
daniele | 0:d7f2341ab245 | 108 | |
daniele | 0:d7f2341ab245 | 109 | goto error; |
daniele | 0:d7f2341ab245 | 110 | } |
daniele | 0:d7f2341ab245 | 111 | else |
daniele | 0:d7f2341ab245 | 112 | { |
daniele | 0:d7f2341ab245 | 113 | // extract host |
daniele | 0:d7f2341ab245 | 114 | urikey->host = (char *)pico_zalloc(index-lastIndex+1); |
daniele | 0:d7f2341ab245 | 115 | |
daniele | 0:d7f2341ab245 | 116 | if(!urikey->host) |
daniele | 0:d7f2341ab245 | 117 | { |
daniele | 0:d7f2341ab245 | 118 | // no memory |
daniele | 0:d7f2341ab245 | 119 | goto error; |
daniele | 0:d7f2341ab245 | 120 | } |
daniele | 0:d7f2341ab245 | 121 | memcpy(urikey->host,uri+lastIndex,index-lastIndex); |
daniele | 0:d7f2341ab245 | 122 | } |
daniele | 0:d7f2341ab245 | 123 | |
daniele | 0:d7f2341ab245 | 124 | if(!uri[index]) |
daniele | 0:d7f2341ab245 | 125 | { |
daniele | 0:d7f2341ab245 | 126 | // nothing specified |
daniele | 0:d7f2341ab245 | 127 | urikey->port = 80u; |
daniele | 0:d7f2341ab245 | 128 | urikey->resource = pico_zalloc(2u); |
daniele | 0:d7f2341ab245 | 129 | urikey->resource[0] = '/'; |
daniele | 0:d7f2341ab245 | 130 | return HTTP_RETURN_OK; |
daniele | 0:d7f2341ab245 | 131 | } |
daniele | 0:d7f2341ab245 | 132 | else if(uri[index] == '/') |
daniele | 0:d7f2341ab245 | 133 | { |
daniele | 0:d7f2341ab245 | 134 | urikey->port = 80u; |
daniele | 0:d7f2341ab245 | 135 | } |
daniele | 0:d7f2341ab245 | 136 | else if(uri[index] == ':') |
daniele | 0:d7f2341ab245 | 137 | { |
daniele | 0:d7f2341ab245 | 138 | urikey->port = 0u; |
daniele | 0:d7f2341ab245 | 139 | index++; |
daniele | 0:d7f2341ab245 | 140 | while(uri[index] && uri[index]!='/') |
daniele | 0:d7f2341ab245 | 141 | { |
daniele | 0:d7f2341ab245 | 142 | // should check if every component is a digit |
daniele | 0:d7f2341ab245 | 143 | urikey->port = urikey->port*10 + (uri[index] - '0'); |
daniele | 0:d7f2341ab245 | 144 | index++; |
daniele | 0:d7f2341ab245 | 145 | } |
daniele | 0:d7f2341ab245 | 146 | } |
daniele | 0:d7f2341ab245 | 147 | |
daniele | 0:d7f2341ab245 | 148 | // extract resource |
daniele | 0:d7f2341ab245 | 149 | if(!uri[index]) |
daniele | 0:d7f2341ab245 | 150 | { |
daniele | 0:d7f2341ab245 | 151 | urikey->resource = pico_zalloc(2u); |
daniele | 0:d7f2341ab245 | 152 | urikey->resource[0] = '/'; |
daniele | 0:d7f2341ab245 | 153 | } |
daniele | 0:d7f2341ab245 | 154 | else |
daniele | 0:d7f2341ab245 | 155 | { |
daniele | 0:d7f2341ab245 | 156 | lastIndex = index; |
daniele | 0:d7f2341ab245 | 157 | while(uri[index] && uri[index]!='?' && uri[index]!='&' && uri[index]!='#') index++; |
daniele | 0:d7f2341ab245 | 158 | urikey->resource = (char *)pico_zalloc(index-lastIndex+1); |
daniele | 0:d7f2341ab245 | 159 | |
daniele | 0:d7f2341ab245 | 160 | if(!urikey->resource) |
daniele | 0:d7f2341ab245 | 161 | { |
daniele | 0:d7f2341ab245 | 162 | // no memory |
daniele | 0:d7f2341ab245 | 163 | pico_err = PICO_ERR_ENOMEM; |
daniele | 0:d7f2341ab245 | 164 | goto error; |
daniele | 0:d7f2341ab245 | 165 | } |
daniele | 0:d7f2341ab245 | 166 | |
daniele | 0:d7f2341ab245 | 167 | memcpy(urikey->resource,uri+lastIndex,index-lastIndex); |
daniele | 0:d7f2341ab245 | 168 | } |
daniele | 0:d7f2341ab245 | 169 | |
daniele | 0:d7f2341ab245 | 170 | return HTTP_RETURN_OK; |
daniele | 0:d7f2341ab245 | 171 | |
daniele | 0:d7f2341ab245 | 172 | error : |
daniele | 0:d7f2341ab245 | 173 | if(urikey->resource) |
daniele | 0:d7f2341ab245 | 174 | { |
daniele | 0:d7f2341ab245 | 175 | pico_free(urikey->resource); |
daniele | 0:d7f2341ab245 | 176 | urikey->resource = NULL; |
daniele | 0:d7f2341ab245 | 177 | } |
daniele | 0:d7f2341ab245 | 178 | if(urikey->host) |
daniele | 0:d7f2341ab245 | 179 | { |
daniele | 0:d7f2341ab245 | 180 | pico_free(urikey->host); |
daniele | 0:d7f2341ab245 | 181 | urikey->host = NULL; |
daniele | 0:d7f2341ab245 | 182 | } |
daniele | 0:d7f2341ab245 | 183 | |
daniele | 0:d7f2341ab245 | 184 | return HTTP_RETURN_ERROR; |
daniele | 0:d7f2341ab245 | 185 | } |
daniele | 0:d7f2341ab245 | 186 | #endif |