Measure system

Dependencies:   EthernetNetIf mbed RF12B

Committer:
benecsj
Date:
Thu Mar 03 08:45:49 2011 +0000
Revision:
0:8d62137f7ff4
Child:
1:b26ab2467b1a
For FRIENDs.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
benecsj 0:8d62137f7ff4 1
benecsj 0:8d62137f7ff4 2 /*
benecsj 0:8d62137f7ff4 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
benecsj 0:8d62137f7ff4 4
benecsj 0:8d62137f7ff4 5 Permission is hereby granted, free of charge, to any person obtaining a copy
benecsj 0:8d62137f7ff4 6 of this software and associated documentation files (the "Software"), to deal
benecsj 0:8d62137f7ff4 7 in the Software without restriction, including without limitation the rights
benecsj 0:8d62137f7ff4 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
benecsj 0:8d62137f7ff4 9 copies of the Software, and to permit persons to whom the Software is
benecsj 0:8d62137f7ff4 10 furnished to do so, subject to the following conditions:
benecsj 0:8d62137f7ff4 11
benecsj 0:8d62137f7ff4 12 The above copyright notice and this permission notice shall be included in
benecsj 0:8d62137f7ff4 13 all copies or substantial portions of the Software.
benecsj 0:8d62137f7ff4 14
benecsj 0:8d62137f7ff4 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
benecsj 0:8d62137f7ff4 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
benecsj 0:8d62137f7ff4 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
benecsj 0:8d62137f7ff4 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
benecsj 0:8d62137f7ff4 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
benecsj 0:8d62137f7ff4 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
benecsj 0:8d62137f7ff4 21 THE SOFTWARE.
benecsj 0:8d62137f7ff4 22 */
benecsj 0:8d62137f7ff4 23
benecsj 0:8d62137f7ff4 24 #include "core/netservice.h"
benecsj 0:8d62137f7ff4 25 #include "HTTPRequestDispatcher.h"
benecsj 0:8d62137f7ff4 26 #include "HTTPRequestHandler.h"
benecsj 0:8d62137f7ff4 27 #include "mbed.h"
benecsj 0:8d62137f7ff4 28 #include <string.h>
benecsj 0:8d62137f7ff4 29
benecsj 0:8d62137f7ff4 30 //#define __DEBUG
benecsj 0:8d62137f7ff4 31 //#include "dbg/dbg.h"
benecsj 0:8d62137f7ff4 32
benecsj 0:8d62137f7ff4 33 HTTPRequestDispatcher::HTTPRequestDispatcher(HTTPServer* pSvr, TCPSocket* pTCPSocket) : NetService(), m_pSvr(pSvr), m_pTCPSocket(pTCPSocket), m_watchdog(), m_closed(false)
benecsj 0:8d62137f7ff4 34 {
benecsj 0:8d62137f7ff4 35 printf("1-DIS-Dispatcher started\r\n");
benecsj 0:8d62137f7ff4 36 m_pTCPSocket->setOnEvent(this, &HTTPRequestDispatcher::onTCPSocketEvent);
benecsj 0:8d62137f7ff4 37 m_watchdog.attach_us<HTTPRequestDispatcher>(this, &HTTPRequestDispatcher::onTimeout, HTTP_REQUEST_TIMEOUT * 1000);
benecsj 0:8d62137f7ff4 38 }
benecsj 0:8d62137f7ff4 39
benecsj 0:8d62137f7ff4 40 HTTPRequestDispatcher::~HTTPRequestDispatcher()
benecsj 0:8d62137f7ff4 41 {
benecsj 0:8d62137f7ff4 42 printf("1-DIS-Dispatcher closed\r\n");
benecsj 0:8d62137f7ff4 43 close();
benecsj 0:8d62137f7ff4 44 }
benecsj 0:8d62137f7ff4 45
benecsj 0:8d62137f7ff4 46 void HTTPRequestDispatcher::dispatchRequest()
benecsj 0:8d62137f7ff4 47 {
benecsj 0:8d62137f7ff4 48 string path;
benecsj 0:8d62137f7ff4 49 string meth;
benecsj 0:8d62137f7ff4 50 HTTP_METH methCode;
benecsj 0:8d62137f7ff4 51
benecsj 0:8d62137f7ff4 52 printf("1-DIS-nDispatching req\r\n");
benecsj 0:8d62137f7ff4 53
benecsj 0:8d62137f7ff4 54 if( !getRequest(&path, &meth ) )
benecsj 0:8d62137f7ff4 55 {
benecsj 0:8d62137f7ff4 56 HandlerActive = false;
benecsj 0:8d62137f7ff4 57 close();
benecsj 0:8d62137f7ff4 58 return; //Invalid request
benecsj 0:8d62137f7ff4 59 }
benecsj 0:8d62137f7ff4 60
benecsj 0:8d62137f7ff4 61 if( !meth.compare("GET") )
benecsj 0:8d62137f7ff4 62 {
benecsj 0:8d62137f7ff4 63 methCode = HTTP_GET;
benecsj 0:8d62137f7ff4 64 }
benecsj 0:8d62137f7ff4 65 else if( !meth.compare("POST") )
benecsj 0:8d62137f7ff4 66 {
benecsj 0:8d62137f7ff4 67 methCode = HTTP_POST;
benecsj 0:8d62137f7ff4 68 }
benecsj 0:8d62137f7ff4 69 else if( !meth.compare("HEAD") )
benecsj 0:8d62137f7ff4 70 {
benecsj 0:8d62137f7ff4 71 methCode = HTTP_HEAD;
benecsj 0:8d62137f7ff4 72 }
benecsj 0:8d62137f7ff4 73 else
benecsj 0:8d62137f7ff4 74 {
benecsj 0:8d62137f7ff4 75 close(); //Parse error
benecsj 0:8d62137f7ff4 76 return;
benecsj 0:8d62137f7ff4 77 }
benecsj 0:8d62137f7ff4 78
benecsj 0:8d62137f7ff4 79 printf("1-DIS-Looking for a handler\r\n");
benecsj 0:8d62137f7ff4 80
benecsj 0:8d62137f7ff4 81 map< string, HTTPRequestHandler*(*)(const char*, const char*, TCPSocket*) >::iterator it;
benecsj 0:8d62137f7ff4 82 // it = m_pSvr->m_lpHandlers.find(rootPath); //We are friends so we can do that
benecsj 0:8d62137f7ff4 83 // NEW CODE START:
benecsj 0:8d62137f7ff4 84 int root_len = 0;
benecsj 0:8d62137f7ff4 85 for (it = m_pSvr->m_lpHandlers.begin(); it != m_pSvr->m_lpHandlers.end(); it++)
benecsj 0:8d62137f7ff4 86 {
benecsj 0:8d62137f7ff4 87 printf("1-DIS-Checking %s...\r\n", (*it).first.c_str());
benecsj 0:8d62137f7ff4 88 root_len = (*it).first.length();
benecsj 0:8d62137f7ff4 89 if ( root_len &&
benecsj 0:8d62137f7ff4 90 !path.compare( 0, root_len, (*it).first ) &&
benecsj 0:8d62137f7ff4 91 (path[root_len] == '/' || path[root_len] == '\0'))
benecsj 0:8d62137f7ff4 92 {
benecsj 0:8d62137f7ff4 93 printf("1-DIS-Found (%s)\r\n", (*it).first.c_str());
benecsj 0:8d62137f7ff4 94 // Found!
benecsj 0:8d62137f7ff4 95 break; // for
benecsj 0:8d62137f7ff4 96 }
benecsj 0:8d62137f7ff4 97 }
benecsj 0:8d62137f7ff4 98 // NEW CODE END
benecsj 0:8d62137f7ff4 99 if((it == m_pSvr->m_lpHandlers.end()) && !(m_pSvr->m_lpHandlers.empty()))
benecsj 0:8d62137f7ff4 100 {
benecsj 0:8d62137f7ff4 101 printf("1-DIS-Using default handler\r\n");
benecsj 0:8d62137f7ff4 102 it = m_pSvr->m_lpHandlers.end();
benecsj 0:8d62137f7ff4 103 it--; //Get the last element
benecsj 0:8d62137f7ff4 104 if( ! (((*it).first.length() == 0) || !(*it).first.compare("/")) ) //This is not the default handler
benecsj 0:8d62137f7ff4 105 it = m_pSvr->m_lpHandlers.end();
benecsj 0:8d62137f7ff4 106 root_len = 0;
benecsj 0:8d62137f7ff4 107 }
benecsj 0:8d62137f7ff4 108 if(it == m_pSvr->m_lpHandlers.end())
benecsj 0:8d62137f7ff4 109 {
benecsj 0:8d62137f7ff4 110 printf("1-DIS-No handler found\r\n");
benecsj 0:8d62137f7ff4 111 HandlerActive = false;
benecsj 0:8d62137f7ff4 112 close(); //No handler found
benecsj 0:8d62137f7ff4 113 return;
benecsj 0:8d62137f7ff4 114 }
benecsj 0:8d62137f7ff4 115
benecsj 0:8d62137f7ff4 116 printf("1-DIS-Handler found.\r\n");
benecsj 0:8d62137f7ff4 117
benecsj 0:8d62137f7ff4 118 //HTTPRequestHandler* pHdlr = (*it).second(rootPath.c_str(), subPath.c_str(), m_pTCPSocket);
benecsj 0:8d62137f7ff4 119 //NEW CODE 1 LINE:
benecsj 0:8d62137f7ff4 120
benecsj 0:8d62137f7ff4 121
benecsj 0:8d62137f7ff4 122 HTTPRequestHandler* pHdlr = (*it).second((*it).first.c_str(), path.c_str() + root_len, m_pTCPSocket);
benecsj 0:8d62137f7ff4 123 m_pTCPSocket = NULL; //We don't own it anymore
benecsj 0:8d62137f7ff4 124
benecsj 0:8d62137f7ff4 125 printf ("1-DIS-Calling handler...\r\n") ;
benecsj 0:8d62137f7ff4 126 switch(methCode)
benecsj 0:8d62137f7ff4 127 {
benecsj 0:8d62137f7ff4 128 case HTTP_GET:
benecsj 0:8d62137f7ff4 129 pHdlr->doGet();
benecsj 0:8d62137f7ff4 130 break;
benecsj 0:8d62137f7ff4 131 case HTTP_POST:
benecsj 0:8d62137f7ff4 132 pHdlr->doPost();
benecsj 0:8d62137f7ff4 133 break;
benecsj 0:8d62137f7ff4 134 case HTTP_HEAD:
benecsj 0:8d62137f7ff4 135 pHdlr->doHead();
benecsj 0:8d62137f7ff4 136 break;
benecsj 0:8d62137f7ff4 137 }
benecsj 0:8d62137f7ff4 138
benecsj 0:8d62137f7ff4 139 printf("1-DIS-Req handled (or being handled)\r\n");
benecsj 0:8d62137f7ff4 140 close();
benecsj 0:8d62137f7ff4 141 }
benecsj 0:8d62137f7ff4 142
benecsj 0:8d62137f7ff4 143 void HTTPRequestDispatcher::close() //Close socket and destroy data
benecsj 0:8d62137f7ff4 144 {
benecsj 0:8d62137f7ff4 145 if(m_closed)
benecsj 0:8d62137f7ff4 146 return;
benecsj 0:8d62137f7ff4 147 m_closed = true; //Prevent recursive calling or calling on an object being destructed by someone else
benecsj 0:8d62137f7ff4 148 m_watchdog.detach();
benecsj 0:8d62137f7ff4 149 if(m_pTCPSocket) //m_pTCPSocket Should only be destroyed if ownership not passed to an handler
benecsj 0:8d62137f7ff4 150 {
benecsj 0:8d62137f7ff4 151 m_pTCPSocket->resetOnEvent();
benecsj 0:8d62137f7ff4 152 m_pTCPSocket->close();
benecsj 0:8d62137f7ff4 153 delete m_pTCPSocket; //This fn might have been called by this socket (through an event), so DO NOT DESTROY IT HERE
benecsj 0:8d62137f7ff4 154 }
benecsj 0:8d62137f7ff4 155 NetService::close();
benecsj 0:8d62137f7ff4 156 }
benecsj 0:8d62137f7ff4 157
benecsj 0:8d62137f7ff4 158
benecsj 0:8d62137f7ff4 159 void HTTPRequestDispatcher::onTimeout() //Connection has timed out
benecsj 0:8d62137f7ff4 160 {
benecsj 0:8d62137f7ff4 161 close();
benecsj 0:8d62137f7ff4 162 }
benecsj 0:8d62137f7ff4 163
benecsj 0:8d62137f7ff4 164 bool HTTPRequestDispatcher::getRequest(string* path, string* meth)
benecsj 0:8d62137f7ff4 165 {
benecsj 0:8d62137f7ff4 166 char req[128];
benecsj 0:8d62137f7ff4 167 char c_path[128];
benecsj 0:8d62137f7ff4 168 char c_meth[128];
benecsj 0:8d62137f7ff4 169 const int maxLen = 128;
benecsj 0:8d62137f7ff4 170 char* p = req;
benecsj 0:8d62137f7ff4 171 //Read Line
benecsj 0:8d62137f7ff4 172 int ret;
benecsj 0:8d62137f7ff4 173 int len = 0;
benecsj 0:8d62137f7ff4 174 for(int i = 0; i < maxLen - 1; i++)
benecsj 0:8d62137f7ff4 175 {
benecsj 0:8d62137f7ff4 176 ret = m_pTCPSocket->recv(p, 1);
benecsj 0:8d62137f7ff4 177 if(!ret)
benecsj 0:8d62137f7ff4 178 {
benecsj 0:8d62137f7ff4 179 break;
benecsj 0:8d62137f7ff4 180 }
benecsj 0:8d62137f7ff4 181 if( (len > 1) && *(p-1)=='\r' && *p=='\n' )
benecsj 0:8d62137f7ff4 182 {
benecsj 0:8d62137f7ff4 183 p--;
benecsj 0:8d62137f7ff4 184 len-=2;
benecsj 0:8d62137f7ff4 185 break;
benecsj 0:8d62137f7ff4 186 }
benecsj 0:8d62137f7ff4 187 else if( *p=='\n' )
benecsj 0:8d62137f7ff4 188 {
benecsj 0:8d62137f7ff4 189 len--;
benecsj 0:8d62137f7ff4 190 break;
benecsj 0:8d62137f7ff4 191 }
benecsj 0:8d62137f7ff4 192 p++;
benecsj 0:8d62137f7ff4 193 len++;
benecsj 0:8d62137f7ff4 194 }
benecsj 0:8d62137f7ff4 195 *p = 0;
benecsj 0:8d62137f7ff4 196
benecsj 0:8d62137f7ff4 197 printf("1-DIS-Parsing request : %s\r\n", req);
benecsj 0:8d62137f7ff4 198
benecsj 0:8d62137f7ff4 199 ret = sscanf(req, "%s %s HTTP/%*d.%*d", c_meth, c_path);
benecsj 0:8d62137f7ff4 200 if(ret !=2)
benecsj 0:8d62137f7ff4 201 return false;
benecsj 0:8d62137f7ff4 202
benecsj 0:8d62137f7ff4 203 *meth = string(c_meth);
benecsj 0:8d62137f7ff4 204 // NEW CODE (old code removed):
benecsj 0:8d62137f7ff4 205 *path = string(c_path);
benecsj 0:8d62137f7ff4 206 return true;
benecsj 0:8d62137f7ff4 207 }
benecsj 0:8d62137f7ff4 208
benecsj 0:8d62137f7ff4 209
benecsj 0:8d62137f7ff4 210
benecsj 0:8d62137f7ff4 211 void HTTPRequestDispatcher::onTCPSocketEvent(TCPSocketEvent e)
benecsj 0:8d62137f7ff4 212 {
benecsj 0:8d62137f7ff4 213
benecsj 0:8d62137f7ff4 214 printf("1-DIS-Event %d\r\n", e);
benecsj 0:8d62137f7ff4 215
benecsj 0:8d62137f7ff4 216 if(m_closed)
benecsj 0:8d62137f7ff4 217 {
benecsj 0:8d62137f7ff4 218 printf("1-DIS-WARN: Discarded\r\n");
benecsj 0:8d62137f7ff4 219 return;
benecsj 0:8d62137f7ff4 220 }
benecsj 0:8d62137f7ff4 221
benecsj 0:8d62137f7ff4 222 switch(e)
benecsj 0:8d62137f7ff4 223 {
benecsj 0:8d62137f7ff4 224 case TCPSOCKET_READABLE:
benecsj 0:8d62137f7ff4 225 m_watchdog.detach();
benecsj 0:8d62137f7ff4 226 m_pTCPSocket->resetOnEvent();
benecsj 0:8d62137f7ff4 227 //Req arrived, dispatch :
benecsj 0:8d62137f7ff4 228 dispatchRequest();
benecsj 0:8d62137f7ff4 229 break;
benecsj 0:8d62137f7ff4 230 case TCPSOCKET_CONTIMEOUT:
benecsj 0:8d62137f7ff4 231 case TCPSOCKET_CONRST:
benecsj 0:8d62137f7ff4 232 case TCPSOCKET_CONABRT:
benecsj 0:8d62137f7ff4 233 case TCPSOCKET_ERROR:
benecsj 0:8d62137f7ff4 234 case TCPSOCKET_DISCONNECTED:
benecsj 0:8d62137f7ff4 235 HandlerActive = false;
benecsj 0:8d62137f7ff4 236 close();
benecsj 0:8d62137f7ff4 237 break;
benecsj 0:8d62137f7ff4 238 }
benecsj 0:8d62137f7ff4 239
benecsj 0:8d62137f7ff4 240 }