LCOV - code coverage report
Current view: top level - Servidor - RequestHandler.cpp (source / functions) Hit Total Coverage
Test: coverage_merged.info Lines: 230 307 74.9 %
Date: 2016-07-11 17:43:33 Functions: 29 30 96.7 %

          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             : }

Generated by: LCOV version 1.12-4-g04a3c0e