handle invalid upload

pull/193/head
Karai Csaba 9 years ago committed by Thorsten von Eicken
parent 40e7fba786
commit 29b691757e
  1. 23
      esp-link/cgiwebserver.c
  2. 35
      httpd/multipart.c
  3. 5
      httpd/multipart.h

@ -5,27 +5,40 @@
#include "cgi.h" #include "cgi.h"
#include "cgioptiboot.h" #include "cgioptiboot.h"
#include "multipart.h" #include "multipart.h"
#include "espfsformat.h"
void webServerMultipartCallback(MultipartCmd cmd, char *data, int dataLen, int position) int webServerMultipartCallback(MultipartCmd cmd, char *data, int dataLen, int position)
{ {
switch(cmd) switch(cmd)
{ {
case FILE_START: case FILE_START:
os_printf("CB: File start: %s\n", data); // do nothing
break; break;
case FILE_DATA: case FILE_DATA:
os_printf("CB: Data (%d): %s\n", position, data); if( position < 4 )
{
for(int p = position; p < 4; p++ )
{
if( data[p - position] != ((ESPFS_MAGIC >> (p * 8) ) & 255 ) )
{
os_printf("Not an espfs image!\n");
return 1;
}
data[p - position] = 0xFF; // clean espfs magic to mark as invalid
}
}
// TODO: flash write
break; break;
case FILE_DONE: case FILE_DONE:
os_printf("CB: Done\n"); // TODO: finalize changes, set back espfs magic
break; break;
} }
return 0;
} }
MultipartCtx webServerContext = {.callBack = webServerMultipartCallback, .position = 0, .recvPosition = 0, .startTime = 0, .boundaryBuffer = NULL}; MultipartCtx webServerContext = {.callBack = webServerMultipartCallback, .position = 0, .recvPosition = 0, .startTime = 0, .boundaryBuffer = NULL};
int ICACHE_FLASH_ATTR cgiWebServerUpload(HttpdConnData *connData) int ICACHE_FLASH_ATTR cgiWebServerUpload(HttpdConnData *connData)
{ {
os_printf("WebServer upload\n");
return multipartProcess(&webServerContext, connData); return multipartProcess(&webServerContext, connData);
} }

