1 //******************************************************************
3 // Copyright 2014 Intel Corporation.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #include "WrapResource.h"
22 #include "RestInput.h"
23 #include "LineInput.h"
24 #include "OICMiddle.h"
31 static bool enableDebug = false; // set to true to print debug messages
33 void printDebugMessage(std::string message)
36 cout << "RestInput: " << message << endl;
40 RestInput::RestInput(LineInput *lineInput) : m_lineInput(lineInput)
42 m_data = (char*)malloc(BUFLEN);
43 m_thread = new std::thread[MAX_CONNS];
47 bool RestInput::init()
49 m_sockfd = socket(AF_INET, SOCK_STREAM, 0);
51 cerr << "Failed to open socket. Exiting" << endl;
54 m_port = 1441; //listening on port 1441
56 m_serverAddr.sin_family = AF_INET;
57 m_serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
58 m_serverAddr.sin_port = htons(m_port);
60 if (::bind(m_sockfd, (struct sockaddr*)&m_serverAddr, sizeof m_serverAddr) < 0) {
61 cerr << "Failed to bind. Exiting " << endl;
65 listen(m_sockfd, MAX_CONNS);
66 startAccept(m_sockfd);
70 // accept incoming connection(s)
71 void RestInput::startAccept(int &sockfd)
73 if (m_threadCount >= MAX_CONNS) {
74 cerr << " Max # of connections reached. Skipping " << endl;
78 int connfd = accept(sockfd, (struct sockaddr *)NULL, NULL);
80 cerr << " Failed to accept incoming connection " << endl;
83 int n = read(connfd, m_data, BUFLEN);
85 cerr << "Failed to read from socket" << endl;
93 // start client thread
94 void RestInput::startThread()
96 std::thread t(&RestInput::processClient, this);
97 m_thread[m_threadCount] = std::move(t);
98 m_thread[m_threadCount++].join();
101 // process read commands for the client
102 void RestInput::processClient(void)
104 std::string restCmd = m_data;
105 std::size_t found = restCmd.find('\n');
106 if (found != std::string::npos) {
107 restCmd = restCmd.substr(0, found-1);
112 void RestInput::handleRead(std::string& restCmd)
114 parseString(restCmd);
115 if (restCmd.find("exit") == 0) {
116 std::thread::id id = std::this_thread::get_id();
117 for(int i = 0; i < m_threadCount; ++i) {
118 if (id == m_thread[i].get_id()) {
119 m_thread[i].detach();
121 cout << "Exiting thread " << id << endl;
128 std::string msg = "command sent to LineInput is: " + restCmd;
129 printDebugMessage(msg);
130 m_lineInput->processLine(restCmd, ss, cb);
131 if (restCmd.find("show") != string::npos) {
132 // if command is show, we want to list out the details of each resource
137 void RestInput::handleShow(stringstream &ss, observecb_t &cb) {
138 std::string temp = ss.str();
139 size_t n = std::count(temp.begin(), temp.end(), '\n'); // number of resources found
140 std::stringstream sstm;
141 std::string lineInputData;
143 for (size_t i = 0; i < n; ++i) {
145 sstm << "details " << i;
146 lineInputData = sstm.str();
147 std::string msg = "Details: " + lineInputData;
148 printDebugMessage(msg);
149 m_lineInput->processLine(lineInputData, ss, cb);
152 lineInputData = sstm.str();
153 msg = "Get: " + lineInputData;
154 printDebugMessage(msg);
155 m_lineInput->processLine(lineInputData, ss, cb);
159 void RestInput::parseString(std::string &toParse)
161 std::size_t pos = toParse.find("HTTP"); // split on HTTP
162 toParse = toParse.substr(0, pos);
163 pos = toParse.find("/"); // find 1st occurance of /
164 toParse = toParse.substr(pos + 1, toParse.size() - 1);
165 std::replace(toParse.begin(), toParse.end(), '/', ' '); // replace all '/' with ' '