HTTP Server upon new mbed Ethernet Interface. Based on original code by Henry Leinen.

Dependencies:   EthernetInterface mbed-rtos mbed

Fork of HTTP_server by pablo gindel

Committer:
pabloxid
Date:
Sun Jul 28 07:53:35 2013 +0000
Revision:
2:dc9184e97328
Parent:
0:fcceff3299be
Child:
3:27b3a889b327
Many fixes: It works now

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pabloxid 0:fcceff3299be 1 #include "mbed.h"
pabloxid 0:fcceff3299be 2 #include "HTTPServer.h"
pabloxid 0:fcceff3299be 3
pabloxid 0:fcceff3299be 4 RequestConfig rq_conf[] = {
pabloxid 0:fcceff3299be 5 { "GET", HTTP_RT_GET },
pabloxid 0:fcceff3299be 6 { "POST", HTTP_RT_POST}
pabloxid 0:fcceff3299be 7 };
pabloxid 0:fcceff3299be 8
pabloxid 0:fcceff3299be 9 HTTPServer::HTTPServer (int port, const char* _path) {
pabloxid 0:fcceff3299be 10
pabloxid 0:fcceff3299be 11 INFO("Binding to port %d...", port);
pabloxid 0:fcceff3299be 12 if (socketServer.bind (port) < 0) {
pabloxid 0:fcceff3299be 13 ERR("Failed to bind to port !\n");
pabloxid 0:fcceff3299be 14 error("Binding");
pabloxid 0:fcceff3299be 15 }
pabloxid 0:fcceff3299be 16
pabloxid 0:fcceff3299be 17 INFO("Listening ...");
pabloxid 0:fcceff3299be 18 if (socketServer.listen(1) < 0) {
pabloxid 0:fcceff3299be 19 ERR("Failed to listen !\n");
pabloxid 0:fcceff3299be 20 error("Listening");
pabloxid 0:fcceff3299be 21 }
pabloxid 0:fcceff3299be 22
pabloxid 0:fcceff3299be 23 INFO("Connected !");
pabloxid 0:fcceff3299be 24 // set into blocking operation
pabloxid 2:dc9184e97328 25 socketServer.set_blocking (true);
pabloxid 0:fcceff3299be 26
pabloxid 0:fcceff3299be 27 path = _path;
pabloxid 0:fcceff3299be 28
pabloxid 0:fcceff3299be 29 }
pabloxid 0:fcceff3299be 30
pabloxid 0:fcceff3299be 31 HTTPServer::~HTTPServer() { };
pabloxid 0:fcceff3299be 32
pabloxid 0:fcceff3299be 33 int HTTPServer::poll () {
pabloxid 0:fcceff3299be 34
pabloxid 0:fcceff3299be 35 cliente = new TCPSocketConnection;
pabloxid 0:fcceff3299be 36 cliente->set_blocking (false, TIMEOUT);
pabloxid 0:fcceff3299be 37
pabloxid 0:fcceff3299be 38 if (socketServer.accept(*cliente) < 0) {
pabloxid 0:fcceff3299be 39 INFO("No connection\n");
pabloxid 0:fcceff3299be 40 return ERROR;
pabloxid 0:fcceff3299be 41 }
pabloxid 0:fcceff3299be 42
pabloxid 2:dc9184e97328 43 // a new connection was received
pabloxid 2:dc9184e97328 44 INFO("Client (IP=%s) is connected !", cliente->get_address());
pabloxid 0:fcceff3299be 45
pabloxid 0:fcceff3299be 46 msg = new HTTPMsg; // estructura para decodificar y alojar el mensaje
pabloxid 0:fcceff3299be 47
pabloxid 2:dc9184e97328 48 int c = pollConnection (); // esto parsea y llena las cosas contenidas en msg
pabloxid 0:fcceff3299be 49
pabloxid 0:fcceff3299be 50 if (c == OK) {
pabloxid 2:dc9184e97328 51 // Handle the request
pabloxid 2:dc9184e97328 52 // cliente->set_blocking (true);
pabloxid 0:fcceff3299be 53 INFO("Handling request !");
pabloxid 0:fcceff3299be 54 handleRequest ();
pabloxid 0:fcceff3299be 55 }
pabloxid 0:fcceff3299be 56
pabloxid 0:fcceff3299be 57 delete msg;
pabloxid 0:fcceff3299be 58 delete cliente;
pabloxid 0:fcceff3299be 59
pabloxid 2:dc9184e97328 60 INFO("Leaving polling thread\n");
pabloxid 0:fcceff3299be 61 return c;
pabloxid 0:fcceff3299be 62 }
pabloxid 0:fcceff3299be 63
pabloxid 0:fcceff3299be 64 int HTTPServer::pollConnection () {
pabloxid 0:fcceff3299be 65
pabloxid 0:fcceff3299be 66 int received = 0;
pabloxid 0:fcceff3299be 67 INFO("Waiting for new data in connection");
pabloxid 0:fcceff3299be 68 // Try receiving request line
pabloxid 0:fcceff3299be 69 received = receiveLine ();
pabloxid 0:fcceff3299be 70
pabloxid 0:fcceff3299be 71 if (received == ERROR) {
pabloxid 0:fcceff3299be 72 // there was an error, probably the connection was closed, so close this connection as well
pabloxid 0:fcceff3299be 73 INFO("No more data available. Will close this connection now.");
pabloxid 0:fcceff3299be 74 return ERROR;
pabloxid 0:fcceff3299be 75 }
pabloxid 0:fcceff3299be 76
pabloxid 0:fcceff3299be 77 // The Request has not yet been received so try it
pabloxid 0:fcceff3299be 78 received = parse ();
pabloxid 0:fcceff3299be 79
pabloxid 0:fcceff3299be 80 if (received == ERROR) {
pabloxid 0:fcceff3299be 81 // Invalid content received, so close the connection
pabloxid 0:fcceff3299be 82 INFO("Invalid message received, so sending negative response and closing connection !");
pabloxid 2:dc9184e97328 83 tcpsend ("HTTP/1.1 400 BadRequest\n\rContent-Length: %d\n\rContent-Type: text\n\r\n\r\n\r", 0);
pabloxid 0:fcceff3299be 84 return ERROR;
pabloxid 0:fcceff3299be 85 }
pabloxid 0:fcceff3299be 86
pabloxid 2:dc9184e97328 87 // The request has been received, try receive the body
pabloxid 0:fcceff3299be 88 do {
pabloxid 0:fcceff3299be 89 received = receiveLine ();
pabloxid 0:fcceff3299be 90 if (received == ERROR) {return ERROR;}
pabloxid 0:fcceff3299be 91 // First check if we received an empty line. This would indicate the end of the message or message body.
pabloxid 0:fcceff3299be 92 if (received == EMPTY) {
pabloxid 0:fcceff3299be 93 // there was an empty line, so we can start with performing the request
pabloxid 0:fcceff3299be 94 INFO("Request Header was received completely. Performing request.");
pabloxid 0:fcceff3299be 95 received = 0;
pabloxid 0:fcceff3299be 96 break;
pabloxid 0:fcceff3299be 97 } else {
pabloxid 2:dc9184e97328 98 /* add message body
pabloxid 0:fcceff3299be 99 if (parseHeader () != 0) {
pabloxid 0:fcceff3299be 100 WARN("Invalid message header received !");
pabloxid 2:dc9184e97328 101 }*/
pabloxid 0:fcceff3299be 102 }
pabloxid 2:dc9184e97328 103 } while (received > 0); //
pabloxid 0:fcceff3299be 104
pabloxid 0:fcceff3299be 105 INFO("Leaving poll function!");
pabloxid 0:fcceff3299be 106 return received;
pabloxid 0:fcceff3299be 107 }
pabloxid 0:fcceff3299be 108
pabloxid 0:fcceff3299be 109 int HTTPServer::receiveLine () {
pabloxid 0:fcceff3299be 110
pabloxid 0:fcceff3299be 111 buffer[0] = 0;
pabloxid 0:fcceff3299be 112
pabloxid 0:fcceff3299be 113 if (!cliente->is_connected()) {
pabloxid 0:fcceff3299be 114 error("NOT Connected anymore");
pabloxid 0:fcceff3299be 115 return ERROR;
pabloxid 0:fcceff3299be 116 }
pabloxid 0:fcceff3299be 117
pabloxid 0:fcceff3299be 118 Timer tm;
pabloxid 0:fcceff3299be 119 int i;
pabloxid 0:fcceff3299be 120
pabloxid 0:fcceff3299be 121 // Try to receive up to the max number of characters
pabloxid 0:fcceff3299be 122 for (i=0; i<BUFFER_SIZE-1; i++) {
pabloxid 0:fcceff3299be 123 int c = cliente->receive (buffer+i, 1);
pabloxid 0:fcceff3299be 124 // Check that - if no character was currently received - the timeout period is reached.
pabloxid 0:fcceff3299be 125 if (c == 0 || c == -1) {
pabloxid 0:fcceff3299be 126 // no character was read, so check if operation timed out
pabloxid 2:dc9184e97328 127 if (tm.read_ms() > 2*TIMEOUT) {
pabloxid 0:fcceff3299be 128 // Operation timed out
pabloxid 0:fcceff3299be 129 INFO("Timeout occured in function 'receiveLine'.");
pabloxid 0:fcceff3299be 130 return ERROR;
pabloxid 0:fcceff3299be 131 }
pabloxid 0:fcceff3299be 132 }
pabloxid 0:fcceff3299be 133 // Check if line terminating character was received
pabloxid 0:fcceff3299be 134 if (buffer[i] == '\n') {break;}
pabloxid 0:fcceff3299be 135 }
pabloxid 0:fcceff3299be 136 // Terminate with \0
pabloxid 0:fcceff3299be 137 buffer[i] = 0;
pabloxid 0:fcceff3299be 138
pabloxid 0:fcceff3299be 139 // Trim for '\r' linefeed at the end
pabloxid 0:fcceff3299be 140 if (i>0 && buffer[i-1] == '\r') {
pabloxid 0:fcceff3299be 141 i--;
pabloxid 0:fcceff3299be 142 buffer[i] = 0;
pabloxid 0:fcceff3299be 143 }
pabloxid 0:fcceff3299be 144
pabloxid 0:fcceff3299be 145 // return number of characters received in the line or return -2 if an empty line was received
pabloxid 0:fcceff3299be 146 if (i==0 || (i==1 && buffer[0]=='\r')) {
pabloxid 0:fcceff3299be 147 // empty line received, so return -2
pabloxid 0:fcceff3299be 148 return EMPTY;
pabloxid 0:fcceff3299be 149 }
pabloxid 0:fcceff3299be 150 // retorna número de caracteres leidos
pabloxid 0:fcceff3299be 151 return i;
pabloxid 0:fcceff3299be 152 }
pabloxid 0:fcceff3299be 153
pabloxid 0:fcceff3299be 154 int HTTPServer::parse () {
pabloxid 0:fcceff3299be 155
pabloxid 0:fcceff3299be 156 // Check if buffer content is not long enough.
pabloxid 0:fcceff3299be 157 if (strlen(buffer) < MIN_LONG) {
pabloxid 0:fcceff3299be 158 ERR("Buffer content is invalid or too short.");
pabloxid 0:fcceff3299be 159 return ERROR;
pabloxid 0:fcceff3299be 160 }
pabloxid 0:fcceff3299be 161
pabloxid 0:fcceff3299be 162 std::vector<std::string> args;
pabloxid 0:fcceff3299be 163
pabloxid 0:fcceff3299be 164 int argno = 0;
pabloxid 0:fcceff3299be 165 // decompose string into a list of arguments
pabloxid 0:fcceff3299be 166 int start = 0; // current starting char
pabloxid 0:fcceff3299be 167 int nLen = strlen(buffer)+1;
pabloxid 0:fcceff3299be 168 for (int i=0; i<nLen; i++) {
pabloxid 0:fcceff3299be 169 if ((buffer[i] == ' ') || (buffer[i] == '\n') || (buffer[i] == 0)) {
pabloxid 0:fcceff3299be 170 // new arg found
pabloxid 0:fcceff3299be 171 buffer[i] = 0;
pabloxid 0:fcceff3299be 172 if (argno++ == 1) {
pabloxid 0:fcceff3299be 173 // it's the uri
pabloxid 0:fcceff3299be 174 // parse the uri args
pabloxid 0:fcceff3299be 175 parseUriArgs (&buffer[start]);
pabloxid 0:fcceff3299be 176 }
pabloxid 0:fcceff3299be 177 INFO("Found argument \"%s\"", &buffer[start]);
pabloxid 0:fcceff3299be 178 args.push_back(&buffer[start]);
pabloxid 0:fcceff3299be 179 start = i+1;
pabloxid 0:fcceff3299be 180 }
pabloxid 0:fcceff3299be 181 }
pabloxid 0:fcceff3299be 182
pabloxid 0:fcceff3299be 183 // store the uri and the HTTP version
pabloxid 0:fcceff3299be 184 msg->uri = args[1];
pabloxid 0:fcceff3299be 185 msg->version = args[2];
pabloxid 0:fcceff3299be 186
pabloxid 0:fcceff3299be 187 // Find matching request type
pabloxid 0:fcceff3299be 188 for (int i=0; i<sizeof(rq_conf)/sizeof(RequestConfig) ; i++) {
pabloxid 0:fcceff3299be 189 if (args.at(0) == rq_conf[i].request_string) {
pabloxid 0:fcceff3299be 190 msg->request = rq_conf[i].request_type;
pabloxid 0:fcceff3299be 191 }
pabloxid 0:fcceff3299be 192 }
pabloxid 0:fcceff3299be 193
pabloxid 0:fcceff3299be 194 return OK;
pabloxid 0:fcceff3299be 195 }
pabloxid 0:fcceff3299be 196
pabloxid 0:fcceff3299be 197 /* esta rutina no se usa */
pabloxid 0:fcceff3299be 198
pabloxid 0:fcceff3299be 199 int HTTPServer::parseHeader () {
pabloxid 0:fcceff3299be 200
pabloxid 0:fcceff3299be 201 // Check if the buffer content is too short to be meaningful
pabloxid 0:fcceff3299be 202 if (strlen(buffer) < MIN_LONG) {return ERROR;}
pabloxid 0:fcceff3299be 203
pabloxid 0:fcceff3299be 204 // decompose string into a touple of <field name> : <field value>
pabloxid 0:fcceff3299be 205 int value_start = 0;
pabloxid 0:fcceff3299be 206 int buflen = strlen(buffer)+1;
pabloxid 0:fcceff3299be 207 for (int i=0; i<buflen; i++) {
pabloxid 0:fcceff3299be 208 if (buffer[i] == ':') {
pabloxid 0:fcceff3299be 209 // touple found
pabloxid 0:fcceff3299be 210 buffer[i] = 0;
pabloxid 0:fcceff3299be 211 value_start = i+1;
pabloxid 0:fcceff3299be 212 msg->headers[buffer] = &buffer[value_start];
pabloxid 0:fcceff3299be 213 INFO("Header name=\"%s\" : value=\"%s\".", buffer, &buffer[value_start]);
pabloxid 0:fcceff3299be 214 return OK;
pabloxid 0:fcceff3299be 215 }
pabloxid 0:fcceff3299be 216 }
pabloxid 0:fcceff3299be 217
pabloxid 0:fcceff3299be 218 ERR("Did not recieve a valid header : \"%s\".", buffer);
pabloxid 0:fcceff3299be 219 return ERROR;
pabloxid 0:fcceff3299be 220 }
pabloxid 0:fcceff3299be 221
pabloxid 0:fcceff3299be 222 int HTTPServer::parseUriArgs (char *uri_buffer) {
pabloxid 0:fcceff3299be 223
pabloxid 0:fcceff3299be 224 // Check if the buffer content is too short to be meaningful
pabloxid 0:fcceff3299be 225 if (strlen(uri_buffer) < MIN_LONG) {return ERROR;}
pabloxid 0:fcceff3299be 226
pabloxid 0:fcceff3299be 227 int args_start = -1;
pabloxid 0:fcceff3299be 228 int value_start = -1;
pabloxid 0:fcceff3299be 229 int buflen = strlen(uri_buffer) + 1;
pabloxid 0:fcceff3299be 230 char* argname = NULL;
pabloxid 0:fcceff3299be 231 char* valuename = NULL;
pabloxid 0:fcceff3299be 232 for (int i=0; i<buflen; i++) {
pabloxid 0:fcceff3299be 233 if (args_start == -1) { // args section not yet found
pabloxid 0:fcceff3299be 234 if (uri_buffer[i] == '?') { // starts with a question mark, so got it
pabloxid 0:fcceff3299be 235 uri_buffer[i] = 0;
pabloxid 0:fcceff3299be 236 args_start = i; // set the start of the args section
pabloxid 0:fcceff3299be 237 INFO("Argument section found !");
pabloxid 0:fcceff3299be 238 }
pabloxid 0:fcceff3299be 239 } else { // search arg-value touples
pabloxid 0:fcceff3299be 240 if (argname == NULL) { // arg-name found ?
pabloxid 0:fcceff3299be 241 if (uri_buffer[i] == '=') {
pabloxid 0:fcceff3299be 242 // yes, separate the arg-name
pabloxid 0:fcceff3299be 243 uri_buffer[i] = 0;
pabloxid 0:fcceff3299be 244 argname = &uri_buffer[args_start];
pabloxid 0:fcceff3299be 245 value_start = i+1;
pabloxid 0:fcceff3299be 246 INFO("Argument name %s", argname);
pabloxid 0:fcceff3299be 247 }
pabloxid 0:fcceff3299be 248 } else { // search for end of value
pabloxid 0:fcceff3299be 249 if ((uri_buffer[i] == '&') || (uri_buffer[i] == 0) || (uri_buffer[i] == '\r') || (uri_buffer[i] == '\n')) {
pabloxid 0:fcceff3299be 250 buffer[i] = 0;
pabloxid 0:fcceff3299be 251 valuename = &uri_buffer[value_start];
pabloxid 0:fcceff3299be 252 INFO("Argument value %s", valuename);
pabloxid 0:fcceff3299be 253 msg->args[argname] = valuename;
pabloxid 0:fcceff3299be 254 // reset all indicators
pabloxid 0:fcceff3299be 255 argname = NULL;
pabloxid 0:fcceff3299be 256 valuename = NULL;
pabloxid 0:fcceff3299be 257 }
pabloxid 0:fcceff3299be 258 }
pabloxid 0:fcceff3299be 259 }
pabloxid 0:fcceff3299be 260 }
pabloxid 0:fcceff3299be 261
pabloxid 0:fcceff3299be 262 return OK;
pabloxid 0:fcceff3299be 263 }
pabloxid 0:fcceff3299be 264
pabloxid 0:fcceff3299be 265 /* verificar qué parte de msg realmente se usa,
pabloxid 0:fcceff3299be 266 eliminar el resto, incluyendo los procesos asociados */
pabloxid 0:fcceff3299be 267
pabloxid 0:fcceff3299be 268 void HTTPServer::handleRequest () {
pabloxid 0:fcceff3299be 269
pabloxid 0:fcceff3299be 270 int err_;
pabloxid 0:fcceff3299be 271
pabloxid 0:fcceff3299be 272 switch (msg->request) {
pabloxid 0:fcceff3299be 273 case HTTP_RT_GET:
pabloxid 0:fcceff3299be 274 INFO("Dispatching GET Request.");
pabloxid 0:fcceff3299be 275 err_ = handleGetRequest();
pabloxid 0:fcceff3299be 276 break;
pabloxid 0:fcceff3299be 277 case HTTP_RT_POST:
pabloxid 0:fcceff3299be 278 INFO("Dispatching POST request.");
pabloxid 0:fcceff3299be 279 err_ = handlePostRequest();
pabloxid 0:fcceff3299be 280 break;
pabloxid 0:fcceff3299be 281 default:
pabloxid 0:fcceff3299be 282 INFO("Error in handleRequest, unhandled request type.");
pabloxid 0:fcceff3299be 283 err_ = 501; // HTTP_NotImplemented
pabloxid 0:fcceff3299be 284 break;
pabloxid 0:fcceff3299be 285 }
pabloxid 0:fcceff3299be 286
pabloxid 0:fcceff3299be 287 // if any of these functions returns a negative number, call the error handler
pabloxid 0:fcceff3299be 288 if (err_ > 0) {
pabloxid 0:fcceff3299be 289 handleError (err_);
pabloxid 0:fcceff3299be 290 }
pabloxid 0:fcceff3299be 291
pabloxid 0:fcceff3299be 292 }
pabloxid 0:fcceff3299be 293
pabloxid 0:fcceff3299be 294 int HTTPServer::handleGetRequest() {
pabloxid 0:fcceff3299be 295
pabloxid 2:dc9184e97328 296 int retval = OK; //success
pabloxid 0:fcceff3299be 297
pabloxid 2:dc9184e97328 298 INFO("Handling Get Request.");
pabloxid 0:fcceff3299be 299
pabloxid 0:fcceff3299be 300 // maping to root path
pabloxid 0:fcceff3299be 301 std::string reqPath = path + msg->uri.substr(1);
pabloxid 0:fcceff3299be 302
pabloxid 0:fcceff3299be 303 // Check if we received a directory with the local path
pabloxid 0:fcceff3299be 304 if (reqPath.substr(reqPath.length()-1, 1) == "/") {
pabloxid 0:fcceff3299be 305 // yes, we shall append the default page name
pabloxid 0:fcceff3299be 306 reqPath += "index.htm";
pabloxid 0:fcceff3299be 307 }
pabloxid 0:fcceff3299be 308
pabloxid 0:fcceff3299be 309 INFO("Mapping \"%s\" to \"%s\"", msg->uri.c_str(), reqPath.c_str());
pabloxid 0:fcceff3299be 310
pabloxid 2:dc9184e97328 311 FILE *file = fopen(reqPath.c_str(), "r");
pabloxid 2:dc9184e97328 312 if (file != NULL) {
pabloxid 0:fcceff3299be 313
pabloxid 2:dc9184e97328 314 // asigna toda la memoria dinámica disponible para 'chunk'
pabloxid 2:dc9184e97328 315 char * chunk = NULL;
pabloxid 2:dc9184e97328 316 int chunk_sz = MAX_CHUNK_SIZE;
pabloxid 2:dc9184e97328 317 while(chunk == NULL) {
pabloxid 2:dc9184e97328 318 chunk_sz /= 2;
pabloxid 2:dc9184e97328 319 chunk = (char*) malloc (chunk_sz);
pabloxid 2:dc9184e97328 320 if (chunk_sz < MIN_CHUNK_SIZE) {
pabloxid 0:fcceff3299be 321 error ("OutOfMemory");
pabloxid 2:dc9184e97328 322 }
pabloxid 0:fcceff3299be 323 }
pabloxid 0:fcceff3299be 324
pabloxid 2:dc9184e97328 325 // File was found and can be returned; first determine the size
pabloxid 2:dc9184e97328 326 fseek (file, 0, SEEK_END);
pabloxid 2:dc9184e97328 327 int size = ftell (file);
pabloxid 2:dc9184e97328 328 fseek (file, 0, SEEK_SET);
pabloxid 0:fcceff3299be 329
pabloxid 2:dc9184e97328 330 startResponse (200, size); // response: 200 = HTTP_Ok
pabloxid 2:dc9184e97328 331 while (!feof(file) && !ferror(file)) {
pabloxid 2:dc9184e97328 332 int count = fread (chunk, 1, chunk_sz , file);
pabloxid 2:dc9184e97328 333 INFO("Processing Response (%d bytes)!", count);
pabloxid 2:dc9184e97328 334 if (cliente->send_all (chunk, count) != count) {
pabloxid 2:dc9184e97328 335 WARN ("Unsent bytes left !"); // TODO: handle filesystem errors
pabloxid 2:dc9184e97328 336 }
pabloxid 0:fcceff3299be 337 }
pabloxid 0:fcceff3299be 338
pabloxid 0:fcceff3299be 339 INFO("Ending Response !");
pabloxid 0:fcceff3299be 340
pabloxid 2:dc9184e97328 341 free (chunk);
pabloxid 2:dc9184e97328 342 fclose (file);
pabloxid 0:fcceff3299be 343
pabloxid 0:fcceff3299be 344 } else {
pabloxid 0:fcceff3299be 345 retval = 404;
pabloxid 0:fcceff3299be 346 ERR("Requested file was not found !");
pabloxid 0:fcceff3299be 347 }
pabloxid 0:fcceff3299be 348
pabloxid 0:fcceff3299be 349 return retval;
pabloxid 0:fcceff3299be 350
pabloxid 0:fcceff3299be 351 }
pabloxid 0:fcceff3299be 352
pabloxid 0:fcceff3299be 353 int HTTPServer::handlePostRequest() {
pabloxid 0:fcceff3299be 354
pabloxid 0:fcceff3299be 355 return 404;
pabloxid 0:fcceff3299be 356 }
pabloxid 0:fcceff3299be 357
pabloxid 0:fcceff3299be 358 static const char hdrStandard[] = "DNT: 1\r\n"
pabloxid 0:fcceff3299be 359 "MaxAge: 0\r\n"
pabloxid 0:fcceff3299be 360 "Connection: Keep-Alive\r\n"
pabloxid 2:dc9184e97328 361 "Content-Type: text/html\r\n" // TODO: handle file types
pabloxid 0:fcceff3299be 362 "Server: mbed embedded\r\n"
pabloxid 0:fcceff3299be 363 "Accessible: 1\r\n"
pabloxid 0:fcceff3299be 364 "\r\n";
pabloxid 0:fcceff3299be 365
pabloxid 2:dc9184e97328 366 void HTTPServer::startResponse (int returnCode, int nLen) {
pabloxid 0:fcceff3299be 367
pabloxid 2:dc9184e97328 368 INFO("Starting response (%d bytes in total)!", nLen);
pabloxid 2:dc9184e97328 369
pabloxid 2:dc9184e97328 370 tcpsend ("HTTP/1.1 %d OK\r\n", returnCode);
pabloxid 2:dc9184e97328 371 tcpsend ("Content-Length: %d\r\n", nLen); // Add 2 chars for the terminating CR+LF
pabloxid 0:fcceff3299be 372 INFO("Sending standard headers !");
pabloxid 2:dc9184e97328 373 tcpsend (hdrStandard);
pabloxid 0:fcceff3299be 374
pabloxid 2:dc9184e97328 375 INFO("Done !");
pabloxid 0:fcceff3299be 376
pabloxid 0:fcceff3299be 377 }
pabloxid 0:fcceff3299be 378
pabloxid 0:fcceff3299be 379 static const char* errorPage = "<HTML><HEAD><META content=\"text/html\" http-equiv=Content-Type></HEAD><BODY><h1>Error</h1><P>HTTPServer Error<P></BODY></HTML>\r\n\r\n";
pabloxid 0:fcceff3299be 380
pabloxid 0:fcceff3299be 381 void HTTPServer::handleError (int errorCode) {
pabloxid 0:fcceff3299be 382
pabloxid 0:fcceff3299be 383 INFO("Handling error !");
pabloxid 0:fcceff3299be 384
pabloxid 2:dc9184e97328 385 tcpsend ("HTTP/1.1 %d Error\r\n", errorCode);
pabloxid 2:dc9184e97328 386 tcpsend ("Content-Length: %d\r\n", strlen(errorPage));
pabloxid 2:dc9184e97328 387 tcpsend ("Content-Type: text/html\r\nServer: mbed embedded\r\n\r\n");
pabloxid 2:dc9184e97328 388 tcpsend (errorPage); // TODO: better error page (handle error type)
pabloxid 0:fcceff3299be 389
pabloxid 0:fcceff3299be 390 INFO("Done !");
pabloxid 0:fcceff3299be 391
pabloxid 0:fcceff3299be 392 }