From 9e2633ab7b5226ffabcd926b1b4b5bd1e858f1d1 Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Mon, 30 Dec 2013 12:12:50 +0000 Subject: [PATCH 01/15] Remove typedef specifier from URLPARAM_RESULT enum Remove the typedef storage class specifier from the declaration of the URLPARAM_RESULT enum as this is not required and causes gcc to emit the warning "'typedef' was ignored in this declaration" when compiling with -Wall. --- WebServer.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/WebServer.h b/WebServer.h index c438ebd..879b6a8 100644 --- a/WebServer.h +++ b/WebServer.h @@ -147,11 +147,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 From 5df418fa5c0cbf9bc607a07a40e121f08d764043 Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Mon, 30 Dec 2013 12:33:27 +0000 Subject: [PATCH 02/15] Re-order initializer list to match member order Correct the order of the initializer list so that gcc doesn't emit the warning "'WebServer::m_cmdCount' will be initialized after 'int WebServer::m_contentLength' when initialized here" when compiling using -Wall. --- WebServer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebServer.h b/WebServer.h index 879b6a8..a1b2ba2 100644 --- a/WebServer.h +++ b/WebServer.h @@ -353,10 +353,10 @@ WebServer::WebServer(const char *urlPrefix, int port) : m_client(255), m_urlPrefix(urlPrefix), m_pushbackDepth(0), - m_cmdCount(0), m_contentLength(0), m_failureCmd(&defaultFailCmd), m_defaultCmd(&defaultFailCmd), + m_cmdCount(0), m_urlPathCmd(NULL) { } From 8388e16e33438cf2bb596119feb9b3b784017f5d Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Mon, 30 Dec 2013 12:38:57 +0000 Subject: [PATCH 03/15] Add extra brackets to while loop in printP Add an additional set of brackets around the while loop condition in WebServer::printP to stop gcc emitting the warning "suggest parentheses around assignment used as truth value" when compiling using -Wall. --- WebServer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebServer.h b/WebServer.h index a1b2ba2..791b22f 100644 --- a/WebServer.h +++ b/WebServer.h @@ -439,7 +439,7 @@ void WebServer::printP(const unsigned char *str) uint8_t buffer[32]; size_t bufferEnd = 0; - while (buffer[bufferEnd++] = pgm_read_byte(str++)) + while ((buffer[bufferEnd++] = pgm_read_byte(str++))) { if (bufferEnd == 32) { From 0b91dc0bb8b27ffa837154dd94f72312cad9d8c3 Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Mon, 30 Dec 2013 12:44:22 +0000 Subject: [PATCH 04/15] Change some ints and chars to unsigned Convert some of the int and char variables to be unsigned int and unsigned char types. This prevents gcc generating the warnings "comparison between signed and unsigned integer expressions" and "array subscript has type 'char'", as well as having a nice side-effect of shaving 42 bytes off the compiled size when building for the Uno. --- WebServer.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/WebServer.h b/WebServer.h index 791b22f..74b0502 100644 --- a/WebServer.h +++ b/WebServer.h @@ -308,7 +308,7 @@ class WebServer: public Print const char *m_urlPrefix; unsigned char m_pushback[32]; - char m_pushbackDepth; + unsigned char m_pushbackDepth; int m_contentLength; char m_authCredentials[51]; @@ -321,7 +321,7 @@ class WebServer: public Print const char *verb; Command *cmd; } m_commands[8]; - char m_cmdCount; + unsigned char m_cmdCount; UrlPathCommand *m_urlPathCmd; void reset(); @@ -480,9 +480,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. From 128c7f4c2c90f2cb632e92af0dfecc9e7f6979f8 Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Mon, 30 Dec 2013 12:58:22 +0000 Subject: [PATCH 05/15] Hide warning when passing string to m_defaultCmd The Command prototype has a char* parameter for the URL tail, but WebServer::dispatchCommand calls this with an empty string as a parameter if there is no URL. As gcc treats empty strings as const char*s this causes a warning to be emitted when compiling using -Wall, so suppress it by explicitly casting it to char*. --- WebServer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebServer.h b/WebServer.h index 74b0502..022e45b 100644 --- a/WebServer.h +++ b/WebServer.h @@ -465,7 +465,7 @@ bool WebServer::dispatchCommand(ConnectionType requestType, char *verb, // 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 From 8b022f601ddb475c2dda4a75273823f44250958f Mon Sep 17 00:00:00 2001 From: Ben Combee Date: Mon, 30 Dec 2013 09:08:03 -0600 Subject: [PATCH 06/15] Merge with local changes for spacing --- WebServer.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/WebServer.h b/WebServer.h index 022e45b..a486bca 100644 --- a/WebServer.h +++ b/WebServer.h @@ -272,7 +272,7 @@ class WebServer: public Print // output headers and a message indicating a server error void httpFail(); - + // output headers and a message indicating "401 Unauthorized" void httpUnauthorized(); @@ -438,7 +438,7 @@ void WebServer::printP(const unsigned char *str) // 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++))) { if (bufferEnd == 32) @@ -461,7 +461,7 @@ void WebServer::printCRLF() 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))) { @@ -613,7 +613,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; } @@ -1168,7 +1168,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. From 3125b21fa9d2b246d7f61b5eafa3db61eaccb015 Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Wed, 1 Jan 2014 16:08:43 +0000 Subject: [PATCH 07/15] Fix compile now EthernetClient == is overloaded Remove comparison of m_client against NULL as this causes a compilation error since arduino/Arduino@ca37de4ba4ecbdb941f14ac1fe7dd40f3008af75. Also initialize m_client with MAX_SOCK_NUMBER to make boolean test of m_client work correctly. --- WebServer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WebServer.h b/WebServer.h index a486bca..df3905c 100644 --- a/WebServer.h +++ b/WebServer.h @@ -350,7 +350,7 @@ class WebServer: public Print 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_contentLength(0), @@ -726,7 +726,7 @@ void WebServer::httpSeeOther(const char *otherURL) int WebServer::read() { - if (m_client == NULL) + if (!m_client) return -1; if (m_pushbackDepth == 0) From 8ce7dbc39d10f9cf5a071410ef784ea50f72485b Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Thu, 16 Jan 2014 17:37:18 +0000 Subject: [PATCH 08/15] Add buffering for all output Update WebServer::write(uint8_t) to write to a buffer instead of sending single characters (or short strings) as small packets. Remove the other signatures of write so that the base ones in the Print class (which call write(uint8_t)) are used instead and simplify the writeP/printP definitions to do this too. This greatly improves the performance of pages which are built from a large number of small strings or values at the expense of a small additional amount of memory (which can be adjusted with the use of a new macro called WEBDUINO_OUTPUT_BUFFER_SIZE) and also saves ~85 bytes of flash. --- WebServer.h | 75 ++++++++++++++++++++++------------------------------- 1 file changed, 31 insertions(+), 44 deletions(-) diff --git a/WebServer.h b/WebServer.h index df3905c..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 @@ -295,9 +299,6 @@ class WebServer: public Print // 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(); @@ -324,6 +325,9 @@ class WebServer: public Print 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, @@ -337,6 +341,7 @@ class WebServer: public Print 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 @@ -357,7 +362,8 @@ WebServer::WebServer(const char *urlPrefix, int port) : m_failureCmd(&defaultFailCmd), m_defaultCmd(&defaultFailCmd), m_cmdCount(0), - m_urlPathCmd(NULL) + m_urlPathCmd(NULL), + m_bufFill(0) { } @@ -392,70 +398,49 @@ 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; + // copy data out of program memory into local storage - while ((buffer[bufferEnd++] = pgm_read_byte(str++))) + 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, @@ -603,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 From c50b210497aa7fe446401ec229aaee2b63993d54 Mon Sep 17 00:00:00 2001 From: cat101 Date: Sun, 2 Feb 2014 22:32:22 -0200 Subject: [PATCH 09/15] Update WebServer.h Hi again. Here is a summary of the changes - The recent patches did not compile. On Arduino 1.0.5 MAX_SOCK_NUM was missing so I included ethernet.h - I added back write(const uint8_t *buffer, size_t size) which was removed with the addition of buffering - I added printf for convenience - I made reset & flushBuf public. I'll continue to use the current version and report any bugs. I think that it may be a good time to up the version number Thanks --- WebServer.h | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/WebServer.h b/WebServer.h index 4e25ce3..02a9a85 100644 --- a/WebServer.h +++ b/WebServer.h @@ -1,7 +1,8 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-file-style: "k&r"; c-basic-offset: 2; -*- Webduino, a simple Arduino web server - Copyright 2009-2012 Ben Combee, Ran Talbott, Christopher Lee, Martin Lormes + Copyright 2009-2014 Ben Combee, Ran Talbott, Christopher Lee, Martin Lormes + Francisco M Cuenca-Acuna Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -28,6 +29,7 @@ #include #include +#include #include #include @@ -221,6 +223,12 @@ class WebServer: public Print // inline overload for printP to handle signed char strings void printP(const char *str) { printP((unsigned char*)str); } + // support for C style formating + void printf(char *fmt, ... ); + #ifdef F + void printf(const __FlashStringHelper *format, ... ); + #endif + // output raw data stored in program memory void writeP(const unsigned char *data, size_t length); @@ -299,10 +307,16 @@ class WebServer: public Print // implementation of write used to implement Print interface virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *buffer, size_t size); // tells if there is anything to process uint8_t available(); + // Flush the send buffer + void flushBuf(); + + // Close the current connection and flush ethernet buffers + void reset(); private: EthernetServer m_server; EthernetClient m_client; @@ -328,7 +342,6 @@ class WebServer: public Print 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, bool tail_complete); @@ -341,7 +354,6 @@ class WebServer: public Print 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 @@ -409,6 +421,12 @@ size_t WebServer::write(uint8_t ch) return sizeof(ch); } +size_t WebServer::write(const uint8_t *buffer, size_t size) +{ + flushBuf(); //Flush any buffered output + return m_client.write(buffer, size); +} + void WebServer::flushBuf() { if(m_bufFill > 0) @@ -443,6 +461,32 @@ void WebServer::printCRLF() print(CRLF); } +void WebServer::printf(char *fmt, ... ) +{ + char tmp[128]; // resulting string limited to 128 chars + va_list args; + va_start (args, fmt ); + vsnprintf(tmp, 128, fmt, args); + va_end (args); + print(tmp); +} + +#ifdef F +void WebServer::printf(const __FlashStringHelper *format, ... ) +{ + char buf[128]; // resulting string limited to 128 chars + va_list ap; + va_start(ap, format); +#ifdef __AVR__ + vsnprintf_P(buf, sizeof(buf), (const char *)format, ap); // progmem for AVR +#else + vsnprintf(buf, sizeof(buf), (const char *)format, ap); // for the rest of the world +#endif + va_end(ap); + print(buf); +} +#endif + bool WebServer::dispatchCommand(ConnectionType requestType, char *verb, bool tail_complete) { From c41b558b888250771c7a7e80e9b75a0c325992b1 Mon Sep 17 00:00:00 2001 From: ntruchsess Date: Fri, 28 Feb 2014 13:52:37 +0100 Subject: [PATCH 10/15] constructor EthernetClient(MAX_SOCK_NUM) is undocumented and equivalent to EthernetClient() anyway --- WebServer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebServer.h b/WebServer.h index 02a9a85..6025264 100644 --- a/WebServer.h +++ b/WebServer.h @@ -367,7 +367,7 @@ class WebServer: public Print WebServer::WebServer(const char *urlPrefix, int port) : m_server(port), - m_client(MAX_SOCK_NUM), + m_client(), m_urlPrefix(urlPrefix), m_pushbackDepth(0), m_contentLength(0), From b2f650fb3bdcdb774dd55c9de6ef44240a96aeae Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Sun, 16 Mar 2014 15:45:34 +0000 Subject: [PATCH 11/15] Reduce size and clarify type of some integer vars Trim down the size of a couple of variables as they didn't need to be as large, clarify the type of some others, and change port from int to uint16_t to match EthernetServer. --- WebServer.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/WebServer.h b/WebServer.h index 6025264..7cb5c7c 100644 --- a/WebServer.h +++ b/WebServer.h @@ -183,7 +183,7 @@ class WebServer: public Print bool tail_complete); // constructor for webserver object - WebServer(const char *urlPrefix = "", int port = 80); + WebServer(const char *urlPrefix = "", uint16_t port = 80); // start listening for connections void begin(); @@ -365,7 +365,7 @@ class WebServer: public Print * IMPLEMENTATION ********************************************************************/ -WebServer::WebServer(const char *urlPrefix, int port) : +WebServer::WebServer(const char *urlPrefix, uint16_t port) : m_server(port), m_client(), m_urlPrefix(urlPrefix), @@ -509,10 +509,10 @@ bool WebServer::dispatchCommand(ConnectionType requestType, char *verb, // if the first character is a slash, there's more after it. if (verb[0] == '/') { - unsigned char i; + uint8_t i; char *qm_loc; - unsigned int verb_len; - int qm_offset; + uint16_t verb_len; + uint8_t qm_offset; // Skip over the leading "/", because it makes the code more // efficient and easier to understand. verb++; @@ -539,7 +539,7 @@ bool WebServer::dispatchCommand(ConnectionType requestType, char *verb, { // Initialize with null bytes, so number of parts can be determined. char *url_path[WEBDUINO_URL_PATH_COMMAND_LENGTH] = {0}; - int part = 0; + uint8_t part = 0; // URL path should be terminated with null byte. *(verb + verb_len) = 0; From f95122d70309f343740be6264853c9274fdef766 Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Sun, 23 Mar 2014 16:58:12 +0000 Subject: [PATCH 12/15] Put flash strings into separate sections Change the definition of the P() macro under the AVR architecture to store the strings in sections named after the variables. This allows unused strings to be removed by the linker, saving space in the flash memory. Also change the variable name for all but one of the instances of failMsg to give the maximum benefit from the above. --- WebServer.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/WebServer.h b/WebServer.h index 7cb5c7c..e88ce74 100644 --- a/WebServer.h +++ b/WebServer.h @@ -134,7 +134,7 @@ extern "C" unsigned long millis(void); // declare a static string #ifdef __AVR__ -#define P(name) static const unsigned char name[] PROGMEM +#define P(name) static const unsigned char name[] __attribute__(( section(".progmem." #name) )) #else #define P(name) static const unsigned char name[] #endif @@ -691,7 +691,7 @@ void WebServer::favicon(ConnectionType type) void WebServer::httpUnauthorized() { - P(failMsg) = + P(unauthMsg) = "HTTP/1.0 401 Authorization Required" CRLF WEBDUINO_SERVER_HEADER "Content-Type: text/html" CRLF @@ -699,19 +699,19 @@ void WebServer::httpUnauthorized() CRLF WEBDUINO_AUTH_MESSAGE; - printP(failMsg); + printP(unauthMsg); } void WebServer::httpServerError() { - P(failMsg) = + P(servErrMsg) = "HTTP/1.0 500 Internal Server Error" CRLF WEBDUINO_SERVER_HEADER "Content-Type: text/html" CRLF CRLF WEBDUINO_SERVER_ERROR_MESSAGE; - printP(failMsg); + printP(servErrMsg); } void WebServer::httpNoContent() From 6b974fd4e9245e8e3029d7cf93456dfc9d592da3 Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Sun, 23 Mar 2014 17:54:28 +0000 Subject: [PATCH 13/15] Save flash by only storing the server header once Modify the functions which send headers to re-use one string containing the server name instead of including it inline in all of the different headers. --- WebServer.h | 86 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 31 deletions(-) diff --git a/WebServer.h b/WebServer.h index e88ce74..dadc763 100644 --- a/WebServer.h +++ b/WebServer.h @@ -40,12 +40,6 @@ #define WEBDUINO_VERSION 1007 #define WEBDUINO_VERSION_STRING "1.7" -#if WEBDUINO_SUPRESS_SERVER_HEADER -#define WEBDUINO_SERVER_HEADER "" -#else -#define WEBDUINO_SERVER_HEADER "Server: Webduino/" WEBDUINO_VERSION_STRING CRLF -#endif - // standard END-OF-LINE marker in HTTP #define CRLF "\r\n" @@ -379,6 +373,8 @@ WebServer::WebServer(const char *urlPrefix, uint16_t port) : { } +P(webServerHeader) = "Server: Webduino/" WEBDUINO_VERSION_STRING CRLF; + void WebServer::begin() { m_server.begin(); @@ -651,14 +647,19 @@ bool WebServer::checkCredentials(const char authCredentials[45]) void WebServer::httpFail() { - P(failMsg) = - "HTTP/1.0 400 Bad Request" CRLF - WEBDUINO_SERVER_HEADER + P(failMsg1) = "HTTP/1.0 400 Bad Request" CRLF; + printP(failMsg1); + +#ifndef WEBDUINO_SUPRESS_SERVER_HEADER + printP(webServerHeader); +#endif + + P(failMsg2) = "Content-Type: text/html" CRLF CRLF WEBDUINO_FAIL_MESSAGE; - printP(failMsg); + printP(failMsg2); } void WebServer::defaultFailCmd(WebServer &server, @@ -691,50 +692,70 @@ void WebServer::favicon(ConnectionType type) void WebServer::httpUnauthorized() { - P(unauthMsg) = - "HTTP/1.0 401 Authorization Required" CRLF - WEBDUINO_SERVER_HEADER + P(unauthMsg1) = "HTTP/1.0 401 Authorization Required" CRLF; + printP(unauthMsg1); + +#ifndef WEBDUINO_SUPRESS_SERVER_HEADER + printP(webServerHeader); +#endif + + P(unauthMsg2) = "Content-Type: text/html" CRLF "WWW-Authenticate: Basic realm=\"" WEBDUINO_AUTH_REALM "\"" CRLF CRLF WEBDUINO_AUTH_MESSAGE; - printP(unauthMsg); + printP(unauthMsg2); } void WebServer::httpServerError() { - P(servErrMsg) = - "HTTP/1.0 500 Internal Server Error" CRLF - WEBDUINO_SERVER_HEADER + P(servErrMsg1) = "HTTP/1.0 500 Internal Server Error" CRLF; + printP(servErrMsg1); + +#ifndef WEBDUINO_SUPRESS_SERVER_HEADER + printP(webServerHeader); +#endif + + P(servErrMsg2) = "Content-Type: text/html" CRLF CRLF WEBDUINO_SERVER_ERROR_MESSAGE; - printP(servErrMsg); + printP(servErrMsg2); } void WebServer::httpNoContent() { - P(noContentMsg) = - "HTTP/1.0 204 NO CONTENT" CRLF - WEBDUINO_SERVER_HEADER + P(noContentMsg1) = "HTTP/1.0 204 NO CONTENT" CRLF; + printP(noContentMsg1); + +#ifndef WEBDUINO_SUPRESS_SERVER_HEADER + printP(webServerHeader); +#endif + + P(noContentMsg2) = CRLF CRLF; - printP(noContentMsg); + printP(noContentMsg2); } void WebServer::httpSuccess(const char *contentType, const char *extraHeaders) { - P(successMsg1) = - "HTTP/1.0 200 OK" CRLF - WEBDUINO_SERVER_HEADER + P(successMsg1) = "HTTP/1.0 200 OK" CRLF; + printP(successMsg1); + +#ifndef WEBDUINO_SUPRESS_SERVER_HEADER + printP(webServerHeader); +#endif + + P(successMsg2) = "Access-Control-Allow-Origin: *" CRLF "Content-Type: "; - printP(successMsg1); + printP(successMsg2); print(contentType); printCRLF(); if (extraHeaders) @@ -744,12 +765,15 @@ void WebServer::httpSuccess(const char *contentType, void WebServer::httpSeeOther(const char *otherURL) { - P(seeOtherMsg) = - "HTTP/1.0 303 See Other" CRLF - WEBDUINO_SERVER_HEADER - "Location: "; + P(seeOtherMsg1) = "HTTP/1.0 303 See Other" CRLF; + printP(seeOtherMsg1); + +#ifndef WEBDUINO_SUPRESS_SERVER_HEADER + printP(webServerHeader); +#endif - printP(seeOtherMsg); + P(seeOtherMsg2) = "Location: "; + printP(seeOtherMsg2); print(otherURL); printCRLF(); printCRLF(); From 4ee01d3cd37422a5edf74c00c47a4e59ceb1d1ef Mon Sep 17 00:00:00 2001 From: mkldon Date: Thu, 10 Apr 2014 16:44:09 +0400 Subject: [PATCH 14/15] Add WEBDUINO_COMMANDS_COUNT macro Add macro for configuring maximum number of commands that can be defined. This macro replaces hardcoded "8" number. --- WebServer.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/WebServer.h b/WebServer.h index dadc763..6360460 100644 --- a/WebServer.h +++ b/WebServer.h @@ -53,6 +53,10 @@ #define WEBDUINO_READ_TIMEOUT_IN_MS 1000 #endif +#ifndef WEBDUINO_COMMANDS_COUNT +#define WEBDUINO_COMMANDS_COUNT 8 +#endif + #ifndef WEBDUINO_URL_PATH_COMMAND_LENGTH #define WEBDUINO_URL_PATH_COMMAND_LENGTH 8 #endif @@ -329,7 +333,7 @@ class WebServer: public Print { const char *verb; Command *cmd; - } m_commands[8]; + } m_commands[WEBDUINO_COMMANDS_COUNT]; unsigned char m_cmdCount; UrlPathCommand *m_urlPathCmd; From a68507ef6d99045fd55b21b4d64df84f3b5422fa Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Thu, 17 Jul 2014 19:13:58 +0100 Subject: [PATCH 15/15] Fix compiler warnings about narrowing conversion The latest 1.5.7 beta release of Arduino includes an updated toolchain which now issues warnings about narrowing of ints to chars inside curly braces becoming ill-formed in C++11. Explicitly cast the values to char to prevent this. --- WebServer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebServer.h b/WebServer.h index 6360460..c8c43c3 100644 --- a/WebServer.h +++ b/WebServer.h @@ -992,7 +992,7 @@ bool WebServer::readPOSTparam(char *name, int nameLen, int ch2 = read(); if (ch1 == -1 || ch2 == -1) return false; - char hex[3] = { ch1, ch2, 0 }; + char hex[3] = { (char)ch1, (char)ch2, '\0' }; ch = strtoul(hex, NULL, 16); }