static void file_uploader_handler(TinyWebServer& web_server, TinyWebPutHandler::PutAction action, char* buffer, int size) { static char *boundary = NULL; static size_t boundary_len = 0; static CircularBuffer<char, 128> cb; static enum state { search_begin=0, search_data, search_filename, in_filename, in_data} st; static int file_size = 0; static String fname = ""; const char *ct; switch (action) { case TinyWebPutHandler::START: { ct = web_server.get_header_value("Content-Type"); if (!ct) { Serial << F("Missing Content-Type\n"); break; } boundary = strstr(ct, "boundary="); if (!boundary) { Serial << F("Missing boundary= in '") << ct << "'\n"; break; } boundary += 5; boundary[0] = '\r'; boundary[1] = '\n'; boundary[2] = '-'; boundary[3] = '-'; boundary_len = strlen(boundary); D(Serial.print("**** Upload file ")); D(Serial.println(fname)); st = search_begin; file_size = 0; lduino.setStatus(F("Loading new ladder program")); break; } static char *fname_tag = "filename=\""; case TinyWebPutHandler::WRITE: for (int i = 0; i < size; i++) { D(Serial.write(*buffer)); switch(st) { case search_begin: cb.push(*buffer++); if (cb.remain() < boundary_len-2) break; if (cb.match(boundary+2, boundary_len-2)) { st = search_filename; D(Serial.println("search_filename")); cb.flush(); fname = ""; } else { cb.pop(); } break; case search_filename: cb.push(*buffer++); if (cb.remain() < strlen(fname_tag)) break; if (cb.match(fname_tag, strlen(fname_tag))) { st = in_filename; D(Serial.println("in_filename")); cb.flush(); } else { cb.pop(); } break; case in_filename: if (*buffer == '\"') { buffer++; st = search_data; D(Serial << F("fname=") << fname << "\n"); D(Serial.println("search_data")); } else { fname += *buffer++; } break; case search_data: cb.push(*buffer++); if (cb.remain() < 4) break; if (cb.match("\r\n\r\n", 4)) { st = in_data; D(Serial.println("in_data")); cb.flush(); } else { cb.pop(); } break; case in_data: cb.push(*buffer++); if (cb.remain() < boundary_len) break; if (cb.match(boundary, boundary_len)) { st = search_data; D(Serial.println("search_data")); cb.flush(); } else { if (file_size == 0) lduino.ClearProgram(); char c = cb.pop(); file_size++; lduino.LoadProgramLine(c); } break; }; } break; case TinyWebPutHandler::END: D(Serial.println("**** END")); D(Serial.print("file size ")); D(Serial.println(file_size)); Client& client = web_server.get_client(); String status; if (file_size > 0 && lduino.getProgramReady()) { status += fname; status += F(" loaded"); } else { status += F("Upload failure"); } Serial << status << '\n'; lduino.setStatus(status); //main_page(client, status); break; } }
static void file_uploader_handler(TinyWebServer& web_server, TinyWebPutHandler::PutAction action, char* buffer, int size) { static char *boundary = NULL; static size_t boundary_len = 0; static CircularBuffer<char, 128> cb; static enum state { search_begin=0, search_data, in_data} st; static int file_size = 0; static char *fname; switch (action) { case TinyWebPutHandler::START: { fname = web_server.get_file_from_path(web_server.get_path()); const char *ct = web_server.get_header_value("Content-Type"); if (!ct) break; boundary = strstr(ct, "boundary="); if (!boundary) break; boundary += 5; boundary[0] = '\r'; boundary[1] = '\n'; boundary[2] = '-'; boundary[3] = '-'; boundary_len = strlen(boundary); D(Serial.print("**** Upload file ")); D(Serial.println(fname)); free(fname); st = search_begin; file_size = 0; break; } case TinyWebPutHandler::WRITE: for (int i = 0; i < size; i++) { D(Serial.write(*buffer)); cb.push(*buffer++); switch(st) { case search_begin: if (cb.remain() < boundary_len-2) break; if (cb.match(boundary+2, boundary_len-2)) { st = search_data; D(Serial.println("search_data")); cb.flush(); } else { cb.pop(); } break; case search_data: if (cb.remain() < 4) break; if (cb.match("\r\n\r\n", 4)) { st = in_data; D(Serial.println("in_data")); cb.flush(); } else { cb.pop(); } break; case in_data: if (cb.remain() < boundary_len) break; if (cb.match(boundary, boundary_len)) { st = search_data; D(Serial.println("search_data")); cb.flush(); } else { if (file_size == 0) lduino.ClearProgram(); char c = cb.pop(); file_size++; lduino.LoadProgramLine(c); } break; }; } break; case TinyWebPutHandler::END: D(Serial.println("**** END")); D(Serial.print("file size ")); D(Serial.println(file_size)); Client& client = web_server.get_client(); String status; if (file_size > 0 && lduino.getProgramReady()) { status += F("<font color='green'>New ladder program uploaded - file size: "); status += file_size; status += F(" bytes</font>"); } else { status += F("<font color='red'>Upload aborted</font>"); } main_page(client, status); break; } }