From: Frédéric Péters Date: Wed, 26 Aug 2020 08:09:29 +0000 (+0200) Subject: webserver: update with latest upstream code X-Git-Url: https://git.0d.be/?p=PanikSwitch.git;a=commitdiff_plain;h=21eca631a2ff2d19d2d7013d675a9bcdc63f0d64 webserver: update with latest upstream code https://github.com/webduino/Webduino --- diff --git a/WebServer.h b/WebServer.h index 8647e09..4e25ce3 100644 --- a/WebServer.h +++ b/WebServer.h @@ -77,6 +77,10 @@ #define WEBDUINO_SERVER_ERROR_MESSAGE "

500 Internal Server Error

" #endif // WEBDUINO_SERVER_ERROR_MESSAGE +#ifndef WEBDUINO_OUTPUT_BUFFER_SIZE +#define WEBDUINO_OUTPUT_BUFFER_SIZE 32 +#endif // WEBDUINO_OUTPUT_BUFFER_SIZE + // add '#define WEBDUINO_FAVICON_DATA ""' to your application // before including WebServer.h to send a null file as the favicon.ico file // otherwise this defaults to a 16x16 px black diode on blue ground @@ -127,11 +131,18 @@ extern "C" unsigned long millis(void); // declare a static string +#ifdef __AVR__ #define P(name) static const unsigned char name[] PROGMEM +#else +#define P(name) static const unsigned char name[] +#endif // returns the number of elements in the array #define SIZE(array) (sizeof(array) / sizeof(*array)) +#ifdef _VARIANT_ARDUINO_DUE_X_ +#define pgm_read_byte(ptr) (unsigned char)(* ptr) +#endif /******************************************************************** * DECLARATIONS ********************************************************************/ @@ -140,11 +151,11 @@ extern "C" unsigned long millis(void); * when you call nextURLparam AFTER the last parameter is read. The * last actual parameter gets an "OK" return code. */ -typedef enum URLPARAM_RESULT { URLPARAM_OK, - URLPARAM_NAME_OFLO, - URLPARAM_VALUE_OFLO, - URLPARAM_BOTH_OFLO, - URLPARAM_EOS // No params left +enum URLPARAM_RESULT { URLPARAM_OK, + URLPARAM_NAME_OFLO, + URLPARAM_VALUE_OFLO, + URLPARAM_BOTH_OFLO, + URLPARAM_EOS // No params left }; class WebServer: public Print @@ -265,7 +276,7 @@ public: // output headers and a message indicating a server error void httpFail(); - + // output headers and a message indicating "401 Unauthorized" void httpUnauthorized(); @@ -288,9 +299,6 @@ public: // implementation of write used to implement Print interface virtual size_t write(uint8_t); - virtual size_t write(const char *str); - virtual size_t write(const uint8_t *buffer, size_t size); - size_t write(const char *data, size_t length); // tells if there is anything to process uint8_t available(); @@ -301,7 +309,7 @@ private: const char *m_urlPrefix; unsigned char m_pushback[32]; - char m_pushbackDepth; + unsigned char m_pushbackDepth; int m_contentLength; char m_authCredentials[51]; @@ -314,9 +322,12 @@ private: const char *verb; Command *cmd; } m_commands[8]; - char m_cmdCount; + unsigned char m_cmdCount; UrlPathCommand *m_urlPathCmd; + uint8_t m_buffer[WEBDUINO_OUTPUT_BUFFER_SIZE]; + uint8_t m_bufFill; + void reset(); void getRequest(WebServer::ConnectionType &type, char *request, int *length); bool dispatchCommand(ConnectionType requestType, char *verb, @@ -330,6 +341,7 @@ private: char *url_tail, bool tail_complete); void noRobots(ConnectionType type); void favicon(ConnectionType type); + void flushBuf(); }; /* define this macro if you want to include the header in a sketch source @@ -343,14 +355,15 @@ private: WebServer::WebServer(const char *urlPrefix, int port) : m_server(port), - m_client(255), + m_client(MAX_SOCK_NUM), m_urlPrefix(urlPrefix), m_pushbackDepth(0), - m_cmdCount(0), m_contentLength(0), m_failureCmd(&defaultFailCmd), m_defaultCmd(&defaultFailCmd), - m_urlPathCmd(NULL) + m_cmdCount(0), + m_urlPathCmd(NULL), + m_bufFill(0) { } @@ -385,80 +398,59 @@ void WebServer::setUrlPathCommand(UrlPathCommand *cmd) size_t WebServer::write(uint8_t ch) { - return m_client.write(ch); -} + m_buffer[m_bufFill++] = ch; -size_t WebServer::write(const char *str) -{ - return m_client.write(str); -} + if(m_bufFill == sizeof(m_buffer)) + { + m_client.write(m_buffer, sizeof(m_buffer)); + m_bufFill = 0; + } -size_t WebServer::write(const uint8_t *buffer, size_t size) -{ - return m_client.write(buffer, size); + return sizeof(ch); } -size_t WebServer::write(const char *buffer, size_t length) +void WebServer::flushBuf() { - return m_client.write((const uint8_t *)buffer, length); + if(m_bufFill > 0) + { + m_client.write(m_buffer, m_bufFill); + m_bufFill = 0; + } } void WebServer::writeP(const unsigned char *data, size_t length) { - // copy data out of program memory into local storage, write out in - // chunks of 32 bytes to avoid extra short TCP/IP packets - uint8_t buffer[32]; - size_t bufferEnd = 0; + // copy data out of program memory into local storage while (length--) { - if (bufferEnd == 32) - { - m_client.write(buffer, 32); - bufferEnd = 0; - } - - buffer[bufferEnd++] = pgm_read_byte(data++); + write(pgm_read_byte(data++)); } - - if (bufferEnd > 0) - m_client.write(buffer, bufferEnd); } void WebServer::printP(const unsigned char *str) { - // copy data out of program memory into local storage, write out in - // chunks of 32 bytes to avoid extra short TCP/IP packets - uint8_t buffer[32]; - size_t bufferEnd = 0; - - while (buffer[bufferEnd++] = pgm_read_byte(str++)) + // copy data out of program memory into local storage + + while (uint8_t value = pgm_read_byte(str++)) { - if (bufferEnd == 32) - { - m_client.write(buffer, 32); - bufferEnd = 0; - } + write(value); } - - // write out everything left but trailing NUL - if (bufferEnd > 1) - m_client.write(buffer, bufferEnd - 1); } void WebServer::printCRLF() { - m_client.write((const uint8_t *)"\r\n", 2); + print(CRLF); } bool WebServer::dispatchCommand(ConnectionType requestType, char *verb, bool tail_complete) { - // if there is no URL, i.e. we have a prefix and it's requested without a + // if there is no URL, i.e. we have a prefix and it's requested without a // trailing slash or if the URL is just the slash if ((verb[0] == 0) || ((verb[0] == '/') && (verb[1] == 0))) { - m_defaultCmd(*this, requestType, "", tail_complete); + m_defaultCmd(*this, requestType, (char*)"", tail_complete); return true; } // if the URL is just a slash followed by a question mark @@ -473,9 +465,9 @@ bool WebServer::dispatchCommand(ConnectionType requestType, char *verb, // if the first character is a slash, there's more after it. if (verb[0] == '/') { - char i; + unsigned char i; char *qm_loc; - int verb_len; + unsigned int verb_len; int qm_offset; // Skip over the leading "/", because it makes the code more // efficient and easier to understand. @@ -596,6 +588,8 @@ void WebServer::processConnection(char *buff, int *bufflen) m_failureCmd(*this, requestType, buff, (*bufflen) >= 0); } + flushBuf(); + #if WEBDUINO_SERIAL_DEBUGGING > 1 Serial.println("*** stopping connection ***"); #endif @@ -606,7 +600,7 @@ void WebServer::processConnection(char *buff, int *bufflen) bool WebServer::checkCredentials(const char authCredentials[45]) { char basic[7] = "Basic "; - if((0 == strncmp(m_authCredentials,basic,6)) && + if((0 == strncmp(m_authCredentials,basic,6)) && (0 == strcmp(authCredentials, m_authCredentials + 6))) return true; return false; } @@ -719,7 +713,7 @@ void WebServer::httpSeeOther(const char *otherURL) int WebServer::read() { - if (m_client == NULL) + if (!m_client) return -1; if (m_pushbackDepth == 0) @@ -1033,7 +1027,7 @@ URLPARAM_RESULT WebServer::nextURLparam(char **tail, char *name, int nameLen, *name++ = ch; --nameLen; } - else + else if(keep_scanning) result = URLPARAM_NAME_OFLO; } @@ -1089,7 +1083,7 @@ URLPARAM_RESULT WebServer::nextURLparam(char **tail, char *name, int nameLen, *value++ = ch; --valueLen; } - else + else if(keep_scanning) result = (result == URLPARAM_OK) ? URLPARAM_VALUE_OFLO : URLPARAM_BOTH_OFLO; @@ -1161,7 +1155,7 @@ void WebServer::getRequest(WebServer::ConnectionType &type, void WebServer::processHeaders() { - // look for three things: the Content-Length header, the Authorization + // look for three things: the Content-Length header, the Authorization // header, and the double-CRLF that ends the headers. // empty the m_authCredentials before every run of this function.