Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of SW_HTTPServer by
Diff: SW_HTTPServer.cpp
- Revision:
- 27:90a1f5a5392f
- Parent:
- 26:38102ef2b132
- Child:
- 28:f93ef41b78e1
--- a/SW_HTTPServer.cpp Thu Oct 10 18:46:55 2013 +0000 +++ b/SW_HTTPServer.cpp Thu Oct 10 20:38:12 2013 +0000 @@ -14,7 +14,20 @@ #include "SW_HTTPServer.h" #include "Utility.h" -#define DEBUG +#define DEBUG "HTTP" + +#if (defined(DEBUG) && !defined(TARGET_LPC11U24)) +#define DBG(x, ...) std::printf("[DBG %s%4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); +#define WARN(x, ...) std::printf("[WRN %s%4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); +#define ERR(x, ...) std::printf("[ERR %s%4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); +#define INFO(x, ...) std::printf("[INF %s%4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); +#else +#define DBG(x, ...) +#define WARN(x, ...) +#define ERR(x, ...) +#define INFO(x, ...) +#endif + const char * DEFAULT_FILENAME = "index.htm"; @@ -87,6 +100,8 @@ wifly = _wf; webroot = (char *)malloc(strlen(_webroot)+1); strcpy(webroot, _webroot); + if (strlen(webroot)>1 && webroot[strlen(webroot)-1] == '/') // remove trailing '/' + webroot[strlen(webroot)-1] = '\0'; maxqueryParams = _maxqueryParams; maxdynamicpages = _maxdynamicpages; headerParams = (namevalue *)malloc(maxheaderParams * sizeof(namevalue)); @@ -168,7 +183,7 @@ static state lastOp = Reset; if (lastOp != op) { const char *states[] = {"Idle", "Receiving", "Sending", "WaitingToClose", "Reset"}; - pc->printf("Poll: %s\r\n", states[op]); + INFO("Poll: %s", states[op]); lastOp = op; } #endif @@ -184,26 +199,20 @@ if (0 == server->accept(client)) { op = Receiving; t_ref = RecordPerformanceData(&perfData.ConnectionAccepted, t_ref); -#ifdef DEBUG - pc->printf("Accepted at %u\r\n", (unsigned int)PerformanceTimer.read_us()); -#endif + INFO("Accepted at %u", (unsigned int)PerformanceTimer.read_us()); } break; case Receiving: n = client.receive(bPtr, headerbuffersize - (bPtr - headerbuffer)); if (n < 0) { -#ifdef DEBUG - pc->printf("*** client.receive() => %d\r\n", n); -#endif + INFO("*** client.receive() => %d", n); } else if (n) { bPtr[n] = '\0'; if (ParseHeader(headerbuffer)) { op = Sending; t_ref = RecordPerformanceData(&perfData.HeaderParsed, t_ref); -#ifdef DEBUG - pc->printf("Header Parsed at %u\r\n", (unsigned int)PerformanceTimer.read_us()); -#endif + INFO("Header Parsed at %u", (unsigned int)PerformanceTimer.read_us()); } bPtr += n; } @@ -213,21 +222,15 @@ SendResponse(); op = WaitingToClose; t_ref = RecordPerformanceData(&perfData.ResponseSent, t_ref); -#ifdef DEBUG - pc->printf("Response Sent at %u\r\n", (unsigned int)PerformanceTimer.read_us()); -#endif + INFO("Response Sent at %u", (unsigned int)PerformanceTimer.read_us()); break; case WaitingToClose: -#ifdef DEBUG - pc->printf("Connection closed entry %u\r\n", (unsigned int)PerformanceTimer.read_us()); -#endif + INFO("Connection closed entry %u", (unsigned int)PerformanceTimer.read_us()); close_connection(); op = Idle; RecordPerformanceData(&perfData.ConnectionClosed, t_ref); -#ifdef DEBUG - pc->printf("Connection closed exit %u\r\n", (unsigned int)PerformanceTimer.read_us()); -#endif + INFO("Connection closed exit %u", (unsigned int)PerformanceTimer.read_us()); break; } } @@ -397,9 +400,7 @@ bool res; res = server->close(); -#ifdef DEBUG - pc->printf("close connection returned %d\r\n", res); -#endif + INFO("close connection returned %d", res); return res; } @@ -427,9 +428,7 @@ if (eqs) *eqs = '\0'; *string = container; -#ifdef DEBUG - pc->printf("Extract(%s) = %s\r\n", needle, container); -#endif + INFO("Extract(%s) = %s", needle, container); ret = true; } else { *string = NULL; // something bad happened... no memory @@ -495,9 +494,7 @@ void HTTPServer::SendResponse() { -#ifdef DEBUG - pc->printf("SendResponse(%s) at %u\r\n", queryType, (unsigned int)PerformanceTimer.read_us()); -#endif + INFO("SendResponse(%s) at %u", queryType, (unsigned int)PerformanceTimer.read_us()); if (strcmp(queryType, "GET") == 0 || strcmp(queryType, "POST") == 0) { if (!(queryString[0] == '.' && queryString[1] == '.')) { const char * fType; @@ -522,9 +519,7 @@ } else { header(400, "Bad Request", "Pragma: err - Unsupported query type\r\n"); } -#ifdef DEBUG - pc->printf(" SendResponse complete at %u\r\n", (unsigned int)PerformanceTimer.read_us()); -#endif + INFO(" SendResponse complete at %u", (unsigned int)PerformanceTimer.read_us()); if (queryType) { myfree(queryType); @@ -538,9 +533,7 @@ myfree(postQueryString); postQueryString = NULL; } -#ifdef DEBUG - pc->printf(" SendResponse free at %u\r\n", (unsigned int)PerformanceTimer.read_us()); -#endif + INFO(" SendResponse free at %u", (unsigned int)PerformanceTimer.read_us()); } @@ -556,9 +549,7 @@ // GET /QueryString HTTP/1.1\r\nHost: 192.168.1.140\r\nCache-Control: max-age=0\r\n\r\n dblCR = strstr(buffer,"\r\n\r\n"); if (dblCR) { // Have to scan from the beginning in case split on \r -#ifdef DEBUG - pc->printf("==\r\n%s==\r\n", buffer); -#endif + INFO("==\r\n%s==\r\n", buffer); char * soRec = buffer; // start of the next record of text char * eoRec = strchr(soRec, '\n'); // search for end of the current record @@ -597,10 +588,8 @@ *delim++ = '\0'; headerParams[headerParamCount].name = soRec; headerParams[headerParamCount].value = delim; -#ifdef DEBUG - pc->printf("%d: headerParams[%s] = {%s}\r\n", headerParamCount, + INFO("%d: headerParams[%s] = {%s}", headerParamCount, headerParams[headerParamCount].name, headerParams[headerParamCount].value); -#endif headerParamCount++; } soRec = eoRec + 1; @@ -608,9 +597,7 @@ } if (queryString) { // We have enough to try to reply -#ifdef DEBUG - pc->printf("create reply queryType{%s}, queryString{%s}\r\n", "GET", queryString); -#endif + INFO("create reply queryType{%s}, queryString{%s}", "GET", queryString); // parse queryParams - if any // /file.htm?name1=value1&name2=value2... // /file.htm?name1&name2=value2... @@ -622,7 +609,7 @@ ParseParameters(paramDelim); // pointing at the NULL, but there are queryParams beyond } } else { - pc->printf("ERROR: queryString not found in (%s)\r\n", soRec); + ERR("queryString not found in (%s)", soRec); } advanceState = true; buffer[0] = 0; @@ -638,18 +625,26 @@ bool acceptIt = false; if (strcmp(queryType, "POST") == 0 && postBytes > 0 ) { if (postBytes) { + int ndxHandler = 0; bool regHandled = false; // Registered Dynamic Handler // Callback and ask if they want to accept this data - for (int i=0; i<handlercount; i++) { - if (strcmp(handlers[i].path, queryString) == 0) { - acceptIt = (*handlers[i].callback)(this, CONTENT_LENGTH_REQUEST, queryString, queryParams, queryParamCount); + for (ndxHandler=0; ndxHandler<handlercount; ndxHandler++) { + if (strcmp(handlers[ndxHandler].path, queryString) == 0) { + acceptIt = (*handlers[ndxHandler].callback)(this, CONTENT_LENGTH_REQUEST, queryString, queryParams, queryParamCount); regHandled = true; break; // we only execute the first one } } if (regHandled && acceptIt) { + // @todo need to refactor - if the thing is bigger than the buffer, + // then we can receive it a chunk at a time, and hand off + // the chunks to the callback. May need callbacks that + // are: START: extract the filename/object name, + // NEXT: a chunk of data, + // END: signals that all chunks were delivered. + // // If so, we'll make space for it postQueryString = (char *)mymalloc(postBytes + 1); if (postQueryString) { @@ -666,12 +661,22 @@ n = client.receive(offset, postBytes - len); if (n >=0) { offset[n] = '\0'; + //printf("HTTPd: %d of %d: [%s]\r\n", len, postBytes, offset); + } else if (n < 0) { + //printf("HTTPd: n=%d\r\n", n); + break; // no more data, before the plan } } if (len >= 0) { - UnescapeString(postQueryString); - ParseParameters(postQueryString); +// UnescapeString(postQueryString); +// ParseParameters(postQueryString); + // use the same handler as for the length check + acceptIt = (*handlers[ndxHandler].callback)(this, DATA_TRANSFER, postQueryString, NULL, 0); + } else { + ERR("HTTPd: len error."); } + } else { + ERR("HTTPd: attempt to allocate %d failed.", postBytes+1); } } else { // Simply copy it to the bitbucket @@ -695,6 +700,7 @@ } + const char * HTTPServer::GetHeaderValue(const char * hdr) { int i;