diff --git a/WebServer.h b/WebServer.h index 02a9a85..c8c43c3 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" @@ -59,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 @@ -134,7 +132,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 @@ -183,7 +181,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(); @@ -335,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; @@ -365,9 +363,9 @@ 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(MAX_SOCK_NUM), + m_client(), m_urlPrefix(urlPrefix), m_pushbackDepth(0), m_contentLength(0), @@ -379,6 +377,8 @@ WebServer::WebServer(const char *urlPrefix, int port) : { } +P(webServerHeader) = "Server: Webduino/" WEBDUINO_VERSION_STRING CRLF; + void WebServer::begin() { m_server.begin(); @@ -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; @@ -651,14 +651,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 +696,70 @@ void WebServer::favicon(ConnectionType type) void WebServer::httpUnauthorized() { - P(failMsg) = - "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(failMsg); + printP(unauthMsg2); } void WebServer::httpServerError() { - P(failMsg) = - "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(failMsg); + 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 +769,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(); @@ -964,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); }