@ -22,7 +22,7 @@ void multipartFreeBoundaryBuffer(MultipartCtx * context)
} }
} }
void multipartProcessBoundaryBuffer(MultipartCtx * context, char * boundary, char * buff, int len, int last) int multipartProcessBoundaryBuffer(MultipartCtx * context, char * boundary, char * buff, int len, int last)
{ {
if( len != 0 ) if( len != 0 )
{ {
@ -35,7 +35,7 @@ void multipartProcessBoundaryBuffer(MultipartCtx * context, char * boundary, cha
while( context->boundaryBufferPtr > 0 ) while( context->boundaryBufferPtr > 0 )
{ {
if( ! last && context->boundaryBufferPtr <= 2 * BOUNDARY_SIZE ) if( ! last && context->boundaryBufferPtr <= 2 * BOUNDARY_SIZE )
return; return 0;
int dataSize = BOUNDARY_SIZE; int dataSize = BOUNDARY_SIZE;
@ -96,7 +96,8 @@ void multipartProcessBoundaryBuffer(MultipartCtx * context, char * boundary, cha
{ {
context->boundaryBuffer[pos] = 0; context->boundaryBuffer[pos] = 0;
os_printf("Uploading file: %s\n", context->boundaryBuffer + start); os_printf("Uploading file: %s\n", context->boundaryBuffer + start);
context->callBack( FILE_START, context->boundaryBuffer + start, pos - start, 0 ); if( context->callBack( FILE_START, context->boundaryBuffer + start, pos - start, 0 ) )
return 1;
context->boundaryBuffer[pos] = '"'; context->boundaryBuffer[pos] = '"';
context->state = STATE_SEARCH_HEADER_END; context->state = STATE_SEARCH_HEADER_END;
} }
@ -111,7 +112,8 @@ void multipartProcessBoundaryBuffer(MultipartCtx * context, char * boundary, cha
{ {
char c = context->boundaryBuffer[dataSize]; char c = context->boundaryBuffer[dataSize];
context->boundaryBuffer[dataSize] = 0; // add terminating zero (for easier handling) context->boundaryBuffer[dataSize] = 0; // add terminating zero (for easier handling)
context->callBack( FILE_DATA, context->boundaryBuffer, dataSize, context->position ); if( context->callBack( FILE_DATA, context->boundaryBuffer, dataSize, context->position ) )
return 1;
context->boundaryBuffer[dataSize] = c; context->boundaryBuffer[dataSize] = c;
context->position += dataSize; context->position += dataSize;
} }
@ -126,7 +128,8 @@ void multipartProcessBoundaryBuffer(MultipartCtx * context, char * boundary, cha
dataSize += os_strlen(boundary); dataSize += os_strlen(boundary);
if( context->state == STATE_UPLOAD_FILE ) if( context->state == STATE_UPLOAD_FILE )
{ {
context->callBack( FILE_DONE, NULL, 0, context->position ); if( context->callBack( FILE_DONE, NULL, 0, context->position ) )
return 1;
os_printf("File upload done\n"); os_printf("File upload done\n");
} }
@ -136,6 +139,7 @@ void multipartProcessBoundaryBuffer(MultipartCtx * context, char * boundary, cha
context->boundaryBufferPtr -= dataSize; context->boundaryBufferPtr -= dataSize;
os_memcpy(context->boundaryBuffer, context->boundaryBuffer + dataSize, context->boundaryBufferPtr); os_memcpy(context->boundaryBuffer, context->boundaryBuffer + dataSize, context->boundaryBufferPtr);
} }
return 0;
} }
int ICACHE_FLASH_ATTR multipartProcess(MultipartCtx * context, HttpdConnData * connData ) int ICACHE_FLASH_ATTR multipartProcess(MultipartCtx * context, HttpdConnData * connData )
@ -162,25 +166,42 @@ int ICACHE_FLASH_ATTR multipartProcess(MultipartCtx * context, HttpdConnData * c
multipartAllocBoundaryBuffer(context); multipartAllocBoundaryBuffer(context);
} }
if( context->state != STATE_ERROR )
{
int feed = 0; int feed = 0;
while( feed < post->buffLen ) while( feed < post->buffLen )
{ {
int len = post->buffLen - feed; int len = post->buffLen - feed;
if( len > BOUNDARY_SIZE ) if( len > BOUNDARY_SIZE )
len = BOUNDARY_SIZE; len = BOUNDARY_SIZE;
multipartProcessBoundaryBuffer(context, post->multipartBoundary, post->buff + feed, len, 0); if( multipartProcessBoundaryBuffer(context, post->multipartBoundary, post->buff + feed, len, 0) )
{
context->state = STATE_ERROR;
break;
}
feed += len; feed += len;
} }
}
context->recvPosition += post->buffLen; context->recvPosition += post->buffLen;
if( context->recvPosition < post->len ) if( context->recvPosition < post->len )
return HTTPD_CGI_MORE; return HTTPD_CGI_MORE;
multipartProcessBoundaryBuffer(context, post->multipartBoundary, NULL, 0, 1); if( context->state != STATE_ERROR )
{
if( multipartProcessBoundaryBuffer(context, post->multipartBoundary, NULL, 0, 1) )
context->state = STATE_ERROR;
}
multipartFreeBoundaryBuffer( context ); multipartFreeBoundaryBuffer( context );
if( context->state == STATE_ERROR )
errorResponse(connData, 400, "Invalid file upload!");
else
{
httpdStartResponse(connData, 204); httpdStartResponse(connData, 204);
httpdEndHeaders(connData); httpdEndHeaders(connData);
}
return HTTPD_CGI_DONE; return HTTPD_CGI_DONE;
} }
else { else {

@ -13,10 +13,11 @@ typedef enum {
STATE_SEARCH_BOUNDARY = 0, STATE_SEARCH_BOUNDARY = 0,
STATE_SEARCH_HEADER, STATE_SEARCH_HEADER,
STATE_SEARCH_HEADER_END, STATE_SEARCH_HEADER_END,
STATE_UPLOAD_FILE STATE_UPLOAD_FILE,
STATE_ERROR,
} MultipartState; } MultipartState;
typedef void (* MultipartCallback)(MultipartCmd cmd, char *data, int dataLen, int position); typedef int (* MultipartCallback)(MultipartCmd cmd, char *data, int dataLen, int position);
typedef struct { typedef struct {
MultipartCallback callBack; MultipartCallback callBack;

Loading…
Cancel
Save