Webserver controller with url trimming for value controls

Dependencies:   LCD_DISCO_F746NG BSP_DISCO_F746NG

Committer:
hudakz
Date:
Thu Apr 06 18:58:40 2017 +0000
Revision:
0:e455fdb56bc8
Child:
2:33e8bb5615a6
Initial release.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:e455fdb56bc8 1 #include "mbed.h"
hudakz 0:e455fdb56bc8 2 #include "EthernetInterface.h"
hudakz 0:e455fdb56bc8 3 #include "TCPServer.h"
hudakz 0:e455fdb56bc8 4 #include "TCPSocket.h"
hudakz 0:e455fdb56bc8 5 #include <stdio.h>
hudakz 0:e455fdb56bc8 6 #include <string>
hudakz 0:e455fdb56bc8 7
hudakz 0:e455fdb56bc8 8 using namespace std;
hudakz 0:e455fdb56bc8 9
hudakz 0:e455fdb56bc8 10 #define PORT 80
hudakz 0:e455fdb56bc8 11
hudakz 0:e455fdb56bc8 12 EthernetInterface ethernet;
hudakz 0:e455fdb56bc8 13 TCPServer server;
hudakz 0:e455fdb56bc8 14 TCPSocket clientSocket;
hudakz 0:e455fdb56bc8 15 SocketAddress clientAddress;
hudakz 0:e455fdb56bc8 16 char receiveBuf[1024] = { };
hudakz 0:e455fdb56bc8 17
hudakz 0:e455fdb56bc8 18 const int OFF = 0;
hudakz 0:e455fdb56bc8 19 const int ON = 1;
hudakz 0:e455fdb56bc8 20
hudakz 0:e455fdb56bc8 21 DigitalOut sw(LED1);
hudakz 0:e455fdb56bc8 22
hudakz 0:e455fdb56bc8 23 const string PASSWORD = "secret"; // change as you like
hudakz 0:e455fdb56bc8 24 const string HTTP_OK = "HTTP/1.0 200 OK";
hudakz 0:e455fdb56bc8 25 const string MOVED_PERM = "HTTP/1.0 301 Moved Permanently\r\nLocation: ";
hudakz 0:e455fdb56bc8 26 const string UNAUTHORIZED = "HTTP/1.0 401 Unauthorized";
hudakz 0:e455fdb56bc8 27 string httpHeader; // HTTP header
hudakz 0:e455fdb56bc8 28 string httpContent; // HTTP content
hudakz 0:e455fdb56bc8 29 // analyse the url given
hudakz 0:e455fdb56bc8 30 // return values: -1 invalid password
hudakz 0:e455fdb56bc8 31 // -2 no command given but password valid
hudakz 0:e455fdb56bc8 32 // -3 just refresh page
hudakz 0:e455fdb56bc8 33 // 0 switch off
hudakz 0:e455fdb56bc8 34 // 1 switch on
hudakz 0:e455fdb56bc8 35 //
hudakz 0:e455fdb56bc8 36 // The string passed to this function will look like this:
hudakz 0:e455fdb56bc8 37 // GET /password HTTP/1.....
hudakz 0:e455fdb56bc8 38 // GET /password/ HTTP/1.....
hudakz 0:e455fdb56bc8 39 // GET /password/?sw=1 HTTP/1.....
hudakz 0:e455fdb56bc8 40
hudakz 0:e455fdb56bc8 41 // GET /password/?sw=0 HTTP/1.....
hudakz 0:e455fdb56bc8 42 int8_t analyseURL(string& str) {
hudakz 0:e455fdb56bc8 43 if(str.substr(5, PASSWORD.size()) != PASSWORD)
hudakz 0:e455fdb56bc8 44 return(-1);
hudakz 0:e455fdb56bc8 45
hudakz 0:e455fdb56bc8 46 uint8_t pos = 5 + PASSWORD.size();
hudakz 0:e455fdb56bc8 47
hudakz 0:e455fdb56bc8 48 if(str.substr(pos, 1) == " ")
hudakz 0:e455fdb56bc8 49 return(-2);
hudakz 0:e455fdb56bc8 50
hudakz 0:e455fdb56bc8 51 if(str.substr(pos++, 1) != "/")
hudakz 0:e455fdb56bc8 52 return(-1);
hudakz 0:e455fdb56bc8 53
hudakz 0:e455fdb56bc8 54 string cmd(str.substr(pos, 5));
hudakz 0:e455fdb56bc8 55
hudakz 0:e455fdb56bc8 56 if(cmd == "?sw=0")
hudakz 0:e455fdb56bc8 57 return(OFF);
hudakz 0:e455fdb56bc8 58
hudakz 0:e455fdb56bc8 59 if(cmd == "?sw=1")
hudakz 0:e455fdb56bc8 60 return(ON);
hudakz 0:e455fdb56bc8 61
hudakz 0:e455fdb56bc8 62 return(-3);
hudakz 0:e455fdb56bc8 63 }
hudakz 0:e455fdb56bc8 64
hudakz 0:e455fdb56bc8 65 /**
hudakz 0:e455fdb56bc8 66 * @brief
hudakz 0:e455fdb56bc8 67 * @note
hudakz 0:e455fdb56bc8 68 * @param
hudakz 0:e455fdb56bc8 69 * @retval
hudakz 0:e455fdb56bc8 70 */
hudakz 0:e455fdb56bc8 71 string& movedPermanently(uint8_t flag) {
hudakz 0:e455fdb56bc8 72 if(flag == 1)
hudakz 0:e455fdb56bc8 73 httpContent = "/" + PASSWORD + "/";
hudakz 0:e455fdb56bc8 74 else
hudakz 0:e455fdb56bc8 75 httpContent = "";
hudakz 0:e455fdb56bc8 76
hudakz 0:e455fdb56bc8 77 httpContent += "<h1>301 Moved Permanently</h1>\r\n";
hudakz 0:e455fdb56bc8 78
hudakz 0:e455fdb56bc8 79 return(httpContent);
hudakz 0:e455fdb56bc8 80 }
hudakz 0:e455fdb56bc8 81
hudakz 0:e455fdb56bc8 82 /**
hudakz 0:e455fdb56bc8 83 * @brief
hudakz 0:e455fdb56bc8 84 * @note
hudakz 0:e455fdb56bc8 85 * @param
hudakz 0:e455fdb56bc8 86 * @retval
hudakz 0:e455fdb56bc8 87 */
hudakz 0:e455fdb56bc8 88 string& showWebPage(uint8_t status) {
hudakz 0:e455fdb56bc8 89 httpContent = "<h2>WebSwitch - Smart Home</h2>\r\n";
hudakz 0:e455fdb56bc8 90
hudakz 0:e455fdb56bc8 91 httpContent += "<pre>Temperature:\t21.8&deg;C\r\n</pre>";
hudakz 0:e455fdb56bc8 92
hudakz 0:e455fdb56bc8 93 if(status == ON) {
hudakz 0:e455fdb56bc8 94 httpContent += "<pre>\r\nHeating:\t<font color=#FF0000>ON </font>";
hudakz 0:e455fdb56bc8 95 httpContent += " <a href=\"./?sw=0\">[Turn off]</a>\r\n";
hudakz 0:e455fdb56bc8 96 }
hudakz 0:e455fdb56bc8 97 else {
hudakz 0:e455fdb56bc8 98 httpContent += "<pre>\r\nHeating:\t<font color=#BBBBBB>OFF</font>";
hudakz 0:e455fdb56bc8 99 httpContent += " <a href=\"./?sw=1\">[Turn on]</a>\r\n";
hudakz 0:e455fdb56bc8 100 }
hudakz 0:e455fdb56bc8 101
hudakz 0:e455fdb56bc8 102 //httpContent += " \r\n";
hudakz 0:e455fdb56bc8 103 //httpContent += " <a href=\".\">Refresh status]</a>\r\n";
hudakz 0:e455fdb56bc8 104 httpContent += "</pre>\r\n";
hudakz 0:e455fdb56bc8 105 httpContent += "<hr>\r\n";
hudakz 0:e455fdb56bc8 106 httpContent += "<pre>2017 ARMmbed Open Source</pre>";
hudakz 0:e455fdb56bc8 107 return httpContent;
hudakz 0:e455fdb56bc8 108 }
hudakz 0:e455fdb56bc8 109
hudakz 0:e455fdb56bc8 110 /**
hudakz 0:e455fdb56bc8 111 * @brief
hudakz 0:e455fdb56bc8 112 * @note
hudakz 0:e455fdb56bc8 113 * @param
hudakz 0:e455fdb56bc8 114 * @retval
hudakz 0:e455fdb56bc8 115 */
hudakz 0:e455fdb56bc8 116 void sendHTTP(TCPSocket& client, string& header, string& content) {
hudakz 0:e455fdb56bc8 117 char content_length[5] = { };
hudakz 0:e455fdb56bc8 118
hudakz 0:e455fdb56bc8 119 header += "\r\nContent-Type: text/html\r\n";
hudakz 0:e455fdb56bc8 120 header += "Content-Length: ";
hudakz 0:e455fdb56bc8 121 sprintf(content_length, "%d", content.length());
hudakz 0:e455fdb56bc8 122 header += string(content_length) + "\r\n";
hudakz 0:e455fdb56bc8 123 header += "Pragma: no-cache\r\n";
hudakz 0:e455fdb56bc8 124 header += "Connection: About to close\r\n";
hudakz 0:e455fdb56bc8 125 header += "\r\n";
hudakz 0:e455fdb56bc8 126
hudakz 0:e455fdb56bc8 127 string webpage = header + content;
hudakz 0:e455fdb56bc8 128 client.send((char*)webpage.c_str(), webpage.length());
hudakz 0:e455fdb56bc8 129 printf("HTTP sent.\n\r");
hudakz 0:e455fdb56bc8 130 }
hudakz 0:e455fdb56bc8 131
hudakz 0:e455fdb56bc8 132 /**
hudakz 0:e455fdb56bc8 133 * @brief
hudakz 0:e455fdb56bc8 134 * @note
hudakz 0:e455fdb56bc8 135 * @param
hudakz 0:e455fdb56bc8 136 * @retval
hudakz 0:e455fdb56bc8 137 */
hudakz 0:e455fdb56bc8 138 int main(void) {
hudakz 0:e455fdb56bc8 139
hudakz 0:e455fdb56bc8 140 ethernet.connect();
hudakz 0:e455fdb56bc8 141 printf("Usage: Type %s/%s/ into your web browser and hit ENTER\r\n", ethernet.get_ip_address(), PASSWORD);
hudakz 0:e455fdb56bc8 142
hudakz 0:e455fdb56bc8 143 /* Open the server on ethernet stack */
hudakz 0:e455fdb56bc8 144 server.open(&ethernet);
hudakz 0:e455fdb56bc8 145
hudakz 0:e455fdb56bc8 146 /* Bind the HTTP port (TCP 80) to the server */
hudakz 0:e455fdb56bc8 147 server.bind(ethernet.get_ip_address(), 80);
hudakz 0:e455fdb56bc8 148
hudakz 0:e455fdb56bc8 149 /* Can handle 5 simultaneous connections */
hudakz 0:e455fdb56bc8 150 server.listen(5);
hudakz 0:e455fdb56bc8 151
hudakz 0:e455fdb56bc8 152 //listening for http GET request
hudakz 0:e455fdb56bc8 153 while(true) {
hudakz 0:e455fdb56bc8 154 server.accept(&clientSocket, &clientAddress);
hudakz 0:e455fdb56bc8 155 printf("\r\n=========================================\r\n");
hudakz 0:e455fdb56bc8 156 printf("Connection succeeded!\n\rIP: %s\n\r", clientAddress.get_ip_address());
hudakz 0:e455fdb56bc8 157 clientSocket.recv(receiveBuf, 1023);
hudakz 0:e455fdb56bc8 158 printf("Recieved Data: %d\n\r\n\r%.*s\n\r", strlen(receiveBuf), strlen(receiveBuf), receiveBuf);
hudakz 0:e455fdb56bc8 159
hudakz 0:e455fdb56bc8 160 string received(receiveBuf);
hudakz 0:e455fdb56bc8 161 if(received.substr(0, 3) != "GET") {
hudakz 0:e455fdb56bc8 162 httpHeader = HTTP_OK;
hudakz 0:e455fdb56bc8 163 httpContent = "<h1>200 OK</h1>";
hudakz 0:e455fdb56bc8 164 sendHTTP(clientSocket, httpHeader, httpContent);
hudakz 0:e455fdb56bc8 165 continue;
hudakz 0:e455fdb56bc8 166 }
hudakz 0:e455fdb56bc8 167
hudakz 0:e455fdb56bc8 168 if(received.substr(0, 6) == "GET / ") {
hudakz 0:e455fdb56bc8 169 httpHeader = HTTP_OK;
hudakz 0:e455fdb56bc8 170 httpContent = "<p>Usage: Type http://ip_address/password/ into your web browser and hit ENTER</p>\r\n";
hudakz 0:e455fdb56bc8 171 sendHTTP(clientSocket, httpHeader, httpContent);
hudakz 0:e455fdb56bc8 172 continue;
hudakz 0:e455fdb56bc8 173 }
hudakz 0:e455fdb56bc8 174
hudakz 0:e455fdb56bc8 175 int cmd = analyseURL(received);
hudakz 0:e455fdb56bc8 176
hudakz 0:e455fdb56bc8 177 if(cmd == -2) {
hudakz 0:e455fdb56bc8 178
hudakz 0:e455fdb56bc8 179 // redirect to the right base url
hudakz 0:e455fdb56bc8 180 httpHeader = MOVED_PERM;
hudakz 0:e455fdb56bc8 181 sendHTTP(clientSocket, httpHeader, movedPermanently(1));
hudakz 0:e455fdb56bc8 182 continue;
hudakz 0:e455fdb56bc8 183 }
hudakz 0:e455fdb56bc8 184
hudakz 0:e455fdb56bc8 185 if(cmd == -1) {
hudakz 0:e455fdb56bc8 186 httpHeader = UNAUTHORIZED;
hudakz 0:e455fdb56bc8 187 httpContent = "<h1>401 Unauthorized</h1>";
hudakz 0:e455fdb56bc8 188 sendHTTP(clientSocket, httpHeader, httpContent);
hudakz 0:e455fdb56bc8 189 continue;
hudakz 0:e455fdb56bc8 190 }
hudakz 0:e455fdb56bc8 191
hudakz 0:e455fdb56bc8 192 if(cmd == ON) {
hudakz 0:e455fdb56bc8 193 sw = ON; // turn the switch on
hudakz 0:e455fdb56bc8 194 }
hudakz 0:e455fdb56bc8 195
hudakz 0:e455fdb56bc8 196 if(cmd == OFF) {
hudakz 0:e455fdb56bc8 197 sw = OFF; // turn the switch off
hudakz 0:e455fdb56bc8 198 }
hudakz 0:e455fdb56bc8 199
hudakz 0:e455fdb56bc8 200 httpHeader = HTTP_OK;
hudakz 0:e455fdb56bc8 201 sendHTTP(clientSocket, httpHeader, showWebPage(sw));
hudakz 0:e455fdb56bc8 202 }
hudakz 0:e455fdb56bc8 203 }