boolean put_handler(TinyWebServer& web_server) { const char* length_str = web_server.get_header_value(PSTR("Content-Length")); long length = atol(length_str); uint32_t start_time = 0; boolean watchdog_start = false; char buffer_[512]; EthernetClient client = web_server.get_client(); if (put_handler_fn) { (*put_handler_fn)(web_server, START, NULL, length); } uint32_t i; for (i = 0; i < length && client.connected();) { // int16_t size = read_chars(web_server, client, (uint8_t*)buffer, 64); int16_t size = read_fast(web_server, client, (uint8_t*)buffer_, sizeof(buffer_)); if (!size) { if (watchdog_start) { if (millis() - start_time > 30000) { // Exit if there has been zero data from connected client // for more than 30 seconds. #if DEBUG Serial << F("TWS:There has been no data for >30 Sec.\n"); #endif break; } } else { // We have hit an empty buffer, start the watchdog. start_time = millis(); watchdog_start = true; } continue; } i += size; // Ensure we re-start the watchdog if we get ANY data input. watchdog_start = false; if (put_handler_fn) { (*put_handler_fn)(web_server, WRITE, buffer_, size); } } if (put_handler_fn) { (*put_handler_fn)(web_server, END, NULL, 0); } client << F("HTTP/1.1 200 OK\r\n"); // web_server.send_error_code(200); web_server.end_headers(); return true; }
static boolean setconfig_handler(TinyWebServer& web_server) { const char* length_str = web_server.get_header_value("Content-Length"); int length = atoi(length_str); uint32_t start_time = millis(); StringParse buf; Client& client = web_server.get_client(); if (length <= 0) return true; while (buf.length() < length && client.connected() && (millis() - start_time < 30000)) { if (!client.available()) continue; buf += client.readString(); } IP_Config.ParseConfig(buf); IP_Config.SaveConfig(); return true; }
static boolean config_handler(TinyWebServer& web_server) { web_server.send_error_code(200); web_server.end_headers(); const char* length_str = web_server.get_header_value("Content-Length"); int length = atoi(length_str); uint32_t start_time = millis(); StringParse buf; EthernetClient client = web_server.get_client(); while (buf.length() < length && client.connected() && (millis() - start_time < 30000)) { if (!client.available()) continue; buf += client.readString(); } ParseConfig(buf); IP_Config.SaveConfig(); main_page(client, F("<font color='green'>IP Config saved</font>")); return true; }
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; } }