|  |  |  | @ -259,7 +259,7 @@ class WEBServer : public TCPServer<T>, public HttpConstants | 
		
	
		
			
				|  |  |  |  |                   break; | 
		
	
		
			
				|  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 //Before in the buffer : key1: value1\r\nkey2: value2
 | 
		
	
		
			
				|  |  |  |  |                 //Before in the buffer : key1: value1\0\nkey2: value2
 | 
		
	
		
			
				|  |  |  |  |                 //After in the buffer : key2: value2\r\n
 | 
		
	
		
			
				|  |  |  |  |                 client->freeDataBuffer((pEndLine - (char *)client->_data) + 2); | 
		
	
		
			
				|  |  |  |  |               } | 
		
	
	
		
			
				
					
					|  |  |  | @ -317,77 +317,27 @@ class WEBServer : public TCPServer<T>, public HttpConstants | 
		
	
		
			
				|  |  |  |  |       #endif | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       //Here we check if we have interesting params
 | 
		
	
		
			
				|  |  |  |  |       char *search = strstr((char *)client->_data, "t-Type: application/x-www-form-urlen"); | 
		
	
		
			
				|  |  |  |  |       if(search != NULL) | 
		
	
		
			
				|  |  |  |  |       char *contentTypeP = strstr((char *)client->_data, "t-Type: application/x-www-form-urlen"); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       if(contentTypeP != NULL) | 
		
	
		
			
				|  |  |  |  |       { | 
		
	
		
			
				|  |  |  |  |         #ifdef DEBUG_WEBS | 
		
	
		
			
				|  |  |  |  |         Serial.printf("Content-Type : APPLICATION_X_WWW_FORM_URLENCODED\n"); | 
		
	
		
			
				|  |  |  |  |         Serial.printf("Data is of type : APPLICATION_X_WWW_FORM_URLENCODED\n"); | 
		
	
		
			
				|  |  |  |  |         #endif | 
		
	
		
			
				|  |  |  |  |         client->_httpRequestData.HMT = APPLICATION_X_WWW_FORM_URLENCODED; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |        | 
		
	
		
			
				|  |  |  |  |       search = strstr((char *)client->_data, "ion: keep-al"); | 
		
	
		
			
				|  |  |  |  |       if(search != NULL) | 
		
	
		
			
				|  |  |  |  |       //Range part for file downloads
 | 
		
	
		
			
				|  |  |  |  |       /*char *startingP = strstr((char *)client->_data, "nge: bytes="), *endP = strchr((char *)client->_data, '-');
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       if(startingP != NULL && endP != NULL) | 
		
	
		
			
				|  |  |  |  |       { | 
		
	
		
			
				|  |  |  |  |         endP = '\0'; | 
		
	
		
			
				|  |  |  |  |         client->_range = strtoul(startingP + 11,NULL, 10); | 
		
	
		
			
				|  |  |  |  |         #ifdef DEBUG_WEBS | 
		
	
		
			
				|  |  |  |  |         Serial.printf("Connection : keep-alive\n"); | 
		
	
		
			
				|  |  |  |  |         Serial.printf("Range : %d\n", client->_range); | 
		
	
		
			
				|  |  |  |  |         #endif | 
		
	
		
			
				|  |  |  |  |         client->_keepAlive = true; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |        | 
		
	
		
			
				|  |  |  |  |       //Range part for file downloads and media playback
 | 
		
	
		
			
				|  |  |  |  |       search = strstr((char *)client->_data, "nge: bytes="); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       if(search != NULL) | 
		
	
		
			
				|  |  |  |  |       { | 
		
	
		
			
				|  |  |  |  |         //We parse the range byte data
 | 
		
	
		
			
				|  |  |  |  |         if(fillRangeByteStruct(client)) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |           #ifdef DEBUG_WEBS | 
		
	
		
			
				|  |  |  |  |           Serial.printf("Range (bytes) data : start -> %u ; end -> %u\n", client->_rangeData._rangeStart, client->_rangeData._rangeEnd); | 
		
	
		
			
				|  |  |  |  |           #endif | 
		
	
		
			
				|  |  |  |  |           client->_rangeData._rangeRequest = true; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         else | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |           #ifdef DEBUG_WEBS | 
		
	
		
			
				|  |  |  |  |           Serial.printf("Range (bytes) data parse error : start -> %u ; end -> %u\n", client->_rangeData._rangeStart, client->_rangeData._rangeEnd); | 
		
	
		
			
				|  |  |  |  |           #endif | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     /*
 | 
		
	
		
			
				|  |  |  |  |      * This function fills the client's _rangeData struct with proper values | 
		
	
		
			
				|  |  |  |  |      */ | 
		
	
		
			
				|  |  |  |  |     bool fillRangeByteStruct(T *client) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       char *rangeStart = strchr((char *)client->_data, '='), *delimiter = strchr((char *)client->_data, '-'), *check(nullptr); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       if(!rangeStart)return false; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       rangeStart++; //We move one char forward
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       //We parse the 1st part of the range byte
 | 
		
	
		
			
				|  |  |  |  |       if(!delimiter) // If only one part (ill-formed)
 | 
		
	
		
			
				|  |  |  |  |       { | 
		
	
		
			
				|  |  |  |  |         client->_rangeData._rangeStart = strtoull(rangeStart, &check, 10); | 
		
	
		
			
				|  |  |  |  |         if(*check != '\0')return false; | 
		
	
		
			
				|  |  |  |  |         return true; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  |       else | 
		
	
		
			
				|  |  |  |  |       { | 
		
	
		
			
				|  |  |  |  |         *delimiter = '\0'; | 
		
	
		
			
				|  |  |  |  |         client->_rangeData._rangeStart = strtoull(rangeStart, &check, 10); | 
		
	
		
			
				|  |  |  |  |         if(*check != '\0')return false; | 
		
	
		
			
				|  |  |  |  |       } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       rangeStart = delimiter+1; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       //We parse the 2nd part of the range byte
 | 
		
	
		
			
				|  |  |  |  |       client->_rangeData._rangeEnd = strtoull(rangeStart, &check, 10); | 
		
	
		
			
				|  |  |  |  |       if(*check != '\0')return false; | 
		
	
		
			
				|  |  |  |  |       return true; | 
		
	
		
			
				|  |  |  |  |       }*/ | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     /*
 | 
		
	
	
		
			
				
					
					|  |  |  | @ -581,29 +531,12 @@ class WEBServer : public TCPServer<T>, public HttpConstants | 
		
	
		
			
				|  |  |  |  |               return false; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |             if(client->_fileSentBytes == 0) | 
		
	
		
			
				|  |  |  |  |             if(client->_fileSentBytes == 0 /*&& client->_range == 0*/) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |               size_t pageToSendSize(pageToSend.size()); | 
		
	
		
			
				|  |  |  |  |               char *fileName = (char *) malloc(sizeof(char) * strlen(pageToSend.name()) + 1);  | 
		
	
		
			
				|  |  |  |  |                | 
		
	
		
			
				|  |  |  |  |               if(fileName == NULL) | 
		
	
		
			
				|  |  |  |  |               { | 
		
	
		
			
				|  |  |  |  |                 sendInfoResponse(HTTP_CODE::HTTP_CODE_INTERNAL_SERVER_ERROR, client, "Failed to allocate memory for the response"); | 
		
	
		
			
				|  |  |  |  |                 pageToSend.close(); | 
		
	
		
			
				|  |  |  |  |                 return false; | 
		
	
		
			
				|  |  |  |  |               } | 
		
	
		
			
				|  |  |  |  |               strcpy(fileName, pageToSend.name()); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |               if(client->_rangeData._rangeRequest) | 
		
	
		
			
				|  |  |  |  |               { | 
		
	
		
			
				|  |  |  |  |                 client->_fileSentBytes = client->_rangeData._rangeStart; | 
		
	
		
			
				|  |  |  |  |                 client->_rangeData._rangeEnd = !client->_rangeData._rangeEnd ? pageToSendSize - 1 : client->_rangeData._rangeEnd; | 
		
	
		
			
				|  |  |  |  |                 pageToSend.seek(client->_fileSentBytes); | 
		
	
		
			
				|  |  |  |  |               } | 
		
	
		
			
				|  |  |  |  |               else | 
		
	
		
			
				|  |  |  |  |                 client->_rangeData._rangeEnd = pageToSendSize - 1; //Needed to carry on sending when not a partial file
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |               header = getHTTPHeader(getMIMETypeByExtension(strlwr(getFileExtension(fileName))), pageToSendSize, client->_rangeData._rangeRequest, client->_rangeData._rangeStart, client->_rangeData._rangeEnd); | 
		
	
		
			
				|  |  |  |  |               if(fileName != NULL)strcpy(fileName, pageToSend.name()); | 
		
	
		
			
				|  |  |  |  |               header = getHTTPHeader(getMIMETypeByExtension(strlwr(getFileExtension(fileName))), pageToSend.size()); | 
		
	
		
			
				|  |  |  |  |                | 
		
	
		
			
				|  |  |  |  |               #ifdef DEBUG_WEBS | 
		
	
		
			
				|  |  |  |  |               Serial.print("FILE EXTENSION : "); | 
		
	
	
		
			
				
					
					|  |  |  | @ -620,15 +553,19 @@ class WEBServer : public TCPServer<T>, public HttpConstants | 
		
	
		
			
				|  |  |  |  |               } | 
		
	
		
			
				|  |  |  |  |                | 
		
	
		
			
				|  |  |  |  |               client->_client.print(header); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |               free(header);header = NULL; | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |             /*else if(client->_fileSentBytes == 0 && (!client->_range == 0))
 | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |               client->_fileSentBytes = client->_range-500; | 
		
	
		
			
				|  |  |  |  |               Serial.println("RANGE SET"); | 
		
	
		
			
				|  |  |  |  |             }*/ | 
		
	
		
			
				|  |  |  |  |             else | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |               pageToSend.seek(client->_fileSentBytes); | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |              | 
		
	
		
			
				|  |  |  |  |             if(pageToSend.available() && client->_fileSentBytes < client->_rangeData._rangeEnd + 1) // File is done sending once the whole file was sent or the partial part is done sending
 | 
		
	
		
			
				|  |  |  |  |             if(pageToSend.available()) | 
		
	
		
			
				|  |  |  |  |             { | 
		
	
		
			
				|  |  |  |  |               readBytes = pageToSend.read(sendBuffer,READ_WRITE_BUFFER_SIZE); | 
		
	
		
			
				|  |  |  |  |               client->_client.write(sendBuffer, readBytes); | 
		
	
	
		
			
				
					
					|  |  |  | @ -725,23 +662,20 @@ class WEBServer : public TCPServer<T>, public HttpConstants | 
		
	
		
			
				|  |  |  |  |       else return UNKNOWN_MIME; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |     static char *getHTTPHeader(HttpMIMEType httpMIMEType, const size_t contentLength, bool acceptRanges = false, size_t rangeStart = 0, size_t rangeEnd = 0) | 
		
	
		
			
				|  |  |  |  |     static char *getHTTPHeader(HttpMIMEType httpMIMEType, const size_t size) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       size_t headerToAllocSize(/*strlen("HTTP/1.1 200 OK\r\nContent-Type: \r\nContent-Length: \r\nCache-Control: max-age=31536000\r\n\r\n")*/86 + 255/*Longest MIME-TYPE that RFC allows*/ + 10 /*Max unsigned long footprint*/ + 1 /*\0 character*/); | 
		
	
		
			
				|  |  |  |  |       if(acceptRanges)headerToAllocSize += (22 + 25 + 10*3 + 13); //"Accept-Ranges: bytes\r\n" is 22 characters + "Content-Range: bytes %u-%u/%u\r\n" + 3*Max unsigned long footprint + space for 206 Partial Content
 | 
		
	
		
			
				|  |  |  |  |       char *header = (char *) malloc(sizeof(char) /*strlen("HTTP/1.1 200 OK\r\nContent-Type: \r\nContent-Length: \r\nCache-Control: max-age=31536000\r\n\r\n")*/* (86 + 255/*Longest MIME-TYPE that RFC allows*/ + 10 /*Max unsigned long footprint*/ + 1)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       char *header = (char *) malloc(sizeof(char) * headerToAllocSize); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       if(!header)return NULL; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       if(!acceptRanges) | 
		
	
		
			
				|  |  |  |  |         sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %u\r\nCache-Control: max-age=31536000\r\n\r\n", httpMIMETypeToString(httpMIMEType), contentLength); | 
		
	
		
			
				|  |  |  |  |       else | 
		
	
		
			
				|  |  |  |  |         sprintf(header,"HTTP/1.1 206 Partial Content\r\nContent-Type: %s\r\nAccept-Ranges: bytes\r\nContent-Length: %u\r\nContent-Range: bytes %u-%u/%u\r\nCache-Control: max-age=31536000\r\n\r\n", httpMIMETypeToString(httpMIMEType), rangeEnd-rangeStart+1,rangeStart ,rangeEnd, contentLength); | 
		
	
		
			
				|  |  |  |  |       injectHeaderLayout(header, httpMIMETypeToString(httpMIMEType), size); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |       return header; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     static void injectHeaderLayout(char *header, const char *contentType, const size_t size) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       sprintf(header,"HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %u\r\nCache-Control: max-age=31536000\r\n\r\n", contentType, size); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |     static char *getFileExtension(char *name) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       char *p(lastIndexOf(name, '.')); | 
		
	
	
		
			
				
					
					|  |  |  | 
 |