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