Example of HTTPServer with additional features: * SNTPClient, DST rules * Link status indication * Local or SDCard-based WebServer * RPC-able class * Static and Dynamic HTML page

Dependencies:   mbed

Committer:
iva2k
Date:
Tue Jan 12 07:41:55 2010 +0000
Revision:
2:360fda42fefd
Parent:
0:886e4b3119ad

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
iva2k 0:886e4b3119ad 1 #include "HTTPServer.h"
iva2k 0:886e4b3119ad 2 #include "NetServer.h"
iva2k 0:886e4b3119ad 3
iva2k 0:886e4b3119ad 4 extern int gDebug; // [iva2k]
iva2k 0:886e4b3119ad 5
iva2k 0:886e4b3119ad 6 using namespace std;
iva2k 0:886e4b3119ad 7 using namespace mbed;
iva2k 0:886e4b3119ad 8
iva2k 0:886e4b3119ad 9 //unsigned int gconnections = 0;
iva2k 0:886e4b3119ad 10
iva2k 0:886e4b3119ad 11 unsigned int mbed::hash(unsigned char *str) {
iva2k 0:886e4b3119ad 12 unsigned int hash = 5381;
iva2k 0:886e4b3119ad 13 int c;
iva2k 0:886e4b3119ad 14 while((c = *(str++))!=(unsigned char)'\0') {
iva2k 0:886e4b3119ad 15 hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
iva2k 0:886e4b3119ad 16 }
iva2k 0:886e4b3119ad 17 return hash;
iva2k 0:886e4b3119ad 18 }
iva2k 0:886e4b3119ad 19
iva2k 0:886e4b3119ad 20 HTTPConnection::HTTPConnection(HTTPServer *pparent, struct tcp_pcb *pcb)
iva2k 0:886e4b3119ad 21 : TCPConnection(pparent, pcb), request_incomplete(true), data(NULL),
iva2k 0:886e4b3119ad 22 request_handler(NULL), request_status(HTTP_NotFound), parent(pparent),
iva2k 0:886e4b3119ad 23 _request_url(NULL), _request_type(0), _request_headerfields(NULL),
iva2k 0:886e4b3119ad 24 _request_length(0), _request_arg_key(NULL), _request_arg_value(NULL),
iva2k 0:886e4b3119ad 25 _request_arg_state(0), emptypolls(0) {
iva2k 0:886e4b3119ad 26 _timeout_max = pparent->timeout();
iva2k 0:886e4b3119ad 27 }
iva2k 0:886e4b3119ad 28
iva2k 0:886e4b3119ad 29 HTTPConnection::~HTTPConnection() {
iva2k 0:886e4b3119ad 30 deleteRequest();
iva2k 0:886e4b3119ad 31 emptypolls = NetServer::time();
iva2k 0:886e4b3119ad 32 }
iva2k 0:886e4b3119ad 33
iva2k 0:886e4b3119ad 34 const char *HTTPConnection::getField(char *key) const {
iva2k 0:886e4b3119ad 35 unsigned int h = hash((unsigned char *)key);
iva2k 0:886e4b3119ad 36 return _request_fields.find(h)->second;
iva2k 0:886e4b3119ad 37 }
iva2k 0:886e4b3119ad 38
iva2k 0:886e4b3119ad 39 void HTTPConnection::addField(char *key, char *value) {
iva2k 0:886e4b3119ad 40 unsigned int h = hash((unsigned char *)key);
iva2k 0:886e4b3119ad 41 if(parent->isField(h)) {
iva2k 0:886e4b3119ad 42 _request_fields.insert( make_pair(h, value));
iva2k 0:886e4b3119ad 43 }
iva2k 0:886e4b3119ad 44 }
iva2k 0:886e4b3119ad 45
iva2k 0:886e4b3119ad 46 void HTTPConnection::send() {
iva2k 0:886e4b3119ad 47 int i = sndbuf();
iva2k 0:886e4b3119ad 48 if(!request_incomplete&&i) {
iva2k 0:886e4b3119ad 49 switch(request_handler->send(this, i)) {
iva2k 0:886e4b3119ad 50 case HTTP_SuccessEnded:
iva2k 0:886e4b3119ad 51 case HTTP_Failed: {
iva2k 0:886e4b3119ad 52 deleteRequest();
iva2k 0:886e4b3119ad 53 release_callbacks();
iva2k 0:886e4b3119ad 54 NetServer::get()->free(this);
iva2k 0:886e4b3119ad 55 close();
iva2k 0:886e4b3119ad 56 } break;
iva2k 0:886e4b3119ad 57 default:
iva2k 0:886e4b3119ad 58 emptypolls = NetServer::time();
iva2k 0:886e4b3119ad 59 break;
iva2k 0:886e4b3119ad 60 }
iva2k 0:886e4b3119ad 61 } else {
iva2k 0:886e4b3119ad 62 if(NetServer::time() - emptypolls > _timeout_max) {
iva2k 0:886e4b3119ad 63 release_callbacks();
iva2k 0:886e4b3119ad 64 NetServer::get()->free(this);
iva2k 0:886e4b3119ad 65 close();
iva2k 0:886e4b3119ad 66 }
iva2k 0:886e4b3119ad 67 }
iva2k 0:886e4b3119ad 68 }
iva2k 0:886e4b3119ad 69
iva2k 0:886e4b3119ad 70 void HTTPConnection::store(void *d, struct pbuf *p) {
iva2k 0:886e4b3119ad 71 int len = p->len-(((int)d)-((int)p->payload));
iva2k 0:886e4b3119ad 72 do {
iva2k 0:886e4b3119ad 73 switch(request_handler->data(this, d, len)) {
iva2k 0:886e4b3119ad 74 case HTTP_SuccessEnded:
iva2k 0:886e4b3119ad 75 case HTTP_Failed: {
iva2k 0:886e4b3119ad 76 deleteRequest();
iva2k 0:886e4b3119ad 77 release_callbacks();
iva2k 0:886e4b3119ad 78 NetServer::get()->free(this);
iva2k 0:886e4b3119ad 79 close();
iva2k 0:886e4b3119ad 80 } break;
iva2k 0:886e4b3119ad 81 default:
iva2k 0:886e4b3119ad 82 break;
iva2k 0:886e4b3119ad 83 }
iva2k 0:886e4b3119ad 84 p = p->next;
iva2k 0:886e4b3119ad 85 if(p) {
iva2k 0:886e4b3119ad 86 len = p->len;
iva2k 0:886e4b3119ad 87 d = static_cast<char *>(p->payload);
iva2k 0:886e4b3119ad 88 }
iva2k 0:886e4b3119ad 89 } while(_request_type&&p);
iva2k 0:886e4b3119ad 90 }
iva2k 0:886e4b3119ad 91
iva2k 0:886e4b3119ad 92 void HTTPConnection::err(err_t err) {
iva2k 0:886e4b3119ad 93 printf("Error\n");
iva2k 0:886e4b3119ad 94 release_callbacks();
iva2k 0:886e4b3119ad 95 NetServer::get()->free(this);
iva2k 0:886e4b3119ad 96 }
iva2k 0:886e4b3119ad 97
iva2k 0:886e4b3119ad 98 err_t HTTPConnection::poll() {
iva2k 0:886e4b3119ad 99 send();
iva2k 0:886e4b3119ad 100 return ERR_OK;
iva2k 0:886e4b3119ad 101 }
iva2k 0:886e4b3119ad 102
iva2k 0:886e4b3119ad 103 err_t HTTPConnection::sent(u16_t len) {
iva2k 0:886e4b3119ad 104 return poll();
iva2k 0:886e4b3119ad 105 }
iva2k 0:886e4b3119ad 106
iva2k 0:886e4b3119ad 107 err_t HTTPConnection::recv(struct pbuf *q, err_t err) {
iva2k 0:886e4b3119ad 108 struct pbuf *p = q;
iva2k 0:886e4b3119ad 109 int i;
iva2k 0:886e4b3119ad 110 char *data;
iva2k 0:886e4b3119ad 111 if (gDebug>1) printf("DEBUG: HTTPConnection::recv(%s, %d) :1\r\n", p ? "<some data>" : "NULL", (int)err);
iva2k 0:886e4b3119ad 112 if(err == ERR_OK && p != NULL) {
iva2k 0:886e4b3119ad 113 /* Inform TCP that we have taken the data. */
iva2k 0:886e4b3119ad 114 recved(p->tot_len);
iva2k 0:886e4b3119ad 115 data = static_cast<char *>(p->payload);
iva2k 0:886e4b3119ad 116
iva2k 0:886e4b3119ad 117 // :1
iva2k 0:886e4b3119ad 118 // Looking if it's GET, POST,
iva2k 0:886e4b3119ad 119 // Followup from an incomplete request Header,
iva2k 0:886e4b3119ad 120 // POST data or just crap (DEL, HEAD ...).
iva2k 0:886e4b3119ad 121 if(!_request_type&&(strncmp(data, "GET ", 4) == 0)) {
iva2k 0:886e4b3119ad 122 _request_type = GET; // Need :2
iva2k 0:886e4b3119ad 123 } else if(!_request_type&&(strncmp(data, "POST ", 5) == 0)) {
iva2k 0:886e4b3119ad 124 _request_type = POST; // Need :2
iva2k 0:886e4b3119ad 125 } else if(_request_type&&request_incomplete) {
iva2k 0:886e4b3119ad 126 getFields(&p, &data); // Need :3
iva2k 0:886e4b3119ad 127 } else if(_request_type == POST) {
iva2k 0:886e4b3119ad 128 // Followup (Data) // Exits
iva2k 0:886e4b3119ad 129 data = static_cast<char *>(p->payload); // [iva2k] Redundand
iva2k 0:886e4b3119ad 130 store(data, p);
iva2k 0:886e4b3119ad 131 emptypolls = NetServer::time();
iva2k 0:886e4b3119ad 132 pbuf_free(q);
iva2k 0:886e4b3119ad 133 data = NULL; // [iva2k] Unnecessary
iva2k 0:886e4b3119ad 134 return ERR_OK;
iva2k 0:886e4b3119ad 135 } else {
iva2k 0:886e4b3119ad 136 pbuf_free(q); // Exits
iva2k 0:886e4b3119ad 137 data = NULL; // [iva2k] Unnecessary
iva2k 0:886e4b3119ad 138 return ERR_OK;
iva2k 0:886e4b3119ad 139 }
iva2k 0:886e4b3119ad 140
iva2k 0:886e4b3119ad 141 if (gDebug>1) printf(" : HTTPConnection::recv() :2 _request_type=%d, _request_url=%s\r\n", (int)_request_type, _request_url?_request_url:"NULL");
iva2k 0:886e4b3119ad 142 // :2
iva2k 0:886e4b3119ad 143 // Processing first POST or GET Packet
iva2k 0:886e4b3119ad 144 // need :3 v--- If its 0 we have followup header data.
iva2k 0:886e4b3119ad 145 if(_request_type&&!_request_url) {
iva2k 0:886e4b3119ad 146 char *pagename = (char *)(data + _request_type);
iva2k 0:886e4b3119ad 147 for(i = _request_type; i < p->len; i++) {
iva2k 0:886e4b3119ad 148 if((data[i] == ' ') || (data[i] == '\r') || (data[i] == '\n')) {
iva2k 0:886e4b3119ad 149 data[i] = 0;
iva2k 0:886e4b3119ad 150 data = &data[i+1];
iva2k 0:886e4b3119ad 151 break;
iva2k 0:886e4b3119ad 152 }
iva2k 0:886e4b3119ad 153 }
iva2k 0:886e4b3119ad 154 emptypolls = NetServer::time();
iva2k 0:886e4b3119ad 155
iva2k 0:886e4b3119ad 156 if((pagename[0] == '/') && (pagename[1] == 0)) {
iva2k 0:886e4b3119ad 157 pagename = "/index.htm";
iva2k 0:886e4b3119ad 158 }
iva2k 0:886e4b3119ad 159
iva2k 0:886e4b3119ad 160 i = strlen(pagename);
iva2k 0:886e4b3119ad 161 _request_url = new char[i+1];
iva2k 0:886e4b3119ad 162 memcpy(_request_url, pagename, i); // [iva2k] memcpy(_request_url, pagename, i+1); would not need next line
iva2k 0:886e4b3119ad 163 _request_url[i] = '\0';
iva2k 0:886e4b3119ad 164 getFields(&p, &data);
iva2k 0:886e4b3119ad 165 }
iva2k 0:886e4b3119ad 166
iva2k 0:886e4b3119ad 167 if (gDebug>1) printf(" : HTTPConnection::recv() :3 _request_url=%s request_incomplete=%d, request_status=%d\r\n", _request_url, (int)request_incomplete, (int)request_status);
iva2k 0:886e4b3119ad 168 // :3
iva2k 0:886e4b3119ad 169 // Send or store the first amoungh of data.
iva2k 0:886e4b3119ad 170 // Only when the message is complete.
iva2k 0:886e4b3119ad 171 if(!request_incomplete) {
iva2k 0:886e4b3119ad 172 emptypolls = NetServer::time();
iva2k 0:886e4b3119ad 173 // Find the right handler
iva2k 0:886e4b3119ad 174 if(!request_handler) {
iva2k 0:886e4b3119ad 175 request_handler = parent->handle(this);
iva2k 0:886e4b3119ad 176 request_status = request_handler->init(this);
iva2k 0:886e4b3119ad 177 if (gDebug>1) printf(" : ... request_status=%d\r\n", (int)request_status);
iva2k 0:886e4b3119ad 178 }
iva2k 0:886e4b3119ad 179 i = strlen(_request_headerfields) + 120;
iva2k 0:886e4b3119ad 180 char *buf = new char[i];
iva2k 0:886e4b3119ad 181 sprintf(buf, "HTTP/1.1 %d OK\r\nServer:mbed embedded%s%d%s\r\nConnection: Close\r\n\r\n", request_status,
iva2k 0:886e4b3119ad 182 (_request_length?"\r\nContent-Length: ":""),_request_length,
iva2k 0:886e4b3119ad 183 getHeaderFields());
iva2k 0:886e4b3119ad 184 i = strlen(buf); // [iva2k] sprintf returns just that, use i=sprintf(...) above instead.
iva2k 0:886e4b3119ad 185 if(sndbuf()>i) {
iva2k 0:886e4b3119ad 186 if(request_status==HTTP_NotFound) {
iva2k 0:886e4b3119ad 187 const char *msg = {
iva2k 0:886e4b3119ad 188 "HTTP/1.1 404 Not Found\r\nServer:mbed embedded\r\n"
iva2k 0:886e4b3119ad 189 "Content-Type: text/html\r\n"
iva2k 0:886e4b3119ad 190 "Content-Length: 163\r\n"
iva2k 0:886e4b3119ad 191 "\r\n"
iva2k 0:886e4b3119ad 192 "<html>\r\n"
iva2k 0:886e4b3119ad 193 "<header>\r\n"
iva2k 0:886e4b3119ad 194 "<title>File not found<title>\r\n"
iva2k 0:886e4b3119ad 195 "</header>\r\n"
iva2k 0:886e4b3119ad 196 "<body>\r\n"
iva2k 0:886e4b3119ad 197 "<h1>HTTP 404</h1>\r\n"
iva2k 0:886e4b3119ad 198 "<p>The file you requested was not found on this mbed. </p>\r\n"
iva2k 0:886e4b3119ad 199 "</body>\r\n"
iva2k 0:886e4b3119ad 200 "</html>\r\n"
iva2k 0:886e4b3119ad 201 };
iva2k 0:886e4b3119ad 202
iva2k 0:886e4b3119ad 203 if (gDebug) printf("HTTP : %s NOT FOUND\r\n", p ? _request_url : "NULL");
iva2k 0:886e4b3119ad 204 write((void *)msg, strlen(msg), 0);
iva2k 0:886e4b3119ad 205 deleteRequest();
iva2k 0:886e4b3119ad 206 } else {
iva2k 0:886e4b3119ad 207 if (gDebug) printf("HTTP : %s \r\n", p ? _request_url : "NULL");
iva2k 0:886e4b3119ad 208 write(buf, i, (TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE));
iva2k 0:886e4b3119ad 209 if(_request_type == POST) {
iva2k 0:886e4b3119ad 210 store(data, p);
iva2k 0:886e4b3119ad 211 } else {
iva2k 0:886e4b3119ad 212 send();
iva2k 0:886e4b3119ad 213 }
iva2k 0:886e4b3119ad 214 }
iva2k 0:886e4b3119ad 215 }
iva2k 0:886e4b3119ad 216 delete buf;
iva2k 0:886e4b3119ad 217 }
iva2k 0:886e4b3119ad 218
iva2k 0:886e4b3119ad 219 // Exits
iva2k 0:886e4b3119ad 220 pbuf_free(q);
iva2k 0:886e4b3119ad 221 data = NULL;
iva2k 0:886e4b3119ad 222 } else {
iva2k 0:886e4b3119ad 223 release_callbacks();
iva2k 0:886e4b3119ad 224 NetServer::get()->free(this);
iva2k 0:886e4b3119ad 225 close();
iva2k 0:886e4b3119ad 226 }
iva2k 0:886e4b3119ad 227 return ERR_OK;
iva2k 0:886e4b3119ad 228 }
iva2k 0:886e4b3119ad 229
iva2k 0:886e4b3119ad 230 void HTTPConnection::getFields(struct pbuf **q, char **d) {
iva2k 0:886e4b3119ad 231 if(parent->fields.empty()) {
iva2k 0:886e4b3119ad 232 while((*q)&&request_incomplete) {
iva2k 0:886e4b3119ad 233 unsigned int end = ((unsigned int)((*q)->payload)+(unsigned int)((*q)->len));
iva2k 0:886e4b3119ad 234 for(; request_incomplete && ((unsigned int)(*d) < end); (*d)++) {
iva2k 0:886e4b3119ad 235 if((*((char *)((*d)-0))=='\n')&&(*((char *)((*d)-1))=='\r')&&
iva2k 0:886e4b3119ad 236 (*((char *)((*d)-2))=='\n')&&(*((char *)((*d)-3))=='\r')) {
iva2k 0:886e4b3119ad 237 request_incomplete = false;
iva2k 0:886e4b3119ad 238 (*d) += 1;
iva2k 0:886e4b3119ad 239 break;
iva2k 0:886e4b3119ad 240 }
iva2k 0:886e4b3119ad 241 }
iva2k 0:886e4b3119ad 242 if(request_incomplete) {
iva2k 0:886e4b3119ad 243 (*q) = (*q)->next;
iva2k 0:886e4b3119ad 244 if((*q)) {
iva2k 0:886e4b3119ad 245 (*d) = static_cast<char *>((*q)->payload);
iva2k 0:886e4b3119ad 246 }
iva2k 0:886e4b3119ad 247 }
iva2k 0:886e4b3119ad 248 }
iva2k 0:886e4b3119ad 249 } else {
iva2k 0:886e4b3119ad 250 char *kb = *d, *ke = NULL, *vb = *d, *ve = NULL;
iva2k 0:886e4b3119ad 251 while((*q)&&request_incomplete) {
iva2k 0:886e4b3119ad 252 unsigned int end = ((unsigned int)((*q)->payload)+(unsigned int)((*q)->len));
iva2k 0:886e4b3119ad 253 for(; request_incomplete && ((unsigned int)(*d) < end); (*d)++) {
iva2k 0:886e4b3119ad 254 switch(**d) {
iva2k 0:886e4b3119ad 255 case ' ': switch(_request_arg_state) {
iva2k 0:886e4b3119ad 256 case 1: case 2: _request_arg_state = 2; break;
iva2k 0:886e4b3119ad 257 case 3: _request_arg_state = 3; break;
iva2k 0:886e4b3119ad 258 default: _request_arg_state = 0; break;
iva2k 0:886e4b3119ad 259 } break;
iva2k 0:886e4b3119ad 260 case ':': switch(_request_arg_state) {
iva2k 0:886e4b3119ad 261 default: _request_arg_state = 2; break;
iva2k 0:886e4b3119ad 262 case 3: _request_arg_state = 3; break;
iva2k 0:886e4b3119ad 263 } break;
iva2k 0:886e4b3119ad 264 case '\r': switch(_request_arg_state) {
iva2k 0:886e4b3119ad 265 default: _request_arg_state = 4; break;
iva2k 0:886e4b3119ad 266 case 5: case 6: _request_arg_state = 6; break;
iva2k 0:886e4b3119ad 267 } break;
iva2k 0:886e4b3119ad 268 case '\n': switch(_request_arg_state) {
iva2k 0:886e4b3119ad 269 default: _request_arg_state = 4; break;
iva2k 0:886e4b3119ad 270 case 4: case 5: _request_arg_state = 5; break;
iva2k 0:886e4b3119ad 271 case 6: _request_arg_state = 7; break;
iva2k 0:886e4b3119ad 272 } break;
iva2k 0:886e4b3119ad 273 default: switch(_request_arg_state) {
iva2k 0:886e4b3119ad 274 default: _request_arg_state = 1; break;
iva2k 0:886e4b3119ad 275 case 2: case 3: _request_arg_state = 3; break;
iva2k 0:886e4b3119ad 276 } break;
iva2k 0:886e4b3119ad 277 }
iva2k 0:886e4b3119ad 278 switch(_request_arg_state) {
iva2k 0:886e4b3119ad 279 case 0: kb = (*d)+1; break; //PreKey
iva2k 0:886e4b3119ad 280 case 1: ke = (*d); break; //Key
iva2k 0:886e4b3119ad 281 case 2: vb = (*d)+1; break; //PreValue
iva2k 0:886e4b3119ad 282 case 3: ve = (*d); break; //Value
iva2k 0:886e4b3119ad 283 default: break;
iva2k 0:886e4b3119ad 284 case 7: request_incomplete = false; break;
iva2k 0:886e4b3119ad 285 case 5: {
iva2k 0:886e4b3119ad 286 int oldkey = (_request_arg_key)?strlen(_request_arg_key):0;
iva2k 0:886e4b3119ad 287 int oldval = (_request_arg_value)?strlen(_request_arg_value):0;
iva2k 0:886e4b3119ad 288 int keylen =(ke&&kb)?ke-kb+1:0;
iva2k 0:886e4b3119ad 289 int vallen = (ve&&vb)?ve-vb+1:0;
iva2k 0:886e4b3119ad 290 char *key = new char[oldkey+keylen];
iva2k 0:886e4b3119ad 291 char *val = new char[oldval+vallen];
iva2k 0:886e4b3119ad 292 if(_request_arg_key&&oldkey) {
iva2k 0:886e4b3119ad 293 strncpy(key, _request_arg_key, oldkey);
iva2k 0:886e4b3119ad 294 }
iva2k 0:886e4b3119ad 295 if(_request_arg_value&&oldval) {
iva2k 0:886e4b3119ad 296 strncpy(val, _request_arg_value, oldval);
iva2k 0:886e4b3119ad 297 }
iva2k 0:886e4b3119ad 298 if(kb&&keylen) {
iva2k 0:886e4b3119ad 299 strncpy(&key[oldkey], kb, keylen);
iva2k 0:886e4b3119ad 300 }
iva2k 0:886e4b3119ad 301 if(vb&&vallen) {
iva2k 0:886e4b3119ad 302 strncpy(&val[oldval], vb, vallen);
iva2k 0:886e4b3119ad 303 }
iva2k 0:886e4b3119ad 304 key[oldkey+keylen] = 0;
iva2k 0:886e4b3119ad 305 val[oldval+vallen] = 0;
iva2k 0:886e4b3119ad 306 // printf("'%s':='%s'\n", key, val);
iva2k 0:886e4b3119ad 307 addField(key, val);
iva2k 0:886e4b3119ad 308 kb = vb = (*d)+1;
iva2k 0:886e4b3119ad 309 ke = ve = NULL;
iva2k 0:886e4b3119ad 310 if(_request_arg_key) {
iva2k 0:886e4b3119ad 311 delete _request_arg_key;
iva2k 0:886e4b3119ad 312 _request_arg_key = NULL;
iva2k 0:886e4b3119ad 313 }
iva2k 0:886e4b3119ad 314 if(_request_arg_value) {
iva2k 0:886e4b3119ad 315 delete _request_arg_value;
iva2k 0:886e4b3119ad 316 _request_arg_value = NULL;
iva2k 0:886e4b3119ad 317 }
iva2k 0:886e4b3119ad 318 delete key;
iva2k 0:886e4b3119ad 319 } break;
iva2k 0:886e4b3119ad 320 }
iva2k 0:886e4b3119ad 321 }
iva2k 0:886e4b3119ad 322 }
iva2k 0:886e4b3119ad 323 switch(_request_arg_state) {
iva2k 0:886e4b3119ad 324 case 0: break; // PreKey
iva2k 0:886e4b3119ad 325 case 5: break; // n-rec
iva2k 0:886e4b3119ad 326 case 6: break; // 2r-rec
iva2k 0:886e4b3119ad 327 default: break;
iva2k 0:886e4b3119ad 328 case 1: case 2: { // Key // PreValue
iva2k 0:886e4b3119ad 329 int keylen =(kb)?(*d)-kb+1:0;
iva2k 0:886e4b3119ad 330 _request_arg_key = new char[keylen];
iva2k 0:886e4b3119ad 331 strncpy(_request_arg_key, kb, keylen+1);
iva2k 0:886e4b3119ad 332 _request_arg_key[keylen] = 0;
iva2k 0:886e4b3119ad 333 } break;
iva2k 0:886e4b3119ad 334 case 3: case 4: { // Value // r-rec
iva2k 0:886e4b3119ad 335 int keylen =(ke&&kb)?ke-kb+1:0;
iva2k 0:886e4b3119ad 336 int vallen = (vb)?(*d)-vb+1:0;
iva2k 0:886e4b3119ad 337 _request_arg_key = new char[keylen];
iva2k 0:886e4b3119ad 338 _request_arg_value = new char[vallen];
iva2k 0:886e4b3119ad 339 strncpy(_request_arg_key, kb, keylen+1);
iva2k 0:886e4b3119ad 340 strncpy(_request_arg_value, vb, vallen+1);
iva2k 0:886e4b3119ad 341 _request_arg_key[keylen] = 0;
iva2k 0:886e4b3119ad 342 _request_arg_value[vallen] = 0;
iva2k 0:886e4b3119ad 343 } break;
iva2k 0:886e4b3119ad 344 }
iva2k 0:886e4b3119ad 345 if(request_incomplete) {
iva2k 0:886e4b3119ad 346 (*q) = (*q)->next;
iva2k 0:886e4b3119ad 347 if((*q)) {
iva2k 0:886e4b3119ad 348 (*d) = static_cast<char *>((*q)->payload);
iva2k 0:886e4b3119ad 349 }
iva2k 0:886e4b3119ad 350 }
iva2k 0:886e4b3119ad 351 }
iva2k 0:886e4b3119ad 352 }
iva2k 0:886e4b3119ad 353
iva2k 0:886e4b3119ad 354 HTTPServer::HTTPServer(unsigned short port)
iva2k 0:886e4b3119ad 355 : TCPListener(port), _timeout_max(60000) {
iva2k 0:886e4b3119ad 356 }
iva2k 0:886e4b3119ad 357
iva2k 0:886e4b3119ad 358 HTTPServer::HTTPServer(const char *hostname, struct ip_addr ip, struct ip_addr nm, struct ip_addr gw, struct ip_addr dns, unsigned short port)
iva2k 0:886e4b3119ad 359 : TCPListener(port), _timeout_max(60000) {
iva2k 0:886e4b3119ad 360 NetServer *net = NULL;
iva2k 0:886e4b3119ad 361 if(ip.addr != ip_addr_any.addr && nm.addr != ip_addr_any.addr && gw.addr != ip_addr_any.addr) {
iva2k 0:886e4b3119ad 362 net = NetServer::create(ip, nm, gw);
iva2k 0:886e4b3119ad 363 if(dns.addr != ip_addr_any.addr) {
iva2k 0:886e4b3119ad 364 net->setDNS1(dns);
iva2k 0:886e4b3119ad 365 }
iva2k 0:886e4b3119ad 366 } else if(hostname) {
iva2k 0:886e4b3119ad 367 net = NetServer::create();
iva2k 0:886e4b3119ad 368 }
iva2k 0:886e4b3119ad 369 if(hostname) {
iva2k 0:886e4b3119ad 370 net->setHostname(hostname);
iva2k 0:886e4b3119ad 371 }
iva2k 0:886e4b3119ad 372 }
iva2k 0:886e4b3119ad 373
iva2k 0:886e4b3119ad 374 void HTTPConnection::deleteRequest() {
iva2k 0:886e4b3119ad 375 for(map<unsigned int, char *>::iterator iter = _request_fields.begin();
iva2k 0:886e4b3119ad 376 iter!=_request_fields.end();iter++) {
iva2k 0:886e4b3119ad 377 delete iter->second;
iva2k 0:886e4b3119ad 378 }
iva2k 0:886e4b3119ad 379 _request_fields.clear();
iva2k 0:886e4b3119ad 380 if(data) {delete data; data = NULL; };
iva2k 0:886e4b3119ad 381
iva2k 0:886e4b3119ad 382 if(_request_type) {
iva2k 0:886e4b3119ad 383 delete _request_headerfields;
iva2k 0:886e4b3119ad 384 delete _request_arg_key;
iva2k 0:886e4b3119ad 385 delete _request_arg_value;
iva2k 0:886e4b3119ad 386 if(_request_url) {
iva2k 0:886e4b3119ad 387 delete _request_url;
iva2k 0:886e4b3119ad 388 _request_url = NULL;
iva2k 0:886e4b3119ad 389 }
iva2k 0:886e4b3119ad 390 }
iva2k 0:886e4b3119ad 391 _request_type = 0;
iva2k 0:886e4b3119ad 392 request_incomplete = true;
iva2k 0:886e4b3119ad 393 }
iva2k 0:886e4b3119ad 394