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

Fork of PicoTCP by Daniele Lacamera

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?

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