Free (GPLv2) TCP/IP stack developed by TASS Belgium

Fork of PicoTCP by Daniele Lacamera

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?

UserRevisionLine numberNew 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