30 #include <wdmp_internal.h>
36 #include "hostIf_utils.h"
37 #include "http_server.h"
40 #include "libsoup/soup.h"
42 #include <condition_variable>
44 extern std::mutex mtx_httpServerThreadDone;
45 extern std::condition_variable cv_httpServerThreadDone;
46 extern bool httpServerThreadDone;
49 static SoupServer *http_server = NULL;
51 static void HTTPRequestHandler(
56 SoupClientContext *client,
59 cJSON *jsonRequest = NULL;
60 cJSON *jsonResponse = NULL;
61 req_struct *reqSt = NULL;
62 res_struct *respSt = NULL;
64 struct timespec start,end,*startPtr,*endPtr;
68 RDK_LOG(RDK_LOG_TRACE1, LOG_TR69HOSTIF,
"[%s:%s] Entering..\n", __FUNCTION__, __FILE__);
70 if (!msg->request_body ||
71 !msg->request_body->data ||
72 !msg->request_body->length)
74 soup_message_set_status_full (msg, SOUP_STATUS_BAD_REQUEST,
"No request data.");
75 RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF,
"[%s:%s] Exiting.. Failed due to no message data.\n", __FUNCTION__, __FILE__);
79 const char *pcCallerID = (
char *)soup_message_headers_get_one(msg->request_headers,
"CallerID");
81 jsonRequest = cJSON_Parse((
const char *) msg->request_body->data);
85 reqSt = (req_struct *)malloc(
sizeof(req_struct));
88 soup_message_set_status_full (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR,
"Cannot create return object");
89 RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF,
"[%s:%s] Exiting.. Failed to create req_struct\n", __FUNCTION__, __FILE__);
92 memset(reqSt, 0,
sizeof(req_struct));
94 if(!strcmp(msg->method,
"GET"))
96 if(!pcCallerID || !strlen(pcCallerID))
98 pcCallerID =
"Unknown";
99 RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF,
"[%s:%s] Unknown Caller ID, GET is allowed by default\n", __FUNCTION__, __FILE__);
102 RDK_LOG(RDK_LOG_DEBUG, LOG_TR69HOSTIF,
"[%s:%s] GET with CallerID : %s..\n", __FUNCTION__, __FILE__, pcCallerID);
103 parse_get_request(jsonRequest, &reqSt, WDMP_TR181);
104 respSt = handleRequest(pcCallerID, reqSt);
107 jsonResponse = cJSON_CreateObject();
108 wdmp_form_get_response(respSt, jsonResponse);
113 for(
int paramIndex = 0; paramIndex < respSt->paramCnt; paramIndex++)
115 if(respSt->retStatus[paramIndex] != 0 || paramIndex == respSt->paramCnt-1)
117 new_st_code = respSt->retStatus[paramIndex];
121 cJSON * stcode = cJSON_GetObjectItem(jsonResponse,
"statusCode");
124 cJSON_SetIntValue(stcode, new_st_code);
129 soup_message_set_status_full (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR,
"Invalid request format");
130 RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF,
"[%s:%s] Exiting.. Request couldn't be processed\n", __FUNCTION__, __FILE__);
134 else if(!strcmp(msg->method,
"POST"))
136 if(!pcCallerID || !strlen(pcCallerID))
138 soup_message_set_status_full (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR,
"POST Not Allowed without CallerID");
139 RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF,
"[%s:%s] Exiting.. POST operation not allowed with unknown CallerID\n", __FUNCTION__, __FILE__);
140 wdmp_free_req_struct(reqSt);
145 RDK_LOG(RDK_LOG_DEBUG, LOG_TR69HOSTIF,
"[%s:%s] POST with CallerID : %s..\n", __FUNCTION__, __FILE__, pcCallerID);
147 parse_set_request(jsonRequest, &reqSt, WDMP_TR181);
148 RDK_LOG(RDK_LOG_DEBUG, LOG_TR69HOSTIF,
"Calling handleRequest...\n");
149 respSt = handleRequest(pcCallerID, reqSt);
152 jsonResponse = cJSON_CreateObject();
153 wdmp_form_set_response(respSt, jsonResponse);
157 for(
int paramIndex = 0; paramIndex < respSt->paramCnt; paramIndex++)
159 if(respSt->retStatus[paramIndex] != 0 || paramIndex == respSt->paramCnt-1)
161 new_st_code = respSt->retStatus[paramIndex];
165 cJSON * stcode = cJSON_GetObjectItem(jsonResponse,
"statusCode");
168 cJSON_SetIntValue(stcode, new_st_code);
173 soup_message_set_status_full (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR,
"Invalid request format");
174 RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF,
"[%s:%s] Exiting.. Request couldn't be processed\n", __FUNCTION__, __FILE__);
175 wdmp_free_req_struct(reqSt);
182 soup_message_set_status_full (msg, SOUP_STATUS_NOT_IMPLEMENTED,
"Method not implemented");
183 RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF,
"[%s:%s] Exiting.. Unsupported operation \n", __FUNCTION__, __FILE__);
184 wdmp_free_req_struct(reqSt);
189 char *buf = cJSON_Print(jsonResponse);
192 soup_message_set_response(msg, (
const char *)
"application/json", SOUP_MEMORY_COPY, buf, strlen(buf));
193 soup_message_set_status (msg, SOUP_STATUS_OK);
196 wdmp_free_req_struct(reqSt);
198 cJSON_Delete(jsonRequest);
199 cJSON_Delete(jsonResponse);
200 wdmp_free_res_struct(respSt);
210 soup_message_set_status_full (msg, SOUP_STATUS_BAD_REQUEST,
"Bad Request");
211 RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF,
"[%s:%s] Exiting.. Failed to parse JSON Message \n", __FUNCTION__, __FILE__);
216 RDK_LOG(RDK_LOG_DEBUG,LOG_TR69HOSTIF,
"Curl Request Processing Time : %lu ms\n", timeValDiff(startPtr, endPtr));
217 RDK_LOG(RDK_LOG_TRACE1, LOG_TR69HOSTIF,
"[%s:%s] Exiting..\n", __FUNCTION__, __FILE__);
222 void *HTTPServerStartThread(
void *msg)
225 GError *error = NULL;
227 guint httpServerPort = argList.httpServerPort;
229 RDK_LOG(RDK_LOG_TRACE1, LOG_TR69HOSTIF,
"[%s:%s] Entering..\n", __FUNCTION__, __FILE__);
231 #ifndef GLIB_VERSION_2_36
235 status = checkDataModelStatus();
238 RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,
"Error in Data Model Initialization\n");
242 if(http_server == NULL)
243 http_server = soup_server_new (SOUP_SERVER_SERVER_HEADER,
"HTTPServer", NULL);
247 RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF,
"SERVER: Could not create server.\n");
252 soup_server_add_handler (http_server, (
const char*)
"/", HTTPRequestHandler, NULL, NULL);
254 if(FALSE == soup_server_listen_local (http_server, httpServerPort, SOUP_SERVER_LISTEN_IPV4_ONLY, &error))
256 RDK_LOG(RDK_LOG_ERROR, LOG_TR69HOSTIF,
"SERVER: failed in soup_server_listen_local. (%s).\n", error->message);
260 ofstream ofs(
"/tmp/.tr69hostif_http_server_ready", ios::trunc | ios::out);
262 RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF,
"Failed to open : /tmp/.tr69hostif_http_server_ready \n");
266 RDK_LOG(RDK_LOG_DEBUG, LOG_TR69HOSTIF,
"SERVER: Started server successfully.\n");
270 std::unique_lock<std::mutex> lck(mtx_httpServerThreadDone);
271 httpServerThreadDone =
true;
272 cv_httpServerThreadDone.notify_all();
275 RDK_LOG(RDK_LOG_TRACE1, LOG_TR69HOSTIF,
"[%s:%s] Exiting..\n", __FUNCTION__, __FILE__);
279 void HttpServerStop()
281 RDK_LOG(RDK_LOG_TRACE1, LOG_TR69HOSTIF,
"SERVER: Stopping HTTP Server....\n");
283 std::unique_lock<std::mutex> lck(mtx_httpServerThreadDone);
284 httpServerThreadDone =
false;
285 soup_server_disconnect(http_server);
286 RDK_LOG(RDK_LOG_TRACE1, LOG_TR69HOSTIF,
"SERVER: Stopped server successfully.\n");