Line data Source code
1 : #include "RequestHandler.h"
2 :
3 : #define MAX_LEN_TOKEN_BUFFER 100
4 : #define BUFFER_SMALL_SIZE 100
5 : #define BUFFER_MSG_SIZE 1000
6 :
7 158 : RequestHandler::RequestHandler(http_message *pMessage, mg_connection *pConnection, std::string shared) :
8 158 : connection(pConnection), http_msg(pMessage) {
9 158 : server_databases_t *databases = ((server_databases_t *) connection->user_data);
10 158 : msgHandler = new MessageHandler(databases);
11 158 : msgHandler->setSharedLink(shared);
12 158 : }
13 :
14 158 : RequestHandler::~RequestHandler() {
15 158 : delete msgHandler;
16 158 : }
17 :
18 10 : void RequestHandler::sendHttpLine(int status_code) {
19 10 : sendHttpReply("","",status_code);
20 10 : }
21 :
22 40 : void RequestHandler::sendHttpReply(std::string reply, std::string content_type, int status) {
23 40 : LOGG(DEBUG) << "Sending reply: "<< status;
24 : mg_printf(connection, "HTTP/1.1 %d\r\n"
25 : "Content-Type: %s\r\n"
26 : "Content-Length: %d\r\n"
27 : "\r\n"
28 : "%s", status, content_type.c_str(),
29 40 : (int) reply.size(), reply.c_str());
30 40 : LOGG(DEBUG) << "Content type: " << content_type;
31 40 : LOGG(DEBUG) << "Content length: " << reply.size();
32 40 : if (reply.length() > 50){
33 6 : LOGG(DEBUG) << "Body: " << reply.substr(0,49) << "...";
34 : }else{
35 34 : LOGG(DEBUG) << "Body: " << reply;
36 : }
37 :
38 40 : }
39 :
40 22 : bool RequestHandler::validateToken() {
41 : char buffer[MAX_LEN_TOKEN_BUFFER];
42 22 : int parsed = mg_get_http_var(&http_msg->query_string, TOKEN_VARIABLE_NAME, buffer, sizeof(buffer));
43 22 : if (!parsed){
44 0 : sendHttpLine(BAD_REQUEST);
45 0 : return false;
46 : }
47 22 : std::string token(buffer);
48 22 : LOGG(DEBUG) << "Validating Token for connection: " << token;
49 22 : if (! msgHandler->validateToken(token)) {
50 3 : this->sendHttpReply("", "", AUTHENTICATION_ERROR);
51 3 : return false;
52 : }
53 19 : LOGG(DEBUG) << "Valid token";
54 19 : return true;
55 : }
56 :
57 1 : void RequestHandler::rejectConnection(int error_code) {
58 1 : LOGG(DEBUG) << "Rejected Connection " << error_code;
59 1 : sendHttpLine(error_code);
60 1 : connection->flags |= MG_F_SEND_AND_CLOSE;
61 1 : }
62 :
63 17 : bool RequestHandler::parseAuthorization(string &user, string &pass) {
64 : char user_[BUFFER_SMALL_SIZE], pass_[BUFFER_SMALL_SIZE];
65 :
66 17 : struct mg_str *hdr = mg_get_http_header(http_msg, AUTHORIZATION_HEADER);
67 17 : mg_http_parse_header(hdr, AUTHORIZATION_HEADER_USER, user_, sizeof(user_));
68 17 : mg_http_parse_header(hdr, AUTHORIZATION_HEADER_PASS, pass_, sizeof(pass_));
69 :
70 :
71 17 : if (! is_equal(&http_msg->uri, USERS_URI) && ! is_equal(&http_msg->uri, USER_URI)) {
72 0 : LOGG(DEBUG) << "Cannot authenticae to this uri";
73 0 : rejectConnection(NOT_IMPLEMENTED);
74 0 : return false;
75 : }
76 17 : user = std::string(user_);
77 17 : pass = std::string(pass_);
78 17 : LOGG(DEBUG) << "Auth header parsed for " << user;
79 17 : return true;
80 : }
81 :
82 22 : bool RequestHandler::login() {
83 22 : return validateToken();
84 : }
85 :
86 15 : void RequestHandler::listenUserPost() {
87 15 : LOGG(DEBUG) << POST_S;
88 30 : string user, pass;
89 15 : if (! parseAuthorization(user, pass)) {
90 0 : return;
91 : }
92 15 : if (! msgHandler->authenticate(user, pass) ) {
93 0 : rejectConnection(UNAUTHORIZED);
94 0 : return;
95 : }
96 15 : msgHandler->setUser(user);
97 15 : LOGG(DEBUG) << "Logged in: " << user;
98 : char localization[500];
99 15 : int parsed = mg_get_http_var(&http_msg->body, USER_LOCATION_TOKEN, localization, sizeof(localization));
100 :
101 15 : if (parsed <= 0 ){
102 0 : sendHttpLine(BAD_REQUEST);
103 0 : return;
104 : }
105 15 : bool updated = msgHandler->addLocalization(std::string(localization));
106 15 : if (! updated){
107 0 : sendHttpLine(BAD_REQUEST);
108 : }else{
109 15 : string token = msgHandler->getToken();
110 15 : sendHttpReply(token,CONTENT_TYPE_HEADER_PLAIN,STATUS_OK);
111 15 : }
112 : }
113 :
114 3 : void RequestHandler::listenUserGet() {
115 3 : LOGG(DEBUG) << GET_S;
116 : char username[BUFFER_SMALL_SIZE];
117 3 : int parsed = mg_get_http_var(&http_msg->query_string, QUERY_STRING_RESOURCE_ID, username, sizeof(username));
118 :
119 3 : if (parsed <= 0 ) {
120 0 : sendHttpLine(BAD_REQUEST);
121 3 : return;
122 : }
123 3 : std::string user_data;
124 3 : msgHandler->getUser(std::string(username), user_data);
125 :
126 3 : sendHttpReply(user_data, CONTENT_TYPE_HEADER_CSV, STATUS_OK);
127 : }
128 :
129 18 : void RequestHandler::listenUserRequest() {
130 18 : LOGG(DEBUG) << "Listening User Request";
131 18 : if (is_equal(&http_msg->method, POST_S)) {
132 15 : listenUserPost();
133 15 : return;
134 : }
135 :
136 3 : if (! login()) {
137 0 : return;
138 : }
139 :
140 3 : if (is_equal(&http_msg->method, GET_S)) {
141 3 : listenUserGet();
142 3 : return;
143 : }
144 :
145 0 : sendHttpLine(NOT_IMPLEMENTED);
146 : }
147 :
148 2 : void RequestHandler::listenUsersPost() {
149 2 : LOGG(DEBUG) << POST_S;
150 : char user_data[1000];
151 4 : string user, pass;
152 2 : if (! parseAuthorization(user, pass)) {
153 0 : return;
154 : }
155 2 : int parsed = mg_get_http_var(&http_msg->body, BODY_USER, user_data, sizeof(user_data));
156 2 : if (parsed <= 0 ) {
157 0 : sendHttpLine(BAD_REQUEST);
158 0 : return;
159 : }
160 : try {
161 2 : msgHandler->setUser( user );
162 3 : bool created = msgHandler->createUser(std::string(user_data), std::string(pass));
163 1 : if (! created){
164 0 : LOGG(DEBUG) << "Cannot create user " << user;
165 0 : rejectConnection(BAD_REQUEST);
166 : }else{
167 1 : sendHttpReply(msgHandler->getToken(), CONTENT_TYPE_HEADER_PLAIN, CREATED);
168 : }
169 :
170 1 : } catch (ExistentUserException existentUserException) {
171 1 : rejectConnection(UNAUTHORIZED);
172 2 : }
173 : }
174 :
175 0 : void RequestHandler::listenUsersGet() {
176 0 : LOGG(DEBUG) << GET_S;
177 0 : std::string users_data;
178 0 : msgHandler->getUsers(users_data);
179 0 : sendHttpReply(users_data, CONTENT_TYPE_HEADER_CSV, STATUS_OK);
180 0 : }
181 :
182 2 : void RequestHandler::listenUsersPut() {
183 2 : LOGG(DEBUG) << PUT_S;
184 : char user_data[1000];
185 2 : int parsed = mg_get_http_var(&http_msg->body, BODY_USER, user_data, sizeof(user_data));
186 2 : if (parsed <= 0 ) {
187 0 : LOGG(DEBUG) << "No 'User=' in request, recieved: " << http_msg->body.p;
188 0 : sendHttpLine(BAD_REQUEST);
189 2 : return;
190 : }
191 2 : bool updated = msgHandler->updateUser(string(user_data));
192 2 : int status = (updated) ? STATUS_OK: BAD_REQUEST;
193 2 : sendHttpLine(status);
194 : }
195 :
196 1 : void RequestHandler::listenUsersDelete() {
197 1 : LOGG(DEBUG) << DELETE_S;
198 1 : bool deleted = msgHandler->deleteUser();
199 1 : int status = (deleted) ? STATUS_OK: BAD_REQUEST;
200 1 : sendHttpLine(status);
201 1 : }
202 :
203 6 : void RequestHandler::listenUsersRequest() {
204 6 : LOGG(DEBUG) << "Listening UserS request";
205 6 : if (is_equal(&http_msg->method, POST_S)) {
206 2 : listenUsersPost();
207 : return;
208 6 : }
209 9 : if (! login()) {
210 : return;
211 : }
212 3 :
213 0 : if (is_equal(&http_msg->method, GET_S)) {
214 3 : listenUsersGet();
215 2 : } else if (is_equal(&http_msg->method, PUT_S)) {
216 1 : listenUsersPut();
217 1 : } else if (is_equal(&http_msg->method, DELETE_S)) {
218 : listenUsersDelete();
219 0 : } else {
220 : rejectConnection(NOT_IMPLEMENTED);
221 : }
222 :
223 : }
224 1 :
225 1 : void RequestHandler::listenInterestRequest() {
226 1 : LOGG(DEBUG) << "Listening Interest request";
227 0 : if (! is_equal(&http_msg->method, GET_S)) {
228 : sendHttpLine(NOT_IMPLEMENTED);
229 : return;
230 1 : }
231 0 :
232 : if (! login()) {
233 : return;
234 1 : }
235 :
236 1 : LOGG(DEBUG) << GET_S;
237 1 : char id_interest[BUFFER_SMALL_SIZE];
238 0 : int parsed = mg_get_http_var(&http_msg->query_string, QUERY_STRING_RESOURCE_ID, id_interest, sizeof(id_interest));
239 0 : if (parsed <= 0 ) {
240 : sendHttpLine(BAD_REQUEST);
241 1 : return;
242 1 : }
243 1 : std::string interest_photo;
244 1 : LOGG(DEBUG) << "searching photo of " << id_interest;
245 : if (msgHandler->getInterestPhoto(interest_photo, std::string(id_interest))){
246 0 : sendHttpReply(interest_photo, CONTENT_TYPE_HEADER_PLAIN, STATUS_OK);
247 : }else{
248 1 : this->sendHttpLine(BAD_REQUEST);
249 : }
250 : LOGG(DEBUG) << "Searched for photo: "<< interest_photo;
251 4 : }
252 4 :
253 4 : void RequestHandler::listenChatRequest() {
254 4 : LOGG(DEBUG) << "Listening chat request";
255 : if (! login()) {
256 0 : return;
257 4 : }
258 2 :
259 2 : if ( is_equal(&http_msg->method, GET_S)) {
260 2 : this->listenChatGet();
261 0 : }else if (is_equal(&http_msg->method, POST_S)){
262 0 : this->listenChatPost();
263 : }else{
264 : sendHttpLine(NOT_IMPLEMENTED);
265 : }
266 0 :
267 1 : }
268 1 :
269 0 : void RequestHandler::listenPhotoGet() {
270 1 : LOGG(DEBUG) << GET_S;
271 1 : char username[BUFFER_SMALL_SIZE];
272 0 : int parsed = mg_get_http_var(&http_msg->query_string, QUERY_STRING_RESOURCE_ID, username, sizeof(username));
273 1 : if (parsed <= 0 ) {
274 0 : sendHttpLine(BAD_REQUEST);
275 1 : return;
276 1 : }
277 0 : std::string photo_64;
278 0 : if (!msgHandler->getPhoto(std::string(username), photo_64)){
279 1 : sendHttpLine(BAD_REQUEST);
280 1 : }else{
281 : sendHttpReply(photo_64, CONTENT_TYPE_HEADER_PLAIN, STATUS_OK);
282 : }
283 0 :
284 1 : }
285 1 :
286 1 : void RequestHandler::listenPhotoPost() {
287 1 : LOGG(DEBUG) << POST_S;
288 1 : std::string photo_64(http_msg->body.p, http_msg->body.len);
289 1 : bool posted = msgHandler->postPhoto(photo_64);
290 1 : int status = (posted) ? STATUS_OK: BAD_REQUEST;
291 0 : sendHttpLine(status);
292 2 : }
293 2 :
294 4 : void RequestHandler::listenPhotoRequest() {
295 0 : LOGG(DEBUG) << "Listening photo request";
296 2 : if (! login()) { return; }
297 1 :
298 1 : if (is_equal(&http_msg->method, GET_S)) {
299 1 : listenPhotoGet();
300 0 : } else if (is_equal(&http_msg->method, POST_S)) {
301 0 : listenPhotoPost();
302 : } else {
303 : sendHttpLine(NOT_IMPLEMENTED);
304 0 : }
305 2 : }
306 2 :
307 4 : void RequestHandler::listenChatNewRequest(){
308 0 : LOGG(DEBUG) << "Listening new chat request";
309 2 : if (! login()) { return; }
310 2 :
311 0 : if (is_equal(&http_msg->method, GET_S)) {
312 0 : this->listenNewChatGet();
313 : }else{
314 : sendHttpLine(NOT_IMPLEMENTED);
315 : }
316 0 :
317 4 : }
318 4 :
319 8 : void RequestHandler::listenMatchesRequest(){
320 0 : LOGG(DEBUG)<< "Listening matches request";
321 4 : if (! login()) {return;}
322 2 :
323 2 : if (is_equal(&http_msg->method, GET_S)) {
324 2 : this->listenMatchesGet();
325 0 : } else if (is_equal(&http_msg->method, POST_S)) {
326 0 : this->listenMatchesPost();
327 : } else{
328 : sendHttpLine(NOT_IMPLEMENTED);
329 : }
330 0 :
331 2 : }
332 2 :
333 : void RequestHandler::listenChatGet(){
334 0 : LOGG(DEBUG)<< GET_S;
335 2 :
336 0 : char friend_name[BUFFER_SMALL_SIZE];
337 2 : std::string reply;
338 1 :
339 1 : if (mg_get_http_var(&http_msg->query_string, QUERY_STRING_RESOURCE_ID, friend_name, sizeof(friend_name)) >= 0) {
340 1 : string chatHistory;
341 1 : msgHandler->getChat(string(friend_name), chatHistory);
342 0 : LOGG(INFO) << "RETURNING CHAT HISTORY: " << chatHistory;
343 1 : reply = chatHistory;
344 2 : } else {
345 1 : string matchesUserData;
346 : string matchesUserNames;
347 2 : msgHandler->getMatches(matchesUserNames);
348 2 :
349 3 : istringstream f(matchesUserNames);
350 1 : string matchUserName;
351 1 : while (std::getline(f, matchUserName)) {
352 1 : string matchUserData;
353 1 : msgHandler->getUser(matchUserName, matchUserData);
354 2 : matchesUserData.append(matchUserData + "\n");
355 0 : }
356 2 : reply = matchesUserData;
357 2 : }
358 : sendHttpReply(reply, CONTENT_TYPE_HEADER_CSV, STATUS_OK);
359 2 : }
360 2 :
361 0 : void RequestHandler::listenChatPost(){
362 0 : LOGG(DEBUG)<< POST_S;
363 2 :
364 2 : char receiverUserName[BUFFER_SMALL_SIZE], message[BUFFER_MSG_SIZE];
365 0 : int parsed = mg_get_http_var(&http_msg->body, BODY_USER_ID, receiverUserName, sizeof(receiverUserName));
366 2 : int parsed_msg = mg_get_http_var(&http_msg->body, BODY_MSG, message, sizeof(message));
367 0 :
368 0 : if ( !parsed || !parsed_msg){
369 2 : LOGG(WARNING) << "BAD CHAT POST REQUEST. ";
370 : sendHttpLine(BAD_REQUEST);
371 2 : return;
372 2 : }
373 2 : bool posted = msgHandler->postChatMsg(receiverUserName, message);
374 : int status = (posted) ? STATUS_OK: BAD_REQUEST;
375 : sendHttpLine(status);
376 2 : }
377 2 :
378 2 : void RequestHandler::listenMatchesGet(){
379 2 : LOGG(DEBUG)<< GET_S;
380 2 : string newMatches;
381 2 : bool result_ok = msgHandler->getNewMatches(newMatches);
382 0 : if(result_ok){
383 0 : sendHttpReply(newMatches, CONTENT_TYPE_HEADER_CSV, STATUS_OK);
384 2 : }else{
385 2 : sendHttpLine(BAD_REQUEST);
386 0 : }
387 2 : }
388 2 :
389 : void RequestHandler::listenMatchesPost(){
390 0 : LOGG(DEBUG)<< POST_S;
391 0 :
392 : char friend_name[BUFFER_SMALL_SIZE];
393 2 : char reaction[10];
394 2 :
395 : int parsed = mg_get_http_var(&http_msg->body, BODY_USER_ID, friend_name, sizeof(friend_name));
396 2 : int parsed_like = mg_get_http_var(&http_msg->body, BODY_LIKE, reaction, sizeof(reaction));
397 0 :
398 2 : if ( !parsed || !parsed_like){
399 0 : sendHttpLine(BAD_REQUEST);
400 : return;
401 2 : }
402 2 :
403 8 : bool posted = msgHandler->postInteraction(friend_name, reaction);
404 : int status = (posted) ? STATUS_OK: BAD_REQUEST;
405 : sendHttpLine(status);
406 2 : }
407 2 :
408 : void RequestHandler::listenNewChatGet(){
409 2 : LOGG(DEBUG)<< GET_S;
410 :
411 : string newMessages;
412 2 : char friend_name[BUFFER_SMALL_SIZE];
413 :
414 2 : int parsed = mg_get_http_var(&http_msg->query_string, QUERY_STRING_RESOURCE_ID, friend_name, sizeof(friend_name));
415 0 :
416 0 : if ( !parsed){
417 2 : LOGG(WARNING) << "BAD GET NEW MESSAGES REQUEST. ";
418 : sendHttpLine(BAD_REQUEST);
419 : return;
420 2 : }
421 2 :
422 2 : bool result_ok = msgHandler->getNewMessages(friend_name, newMessages);
423 2 : if(result_ok){
424 : LOGG(INFO) << "RETURNING NEW MESSAGES: " << newMessages;
425 0 : sendHttpReply(newMessages, CONTENT_TYPE_HEADER_CSV, STATUS_OK);
426 0 : }else{
427 2 : LOGG(WARNING) << "BAD GET NEW MESSAGES REQUEST. ";
428 9 : sendHttpLine(BAD_REQUEST);
429 : }
430 : }
|