1 // Copyright (c) 2012 Dennco Project
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 // Created by tkawata on 1/28/2012.
20 #include "DNServerHTTPImpl.h"
21 #include "DNServerHTTP.h"
22 #include "DNServerBase.h"
32 const unsigned int DNServerHTTP::HTTPDEFAULTPORT = 50000;
35 DNServerHTTP::DNServerHTTP(DNEngine* engine) : DNServerBase(engine)
37 impl = DNServerHTTPImpl::create(this, DNServerHTTP::clientRequestHandler);
40 DNServerHTTP::~DNServerHTTP()
46 bool DNServerHTTP::isRunning()
48 return impl->isRunning();
51 void DNServerHTTP::start()
56 void DNServerHTTP::stop()
61 void DNServerHTTP::setPortNumber(unsigned int portNumber)
63 impl->setPortNumber(portNumber);
66 void DNServerHTTP::replyWithStatusCode(int code, const char* message)
68 impl->replyWithStatusCode(code, message);
71 void DNServerHTTP::replyWithFile(const char* filePath)
73 impl->replyWithFile(filePath);
77 void DNServerHTTP::clientRequestHandler(DNServerHTTP *server, const char *path, const char *body)
84 if (strncmp(p, "http://", 7) == 0)
91 errorMsg = "Request path is not a valid HTTP path";
97 errorMsg = "Request path is not correct";
102 while(*p && *p != '/')
108 errorMsg = "no request URL. It should be /get or /set";
111 bool isUIRequest = false;
112 bool isQueryRequest = true;
113 const char *pathPart = p;
118 if (strncmp(p, "/ui",3) == 0)
123 if (!isUIRequest && strlen(p) >= 4)
125 if (strncmp(p, "/get",4) == 0)
127 isQueryRequest = true;
130 else if (strncmp(p, "/set",4) == 0)
132 isQueryRequest = false;
138 errorMsg = "request path is not valid. It should be /get or /set";
143 if (!isUIRequest && valid)
145 if (*p != 0 && *p != ' ' && *p != '?')
148 errorMsg = "request path is not valid. It should be /get or /set";
154 std::string response;
157 server->doUIRequest(pathPart);
159 else if(isQueryRequest)
161 server->doQueryRequest(body);
165 server->doSetRequest(body);
170 server->doBadRequest(errorMsg);
175 void DNServerHTTP::doQueryRequest(std::string requestBody)
177 const char *oc = requestBody.c_str();
178 size_t oclen = strlen(oc);
179 char *c = new char[oclen + 1];
180 strncpy(c, oc, oclen + 1);
182 std::string resultString;
184 const char *value = c;
185 const char *name = c;
199 if (strlen(name) == 4 && strncmp(name, "path", 4) == 0)
201 //valid request. do the query
202 float result = mEngine->doClientGetRequest(value);
204 resultString.append(1,',');
207 sprintf(rs, "%12f", result);
208 resultString.append(rs);
220 replyWithStatusCode(200, resultString.c_str());
223 void DNServerHTTP::doSetRequest(std::string requestBody)
225 const char *oc = requestBody.c_str();
226 size_t oclen = strlen(oc);
227 char *c = new char[oclen + 1];
228 strncpy(c, oc, oclen + 1);
230 std::string resultString;
232 const char *value = c;
233 const char *name = c;
247 mEngine->doClientSetRequest(name, value);
261 sprintf(rs, "%12d", cnt);
262 replyWithStatusCode(200, rs);
265 void DNServerHTTP::doUIRequest(const char *path)
267 std::string filepath = getContentPath();
268 trimString(filepath);
269 if (filepath.at(filepath.length()-1) != '/')
271 filepath.append(1,'/');
273 filepath.append(path+1);
274 replyWithFile(filepath.c_str());
278 void DNServerHTTP::doBadRequest(std::string errorMsg)
280 replyWithStatusCode(400, errorMsg.c_str());
283 std::string DNServerHTTP::getContentPath()
285 return mEngine->getContainerRootPath();
289 DNHTTPRequest* DNServerHTTP::parseHttpRequest(const char *message)
291 size_t len = strlen(message);
298 std::string postbody;
306 if (strncmp(message, "POST ", 5) == 0)
312 else if (strncmp(message, "GET ", 4) == 0)
320 //non supported message
327 while (*p && *p == ' ' && *p != '\r' && *p != '\n')
331 if (!*p || *p == '\r' || *p == '\n')
338 while (*p && *p != ' ' && *p != '\r' && *p != '\n')
341 if (*p != ' ' && p - s < 1)
347 path = std::string(s, p - s);
356 if (*p == '\n' && *(p-1) == '\r')
370 const char *he = p-1;
373 if (*p == '\n' && *(p-1) == '\r' && *(p-2) == '\n')
386 if (p-hs >= 5 && strncmp("Host", p-4, 4))
390 while(p <= hs && *p && *p !='\r')
396 host = std::string(tmp, p - tmp - 1);
401 if (p-hs >= 15 && strncmp("Content-Length", p-14,14))
405 while(p <= hs && *p && *p !='\r')
411 contentLen = atoi(std::string(tmp, p - tmp - 1).c_str());
420 if (isPost && contentLen>0)
423 const char *ps = he+1;
424 while (*(ps + bl) && bl < contentLen)
429 postbody = std::string(ps, bl);
435 DNHTTPRequest *request = new DNHTTPRequest();
436 request->isPost = isPost;
440 request->postData = postbody;