Exemplo n.º 1
0
void* doNetWork(struct threadData* td) {
    /*Response Variables*/
    struct http_request request;
    int bytesSent;
    int sendResponse;
    int controller;
    int status;
    char * response;
    /* Request variables */
    int readAmount;
    int totalRead;
    int flags; 
    int j,k;
    int contentLength;
    int contentLengthRecieved;
    int contentLengthPosition;
    char * tempBuff;
    char * raw_message;
    char contentLengthBuff[100];
    bytesSent = 0;
    sendResponse =0;

    response = malloc(sizeof(char)*STARTING_RESPONSE_SIZE);
    if(response == NULL){
        NETWORK_LOG_LEVEL_1("Fatal: Failed to allocate memory for response");
        response = "{}";
        status = 500;
        goto internal_err;
    }
    memset(response,0,sizeof(char)*STARTING_RESPONSE_SIZE);

    raw_message = malloc(1+sizeof(char)*BUFSIZ); /* Just enough space for the first read, to determine content length */
    if(raw_message == NULL){
        /* Internal Problem! */
        NETWORK_LOG_LEVEL_1("Fatal: Failed to allocate memory for first-read temporary buffer");
        response[0]='{'; response[1]='}'; response[2]='\0';
        status = 500;
        goto internal_err;
    }
    memset(raw_message, 0,1+sizeof(char)*BUFSIZ);
    tempBuff = NULL; /* temp buff will be used to realloc */
        

    /* Accept and read incoming request  */
    if(td->clientfd == -1)
        goto bad_client_id;

    readAmount=totalRead=contentLengthRecieved =contentLengthPosition= contentLength = 0;

    NETWORK_LOG_LEVEL_2_NUM("Accepted Client Request on File Descriptor ", td->clientfd);
    readAmount = 1; /* Sentinal */
    flags = fcntl(td->clientfd, F_GETFL, 0);
    fcntl(td->clientfd, F_SETFL, flags | O_NONBLOCK);
    contentLength = -1; /* Sentinal */
    while(readAmount != 0){
        readAmount = read(td->clientfd,raw_message+totalRead,BUFSIZ);    
        if(readAmount == -1){
            if(errno == EAGAIN && totalRead == 0)
                continue;
            else if(contentLengthRecieved != contentLength)
                continue;
            else
                readAmount = 0;
        }else{
            NETWORK_LOG_LEVEL_2_NUM("Reading Data From Socket", td->clientfd);
            /* Since we're here that means we have at least 
             * the beginning of the request itself but we're
             * waiting for more. So determine the content-length
             * and then figure out if we have all of it or not
            */
            contentLengthPosition = strnstr("Content-Length", raw_message, BUFSIZ);                    
            if(contentLengthPosition == -1){
                /* You didn't send us a content length, carry on! 
                 * so no data, so just url, so good bye.
                */
                contentLengthRecieved = contentLength = readAmount = 0;
            }else{
                if(totalRead == 0){                            
                    /* Convert the content length 
                    * reuse this connections buffer.
                    */
                    bzero(contentLengthBuff, sizeof contentLengthBuff); /* Only what we need */
                    contentLength = contentLengthPosition;
                    contentLength+=strlen("Content-Length: "); /* Skip the text */
                     
                    for(k=0; k < (int)sizeof(contentLengthBuff) && *(raw_message + contentLength) != '\0' && *(raw_message + contentLength) != '\r'; ++k, contentLength++)
                        contentLengthBuff[k] = *(raw_message + contentLength);
                    contentLengthBuff[k] = '\0';
                    contentLength = atoi(contentLengthBuff);                            
                    
                    /* Malloc for the content Length 
                     * j is the position of the data, all things prior 
                     * need to be conserved as well
                    */
                    if( contentLength > 0 ){
                        tempBuff = malloc(5+ strlen(raw_message) + contentLength + BUFSIZ);
                        if(tempBuff == NULL){
                            free(raw_message);
                            NETWORK_LOG_LEVEL_1("Could not reallocate memory during request data acquisition");
                            goto internal_err;
                        }else{
                            memset(tempBuff, 0, 5+ strlen(raw_message) + contentLength + BUFSIZ);
                            strcpy(tempBuff, raw_message);
                            swapCharPtr(&tempBuff, &raw_message);
                            free(tempBuff);
                        }
                    }
                }

                /* We've said a content length now, and we need 
                * determine how much we've actually recieved
                * no need to store it, just count it with j. 
                */
                j = strnstr("\r\n\r\n", raw_message, BUFSIZ);
                if(j != -1){
                    j+=4; /* skip newlines */
                    j+= contentLengthRecieved;
                    for(contentLengthRecieved = (contentLengthRecieved==0 ? 0 : contentLengthRecieved); (unsigned int)j < strlen(raw_message); ++j, ++contentLengthRecieved)
                        ;                            
                }else{   
                    /* Could not find content...*/
                    if(contentLength <= 0)
                        readAmount = 0; /* Get out */
                    else
                        contentLengthRecieved = 0; /* Haven't received it yet */
                }
            }
            /* Important to do this last as the totalRead is what
             * determines if we malloc for content or not
            */
            
            fprintf(stderr, "Recieving Data From Socket %d: %d/%d\n", td->clientfd ,contentLengthRecieved, contentLength);    
            
            totalRead += readAmount;                
            if(contentLength == contentLengthRecieved) 
                readAmount = 0;      
        }
    }
    if(totalRead > THREAD_DATA_MAX_SIZE)
        NETWORK_LOG_LEVEL_1("Warning: Total Read Greater than Buffer Length");

    /*Blank JSON response for no control*/
    *(response+1)='{'; *(response+1)='}'; *(response+2)='\0';
    status = 200;
    parseRequest(&request, raw_message);

    /* Pass the request off to a handler */
    controller = determineController(request.url);
    /* Determine method and call. */
    switch(controller){
        case HEARTBEAT_CONTROLLER :
            NETWORK_LOG_LEVEL_2("Heartbeat Controller Processing Request.");
            status = heartbeat_controller(response, STARTING_RESPONSE_SIZE);
            break;
        case COMMENTS_CONTROLLER :
            NETWORK_LOG_LEVEL_2("Comments Controller Processing Request.");
            status = comment_controller(&request, &response,  STARTING_RESPONSE_SIZE);
            break;
        case HEATMAP_CONTROLLER :
            NETWORK_LOG_LEVEL_2("Heatmap Controller Processing Request.");
            status = heatmap_controller(&request, &response,  STARTING_RESPONSE_SIZE);
            break;
        case MARKER_CONTROLLER :
            NETWORK_LOG_LEVEL_2("Marker Controller Processing Request.");
            status = marker_controller(&request, &response,  STARTING_RESPONSE_SIZE);
            break;
        case REPORT_CONTROLLER :
            NETWORK_LOG_LEVEL_2("Report Controller Processing Request.");
            status = report_controller(&request, &response,  STARTING_RESPONSE_SIZE);
            break;
        default:
            NETWORK_LOG_LEVEL_2("Unknown URL. Refusing to process request.");
            /* We have no clue what the client is talking about with their url */
            status = 404;
            break;
    }
    

    /* Log and clean up. */
    NETWORK_LOG_LEVEL_1("Incoming Request:")
    NETWORK_LOG_LEVEL_1(request.url);
    if(request.contentLength > 0){
        NETWORK_LOG_LEVEL_2("Incoming Data:");
        NETWORK_LOG_LEVEL_2_NUM("Content length of Data: ", request.contentLength);
        NETWORK_LOG_LEVEL_2(request.data);
    }
    if(request.contentLength > 0)
        free(request.data);

    internal_err:
    td->msg = malloc(strlen(response) + 256);
    if(td->msg == NULL){
        NETWORK_LOG_LEVEL_2_NUM("Fatal: Not enough memory for HTTP response", (int)strlen(response)+256);
        free(raw_message);
        free(response);
        close(td->clientfd);
        return NULL;
    }
    memset(td->msg,0,strlen(response)+256);
    createResponse(response,td->msg,status);
    td->msg[strlen(td->msg)] = '\0';\



    bad_client_id: 
    if(td->clientfd != -1){
        do{
            sendResponse = send(td->clientfd,(td->msg)+bytesSent,strlen(td->msg)-bytesSent,0);  
            if(sendResponse == -1){
                NETWORK_LOG_LEVEL_2(strerror(errno));    
            }else{
                bytesSent += sendResponse;
            }
            NETWORK_LOG_LEVEL_1("Sending Response:");
            NETWORK_LOG_LEVEL_1( ( td->msg )+bytesSent  ); 
            NETWORK_LOG_LEVEL_2_NUM("Bytes sent to client: ", bytesSent);
            
        } while(bytesSent < (int)strlen(td->msg) -1 );
        close(td->clientfd);
    }else{
        NETWORK_LOG_LEVEL_2("File Descriptor invalid. If shutting down there is no problem.");
        NETWORK_LOG_LEVEL_2("If not shutting down, there was an issue sending data to the client.");
    }
    free(td->msg);
    free(raw_message);
    free(response);
    return NULL;
}
Exemplo n.º 2
0
// VFALCO ARGH! returning a single std::string for the entire response?
std::string
ServerHandlerImp::processRequest (std::string const& request,
    beast::IP::Endpoint const& remoteIPAddress)
{
    Json::Value jvRequest;
    {
        Json::Reader reader;
        if ((request.size () > 1000000) ||
            ! reader.parse (request, jvRequest) ||
            jvRequest.isNull () ||
            ! jvRequest.isObject ())
        {
            return createResponse (400, "Unable to parse request");
        }
    }

    auto const role = getConfig ().getAdminRole (jvRequest, remoteIPAddress);

    Resource::Consumer usage;

    if (role == Config::ADMIN)
        usage = m_resourceManager.newAdminEndpoint (remoteIPAddress.to_string());
    else
        usage = m_resourceManager.newInboundEndpoint(remoteIPAddress);

    if (usage.disconnect ())
        return createResponse (503, "Server is overloaded");

    // Parse id now so errors from here on will have the id
    //
    // VFALCO NOTE Except that "id" isn't included in the following errors.
    //
    Json::Value const id = jvRequest ["id"];

    Json::Value const method = jvRequest ["method"];

    if (method.isNull ())
        return createResponse (400, "Null method");

    if (! method.isString ())
        return createResponse (400, "method is not string");

    std::string strMethod = method.asString ();
    if (strMethod.empty())
        return createResponse (400, "method is empty");

    // Parse params
    Json::Value params = jvRequest ["params"];

    if (params.isNull ())
        params = Json::Value (Json::arrayValue);

    else if (!params.isArray ())
        return HTTPReply (400, "params unparseable");

    // VFALCO TODO Shouldn't we handle this earlier?
    //
    if (role == Config::FORBID)
    {
        // VFALCO TODO Needs implementing
        // FIXME Needs implementing
        // XXX This needs rate limiting to prevent brute forcing password.
        return HTTPReply (403, "Forbidden");
    }


    std::string response;
    RPCHandler rpcHandler (m_networkOPs);
    Resource::Charge loadType = Resource::feeReferenceRPC;

    m_journal.debug << "Query: " << strMethod << params;

    Json::Value const result (rpcHandler.doRpcCommand (
        strMethod, params, role, loadType));
    m_journal.debug << "Reply: " << result;

    usage.charge (loadType);

    response = JSONRPCReply (result, Json::Value (), id);

    return createResponse (200, response);
}
Exemplo n.º 3
0
void ServiceTask::run()
{
	//logger << dlib << endl;
	string ip = "invalid session";
	string alldatlg = "\ngot fd from parent";
	SSL *ssl=NULL;
	BIO *sbio=NULL;
	BIO *io=NULL,*ssl_bio=NULL;
	try
	{
		int cntlen = 0;
		char buf[MAXBUFLENM];
		strVec results;
		stringstream ss;
		string temp;
		//int bytes = -1;
		if(isSSLEnabled)
		{
			sbio=BIO_new_socket(fd,BIO_NOCLOSE);
			ssl=SSL_new(ctx);
			SSL_set_bio(ssl,sbio,sbio);

			io=BIO_new(BIO_f_buffer());
			ssl_bio=BIO_new(BIO_f_ssl());
			BIO_set_ssl(ssl_bio,ssl,BIO_CLOSE);
			BIO_push(io,ssl_bio);

			int r = SSL_accept(ssl);
			cout << r << endl;
			int bser = SSL_get_error(ssl,r);
			cout << bser << endl;
			if(r<=0)
			{
				sslHandler.error_occurred((char*)"SSL accept error",fd,ssl);
				return;
			}


			int er=-1;
			bool flag = true;
			while(flag)
			{
				er = BIO_gets(io,buf,BUFSIZZ-1);
				cout << er << endl;
				int bser = SSL_get_error(ssl,er);
				cout << bser << endl;
				switch(bser)
				{
					case SSL_ERROR_WANT_READ:
					{
						logger << "more to read error" << endl;
						break;
					}
					case SSL_ERROR_WANT_WRITE:
					{
						logger << "more to write error" << endl;
						break;
					}
					case SSL_ERROR_NONE:
					{
						break;
					}
					case SSL_ERROR_ZERO_RETURN:
					{
						sslHandler.error_occurred((char*)"SSL error problem",fd,ssl);
						if(io!=NULL)BIO_free(io);
						return;
					}
					default:
					{
						sslHandler.error_occurred((char*)"SSL read problem",fd,ssl);
						if(io!=NULL)BIO_free(io);
						return;
					}
				}
				ss << buf;
				//logger <<buf <<endl;
				if(!strcmp(buf,"\r\n") || !strcmp(buf,"\n"))
					break;
				string temp(buf);
				if(temp=="")continue;
				temp = temp.substr(0,temp.length()-1);
				results.push_back(temp);
				//logger << temp <<endl;
				if(temp.find("Content-Length:")!=string::npos)
				{
					std::string cntle = temp.substr(temp.find(": ")+2);
					cntle = cntle.substr(0,cntle.length()-1);
					//logger << "contne-length="<<cntle <<endl;
					try
					{
						cntlen = CastUtil::lexical_cast<int>(cntle);
					}
					catch(const char* ex)
					{
						logger << "bad lexical cast" <<endl;
					}
				}
				memset(&buf[0], 0, sizeof(buf));
			}
		}
		else
		{
			int er=-1;
			bool flag = true;
			sbio=BIO_new_socket(fd,BIO_CLOSE);
			io=BIO_new(BIO_f_buffer());
			BIO_push(io,sbio);
			logger << "into run method" << endl;
			while(flag)
			{
				er = BIO_gets(io,buf,BUFSIZZ-1);
				if(er==0)
				{
					close(fd);
					logger << "\nsocket closed before being serviced" <<flush;
					return;
				}
				ss << buf;
				if(!strcmp(buf,"\r\n") || !strcmp(buf,"\n") || er<0)
					break;
				string temp(buf);
				temp = temp.substr(0,temp.length()-1);
				results.push_back(temp);
				//logger << temp <<endl;
				if(temp.find("Content-Length:")!=string::npos)
				{
					std::string cntle = temp.substr(temp.find(": ")+2);
					cntle = cntle.substr(0,cntle.length()-1);
					//logger << "contne-length="<<cntle <<endl;
					try
					{
						cntlen = CastUtil::lexical_cast<int>(cntle);
					}
					catch(const char* ex)
					{
						logger << "bad lexical cast" <<endl;
					}
				}
				memset(&buf[0], 0, sizeof(buf));
			}
		}

		ss.clear();
		if(isSSLEnabled && cntlen>0)
		{
			int er=-1;
			if(cntlen>0)
			{
				//logger << "reading conetnt " << cntlen << endl;
				er = BIO_read(io,buf,cntlen);
				switch(SSL_get_error(ssl,er))
				{
					case SSL_ERROR_NONE:
						cntlen -= er;
						break;
					case SSL_ERROR_ZERO_RETURN:
					{
						sslHandler.error_occurred((char*)"SSL error problem",fd,ssl);
						if(io!=NULL)BIO_free(io);
						return;
					}
					default:
					{
						sslHandler.error_occurred((char*)"SSL read problem",fd,ssl);
						if(io!=NULL)BIO_free(io);
						return;
					}
				}
				string temp(buf);
				results.push_back("\r");
				results.push_back(temp);
				//logger <<buf <<endl;
				memset(&buf[0], 0, sizeof(buf));
			}
		}
		else if(cntlen>0)
		{
			int er=-1;
			if(cntlen>0)
			{
				//logger << "reading conetnt " << cntlen << endl;
				er = BIO_read(io,buf,cntlen);
				if(er==0)
				{
					close(fd);
					logger << "\nsocket closed before being serviced" <<flush;
					return;
				}
				else if(er>0)
				{
					string temp(buf);
					results.push_back("\r");
					results.push_back(temp);
					//logger << temp <<endl;
					memset(&buf[0], 0, sizeof(buf));
				}
			}
		}
		alldatlg += "--read data";
		map<string,string> params1 = *params;
		string webpath = serverRootDirectory + "web/";
		HttpRequest* req= new HttpRequest(results,webpath);
		//logger << req->toString() << endl;

		if(req->getFile()=="")
		{
			logger << req->getFile() << endl;
			req->setFile("index.html");
		}
		if(req->hasCookie())
		{
			logger << "has the session id" << endl;
			if(!configData.sessatserv)
				req->getSession()->setSessionAttributes(req->getCookieInfo());
			else
			{
				string id = req->getCookieInfoAttribute("FFEADID");
				logger << id << endl;
				map<string,string> values = readFromSharedMemeory(id);
				req->getSession()->setSessionAttributes(values);
			}
		}

		if(configData.cntMap[req->getCntxt_name()]!="true")
		{
			req->setCntxt_name("default");
			req->setCntxt_root(webpath+"default");
			req->setUrl(webpath+"default"+req->getActUrl());
		}
		//logger << req->getCntxt_name() << req->getCntxt_root() << req->getUrl() << endl;

		if(configData.appMap[req->getCntxt_name()]!="false")
		{
			if(dlib == NULL)
			{
				cerr << dlerror() << endl;
				exit(-1);
			}
			string meth1 = (req->getCntxt_name()+"checkRules");
			string path1;
			void *mkr1 = dlsym(dlib, meth1.c_str());
			if(mkr1!=NULL)
			{
				typedef string (*DCPPtr1) (string,HttpSession);
				DCPPtr1 f =  (DCPPtr1)mkr1;
				path1 = f(req->getUrl(),*(req->getSession()));
				//logger << path1 << flush;
				if(path1=="FAILED")
				{
					req->setUrl("");
				}
				else if(path1!="" && path1!=req->getUrl())
				{
					req->setUrl(path1);
				}
			}
		}

		HttpResponse res;
		string ext = getFileExtension(req->getUrl());
		vector<unsigned char> test;
		string content;
		string claz;
		bool isoAuthRes = false;
		long sessionTimeoutVar = configData.sessionTimeout;
		bool isContrl = securityHandler.handle(configData.ip_address, req, res, configData.securityObjectMap, sessionTimeoutVar, dlib, configData.cntMap);

		filterHandler.handleIn(req, res, configData.filterMap, dlib, ext);

		if(!isContrl)
		{
			isContrl = authHandler.handle(configData.autMap, configData.autpattMap, req, res, configData.filterMap, dlib, ext);
		}
		string pthwofile = req->getCntxt_name()+req->getActUrl();
		if(req->getCntxt_name()!="default" && configData.cntMap[req->getCntxt_name()]=="true")
		{
			pthwofile = req->getActUrl();
		}
		if(!isContrl)
		{
			isContrl = controllerHandler.handle(req, res, configData.urlpattMap, configData.mappattMap, dlib, ext,
					configData.rstCntMap, configData.mapMap, configData.urlMap, pthwofile);
		}

		/*After going through the controller the response might be blank, just set the HTTP version*/
		res.setHttpVersion(req->getHttpVersion());
		//logger << req->toString() << endl;
		if(req->getMethod()!="TRACE")
		{
			if(isContrl)
			{

			}
			else if(ext==".form")
			{
				formHandler.handle(req, res, configData.formMap, dlib);
			}
			else if((req->getContent_type().find("application/soap+xml")!=string::npos || req->getContent_type().find("text/xml")!=string::npos)
					&& (req->getContent().find("<soap:Envelope")!=string::npos || req->getContent().find("<soapenv:Envelope")!=string::npos)
					&& configData.wsdlmap[req->getFile()]==req->getCntxt_name())
			{
				soapHandler.handle(req, res, dlib, configData.props[".xml"]);
			}
			else
			{
				bool cntrlit = scriptHandler.handle(req, res, configData.handoffs, dlib, ext, configData.props);
				logger << "html page requested" <<endl;
				if(cntrlit)
				{

				}
				else
				{
					cntrlit = extHandler.handle(req, res, dlib, configData.resourcePath, configData.tmplMap, configData.vwMap, ext, configData.props);
				}
				if(!cntrlit && ext==".fview")
				{
					content = fviewHandler.handle(req, res, configData.fviewmap);
				}
				else
				{
					if(res.getContent_str()=="")
						content = getContentStr(req->getUrl(),configData.lprops[req->getDefaultLocale()],ext);
					else
						content = res.getContent_str();
				}
				if(content.length()==0)
				{
					res.setStatusCode("404");
					res.setStatusMsg("Not Found");
					//res.setContent_len(CastUtil::lexical_cast<string>(0));
				}
				else
				{
					res.setStatusCode("200");
					res.setStatusMsg("OK");
					if(res.getContent_type()=="")res.setContent_type(configData.props[ext]);
					res.setContent_str(content);
					//res.setContent_len(CastUtil::lexical_cast<string>(content.length()));
					//sess.setAttribute("CURR",req->getUrl());
				}
			}

			filterHandler.handleOut(req, res, configData.filterMap, dlib, ext);
		}

		alldatlg += "--processed data";
		string h1;
		bool sessionchanged = !req->hasCookie();
		sessionchanged |= req->getSession()->isDirty();
		if(req->getConnection()!="")
			res.setConnection("close");
		createResponse(res,sessionchanged,req->getSession()->getSessionAttributes(),req->getCookieInfoAttribute("FFEADID"), sessionTimeoutVar, configData.sessatserv);
		//Head should behave exactly as Get but there should be no entity body
		if(req->getMethod()=="HEAD")
		{
			h1 = res.generateHeadResponse();
		}
		else if(req->getMethod()=="OPTIONS")
		{
			h1 = res.generateOptionsResponse();
		}
		else if(req->getMethod()=="TRACE")
		{
			h1 = res.generateTraceResponse(req);
		}
		else
		{
			h1 = res.generateResponse();
		}
		//logger << h1 << endl;
		if(isSSLEnabled)
		{
			int r;
			/* Now perform renegotiation if requested */
			if(configData.client_auth==CLIENT_AUTH_REHANDSHAKE){
			  SSL_set_verify(ssl,SSL_VERIFY_PEER |
				SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);

			  /* Stop the client from just resuming the
				 un-authenticated session */
			  SSL_set_session_id_context(ssl,
				(const unsigned char*)&SSLHandler::s_server_auth_session_id_context,
				sizeof(SSLHandler::s_server_auth_session_id_context));

			  if(SSL_renegotiate(ssl)<=0)
			  {
				  sslHandler.error_occurred((char*)"SSL renegotiation error",fd,ssl);
				  if(io!=NULL)BIO_free(io);
				  return;
			  }
			  if(SSL_do_handshake(ssl)<=0)
			  {
				  sslHandler.error_occurred((char*)"SSL renegotiation error",fd,ssl);
				  if(io!=NULL)BIO_free(io);
				  return;
			  }
			  ssl->state=SSL_ST_ACCEPT;
			  if(SSL_do_handshake(ssl)<=0)
			  {
				  sslHandler.error_occurred((char*)"SSL renegotiation error",fd,ssl);
				  if(io!=NULL)BIO_free(io);
				  return;
			  }
			}
			if((r=BIO_puts(io,h1.c_str()))<=0)
			{
				  sslHandler.error_occurred((char*)"send failed",fd,ssl);
				  if(io!=NULL)BIO_free(io);
				  return;
			}
			if((r=BIO_flush(io))<0)
			{
				  sslHandler.error_occurred((char*)"Error flushing BIO",fd,ssl);
				  if(io!=NULL)BIO_free(io);
				  return;
			}
			sslHandler.closeSSL(fd,ssl,io);
		}
		else
		{
			int size;
			if ((size=send(fd,&h1[0] , h1.length(), 0)) == -1)
				logger << "send failed" << flush;
			else if(size==0)
			{
				close(fd);
				memset(&buf[0], 0, sizeof(buf));
				logger << "socket closed for writing" << flush;
				return;
			}

			if(io!=NULL)BIO_free_all(io);
		}
		close(fd);
		memset(&buf[0], 0, sizeof(buf));
		ss.clear();

		//Logger::info("got new connection to process\n"+req->getFile()+" :: " + res.getStatusCode() + "\n"+req->getCntxt_name() + "\n"+req->getCntxt_root() + "\n"+req->getUrl());
		delete req;
		logger << alldatlg << "--sent data--DONE" << flush;
		//sessionMap[sessId] = sess;
	}
	catch(...)
	{
		logger << "Standard exception: " << endl;
	}
}
Exemplo n.º 4
0
HttpResponse ServiceTask::apacheRun(HttpRequest* req)
{
	//logger << dlib << endl;
	HttpResponse res;
	string ip;
	string alldatlg = "\ngot fd from parent";
	try
	{
		string webpath = serverRootDirectory + "web/";

		if(req->getFile()=="")
		{
			logger << req->getFile() << endl;
			req->setFile("index.html");
		}
		if(req->hasCookie())
		{
			logger << "has the session id" << endl;
			if(!configData.sessatserv)
				req->getSession()->setSessionAttributes(req->getCookieInfo());
			else
			{
				string id = req->getCookieInfoAttribute("FFEADID");
				logger << id << endl;
				map<string,string> values = readFromSharedMemeory(id);
				req->getSession()->setSessionAttributes(values);
			}
		}

		if(configData.cntMap[req->getCntxt_name()]!="true")
		{
			req->setCntxt_name("default");
			req->setCntxt_root(webpath+"default");
			req->setUrl(webpath+"default"+req->getActUrl());
		}
		//logger << req->getCntxt_name() << req->getCntxt_root() << req->getUrl() << endl;

		if(configData.appMap[req->getCntxt_name()]!="false")
		{
			if(dlib == NULL)
			{
				cerr << dlerror() << endl;
				exit(-1);
			}
			string meth1 = (req->getCntxt_name()+"checkRules");
			string path1;
			void *mkr1 = dlsym(dlib, meth1.c_str());
			if(mkr1!=NULL)
			{
				typedef string (*DCPPtr1) (string,HttpSession);
				DCPPtr1 f =  (DCPPtr1)mkr1;
				path1 = f(req->getUrl(),*(req->getSession()));
				//logger << path1 << flush;
				if(path1=="FAILED")
				{
					req->setUrl("");
				}
				else if(path1!="" && path1!=req->getUrl())
				{
					req->setUrl(path1);
				}
			}
		}

		string ext = getFileExtension(req->getUrl());
		vector<unsigned char> test;
		string content;
		string claz;
		bool isoAuthRes = false;
		long sessionTimeoutVar = configData.sessionTimeout;
		bool isContrl = securityHandler.handle(configData.ip_address, req, res, configData.securityObjectMap, sessionTimeoutVar, dlib, configData.cntMap);

		filterHandler.handleIn(req, res, configData.filterMap, dlib, ext);

		if(!isContrl)
		{
			isContrl = authHandler.handle(configData.autMap, configData.autpattMap, req, res, configData.filterMap, dlib, ext);
		}
		string pthwofile = req->getCntxt_name()+req->getActUrl();
		if(req->getCntxt_name()!="default" && configData.cntMap[req->getCntxt_name()]=="true")
		{
			pthwofile = req->getActUrl();
		}
		if(!isContrl)
		{
			isContrl = controllerHandler.handle(req, res, configData.urlpattMap, configData.mappattMap, dlib, ext,
					configData.rstCntMap, configData.mapMap, configData.urlMap, pthwofile);
		}

		/*After going through the controller the response might be blank, just set the HTTP version*/
		res.setHttpVersion(req->getHttpVersion());
		//logger << req->toString() << endl;
		if(isContrl)
		{

		}
		else if(ext==".form")
		{
			formHandler.handle(req, res, configData.formMap, dlib);
		}
		else if((req->getContent_type().find("application/soap+xml")!=string::npos || req->getContent_type().find("text/xml")!=string::npos)
				&& (req->getContent().find("<soap:Envelope")!=string::npos || req->getContent().find("<soapenv:Envelope")!=string::npos)
				&& configData.wsdlmap[req->getFile()]==req->getCntxt_name())
		{
			soapHandler.handle(req, res, dlib, configData.props[".xml"]);
		}
		else
		{
			bool cntrlit = scriptHandler.handle(req, res, configData.handoffs, dlib, ext, configData.props);
			logger << "html page requested" <<endl;
			if(cntrlit)
			{

			}
			else
			{
				cntrlit = extHandler.handle(req, res, dlib, configData.resourcePath, configData.tmplMap, configData.vwMap, ext, configData.props);
			}
			if(!cntrlit && ext==".fview")
			{
				content = fviewHandler.handle(req, res, configData.fviewmap);
			}
			else
			{
				if(res.getContent_str()=="")
					content = getContentStr(req->getUrl(),configData.lprops[req->getDefaultLocale()],ext);
				else
					content = res.getContent_str();
			}
			if(content.length()==0)
			{
				res.setStatusCode("404");
				res.setStatusMsg("Not Found");
				//res.setContent_len(CastUtil::lexical_cast<string>(0));
			}
			else
			{
				res.setStatusCode("200");
				res.setStatusMsg("OK");
				if(res.getContent_type()=="")res.setContent_type(configData.props[ext]);
				res.setContent_str(content);
				//res.setContent_len(CastUtil::lexical_cast<string>(content.length()));
				//sess.setAttribute("CURR",req->getUrl());
			}
		}

		filterHandler.handleOut(req, res, configData.filterMap, dlib, ext);

		alldatlg += "--processed data";
		string h1;
		bool sessionchanged = !req->hasCookie();
		sessionchanged |= req->getSession()->isDirty();
		if(req->getConnection()!="")
			res.setConnection("close");
		createResponse(res,sessionchanged,req->getSession()->getSessionAttributes(),req->getCookieInfoAttribute("FFEADID"), sessionTimeoutVar, configData.sessatserv);
		//h1 = res.generateResponse();
		delete req;
		logger << alldatlg << "--sent data--DONE" << flush;
		//sessionMap[sessId] = sess;
	}
	catch(const char* ex)
	{
		logger << ex << endl;
	}
	catch(...)
	{
		logger << "Standard exception: " << endl;
	}
	return res;
}
Exemplo n.º 5
0
void HttpClient::sendRequest(natural contentLength, PostStreamOption pso) {
	try {
		createRequest(urlToOpen,methodToOpen);
		request->setContentLength(contentLength);
		bool use100 = false;
		if (!useHTTP10) {


			switch(pso) {
			case psoDefault:
			case psoAllow100: use100 = connectionReused; break;
			case psoFavour100:
			case psoForce100: use100 = true;break;
			case psoBuffer: request->setContentLength(HttpRequest::calculateLength);break;
			case psoAvoid100NoReuseConn: if (connectionReused) {
											closeConnection();
											createRequest(urlToOpen,methodToOpen);
										};break;
			case psoAvoid100: break;
			}

			if (use100) {
				setHeader(fldExpect,continue100);
			}
		}

		for (HdrMap::Iterator iter = reqHdrMap.getFwIter(); iter.hasItems();) {
			const HdrMap::KeyValue &kv = iter.getNext();
			request->setHeader(kv.key, kv.value);
		}


		request->beginBody();
		createResponse(false);

		if (use100) {
			//flush buffers now
			nstream->flush();
			if (nstream->wait(INetworkResource::waitForInput,10000) != INetworkResource::waitTimeout) {
				response->readHeaders();
				//there can other response, so if we cannot continue, return response to the caller
				if (!response->canContinue()) {
					//check status
					if (status == 417) {//we got precondition failed - no worries, we can repeat the request

						response->skipRemainBody(false);

						return sendRequest(contentLength, psoAvoid100);

					} else {

						loadResponse();
						throw HttpStatusException(THISLOCATION,urlToOpen,status, statusMessage);

					}
				}
			}
		}


	}catch (NetworkException &) {
		if (connectionReused) {
			closeConnection();
			sendRequest(contentLength,pso);
		} else {
			throw;
		}
	}catch (IOException &) {
		if (connectionReused) {
			closeConnection();
			sendRequest(contentLength,pso);
		} else {
			throw;
		}
	}
}
Exemplo n.º 6
0
HttpResponse& HttpClient::sendRequestInternal(ConstStrA url, Method method, SeqFileInput data, const HdrItem* headers, bool wo100) {

	//for HTTP/1.0 we need to buffer request (sad)
	if (useHTTP10) {
		//create buffer
		AutoArray<byte> buffer;
		if (data.hasItems()) {
			do {
				natural pos = buffer.length();
				//reserve buffer
				buffer.resize(pos+4096);
				//read buffer
				natural sz = data.blockRead(buffer.data()+pos,4096,true);
				//adjust buffer size
				buffer.resize(pos+sz);
				//continue until end
			} while (data.hasItems());
		}
		//send request
		return sendRequest(url,method,buffer,headers);
	} else {
		//while reading from the stream, we need to ensure, that server is ready to accept our data
		//so in this case, we will use Expect: 100-continue precondition
		try {
			//create request for url
			HttpRequest &rq = createRequest(url,method);
			//we don't need to use 100-continue if connection was recently opened
			if (!connectionReused) wo100 = true;
			//set content length to infinity - this should switch to chunked
			rq.setContentLength(naturalNull);
			//load headers
			feedHeaders(rq, headers);
			//set Expect: 100-continue
			if (!wo100) rq.setHeader(fldExpect,"100-continue");
			//close headers and start body, but we must wait for response now
			rq.beginBody();
			//so create response (do not read headers)
			HttpResponse& resp = createResponse(false);
			//now wait some time to server's response.
			//because it could ignore our header, we must not wait for infinity time
			if (wo100 || nstream->wait(INetworkResource::waitForInput,10000) != INetworkResource::waitTimeout) {
				//data arrived in time - read headers
				resp.readHeaders();
				//there can other response, so if we cannot continue, return response to the caller
				if (!resp.canContinue()) {
					//check status
					if (resp.getStatus() == 417) //we got precondition failed - no worries, we can repeat the request
						//at least we know, that connection is alive
						return sendRequestInternal(url,method,data,headers,true);
					else {
						//other status is send to the caller
						return resp;
					}
				}
			}

			//until now, request could be repeated anytime for network errors
			//- because keep-alive can be closed by the server anytime during request

			//now we should prevent repeating request when network error happened
			//because we starting reading the stream
			connectionReused = false;

			//create a buffer for data
			CArray<byte, 1024> buffer;
			//open request as stream
			SeqFileOutput dout(&rq);
			//use blockcopy to copy data to the request
			dout.blockCopy(data,buffer,naturalNull);
			//close the output
			rq.closeOutput();
			//now wait for response.
			resp.waitAfterContinue(HttpResponse::readHeadersNow);

			//because we could skip waiting on 100-continue above, we need to receive it now
			//and any other such responses
			while (resp.canContinue()) {
				resp.waitAfterContinue(HttpResponse::readHeadersNow);
			}

			//return other response to the caller
			return resp;
		} catch (const NetworkException &e) {
			if (connectionReused) {
				closeConnection();
				return sendRequest(url, method, data, headers);
			} else {
				throw;
			}
		}
	}
}
Exemplo n.º 7
0
 void PathHandler::handleError (TriagensError const&) {
   _response = createResponse(HttpResponse::SERVER_ERROR);
 }
Exemplo n.º 8
0
    HttpHandler::status_e PathHandler::execute () {
      static string const allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890. +-_=";

      vector<string> names = _request->suffix();
      string name = path;
      string last = "";

      if (names.empty() && ! defaultFile.empty()) {
        string url = _request->requestPath();

        if (! url.empty() && url[url.size() - 1] != '/') {
          url += "/" + defaultFile;
        }

        _response = createResponse(HttpResponse::MOVED_PERMANENTLY);

        _response->setHeader("location", url);
        _response->setContentType("text/html");

        _response->body().appendText("<html><head><title>Moved</title></head><body><h1>Moved</h1><p>This page has moved to <a href=\"");
        _response->body().appendText(url);
        _response->body().appendText(">");
        _response->body().appendText(url);
        _response->body().appendText("</a>.</p></body></html>");

        return HANDLER_DONE;
      }

      for (vector<string>::const_iterator j = names.begin();  j != names.end();  ++j) {
        string const& next = *j;

        if (next == ".") {
          LOGGER_WARNING << "file '" << name << "' contains '.'";

          _response = createResponse(HttpResponse::FORBIDDEN);
          _response->body().appendText("path contains '.'");
          return HANDLER_DONE;
        }

        if (next == "..") {
          LOGGER_WARNING << "file '" << name << "' contains '..'";

          _response = createResponse(HttpResponse::FORBIDDEN);
          _response->body().appendText("path contains '..'");
          return HANDLER_DONE;
        }

        string::size_type sc = next.find_first_not_of(allowed);

        if (sc != string::npos) {
          LOGGER_WARNING << "file '" << name << "' contains illegal character";

          _response = createResponse(HttpResponse::FORBIDDEN);
          _response->body().appendText("path contains illegal character '" + string(1, next[sc]) + "'");
          return HANDLER_DONE;
        }

        if (! path.empty()) {
          if (! FileUtils::isDirectory(path)) {
            LOGGER_WARNING << "file '" << name << "' not found";

            _response = createResponse(HttpResponse::NOT_FOUND);
            _response->body().appendText("file not found");
            return HANDLER_DONE;
          }
        }

        name += "/" + next;
        last = next;

        if (! allowSymbolicLink && FileUtils::isSymbolicLink(name)) {
          LOGGER_WARNING << "file '" << name << "' contains symbolic link";

          _response = createResponse(HttpResponse::FORBIDDEN);
          _response->body().appendText("symbolic links are not allowed");
          return HANDLER_DONE;
        }
      }

      if (! FileUtils::isRegularFile(name)) {
        LOGGER_WARNING << "file '" << name << "' not found";

        _response = createResponse(HttpResponse::NOT_FOUND);
        _response->body().appendText("file not found");
        return HANDLER_DONE;
      }

      _response = createResponse(HttpResponse::OK);

      try {
        FileUtils::slurp(name, _response->body());
      }
      catch (...) {
        LOGGER_WARNING << "file '" << name << "' not readable";

        _response = createResponse(HttpResponse::NOT_FOUND);
        _response->body().appendText("file not readable");
        return HANDLER_DONE;
      }

      string::size_type d = last.find_last_of('.');

      if (d != string::npos) {
        string suffix = last.substr(d);

        if (suffix == ".jpg") {
          _response->setContentType("image/jpg");
        }
        else if (suffix == ".js") {
          _response->setContentType("text/javascript");
        }
        else if (suffix == ".gif") {
          _response->setContentType("image/gif");
        }
        else if (suffix == ".png") {
          _response->setContentType("image/png");
        }
        else if (suffix == ".css") {
          _response->setContentType("text/css");
        }
        else if (suffix == ".html") {
          _response->setContentType("text/html");
        }
        else if (suffix == ".ico") {
          _response->setContentType("image/x-icon");
        }
        else if (suffix == ".pdf") {
          _response->setContentType("application/pdf");
        }
        else if (suffix == ".txt") {
          _response->setContentType("text/plain");
        }
        else {
          LOGGER_WARNING << "unknown suffix = " << suffix;
          _response->setContentType(contentType);
        }
      }
      else {
        _response->setContentType(contentType);
      }

      return HANDLER_DONE;
    }
 ServiceUnavailableHandler::ServiceUnavailableHandler ()
   : HttpHandler(0) {
   _response = createResponse(HttpResponse::SERVICE_UNAVAILABLE);
 }
Exemplo n.º 10
0
MsgPacket* ChannelController::processGetChannels(MsgPacket* request) {
    ChannelCache& channelCache = ChannelCache::instance();

    isyslog("Fetching channels ...");

    int type = request->get_U32();

    isyslog("Type: %s",
            type == 0 ? "MPEG2/H.264 channels" :
            type == 1 ? "radio channels" :
            type == 2 ? "H.264 channels" :
            "UNDEFINED"
           );

    //
    // PROTOCOL 7 - CLIENT MUST SEND THIS
    //

    const char* language = request->get_String();
    // do we want fta channels ?
    m_wantFta = request->get_U32();
    isyslog("Free To Air channels: %s", m_wantFta ? "Yes" : "No");

    // display only channels with native language audio ?
    m_filterLanguage = request->get_U32();
    isyslog("Only native language: %s", m_filterLanguage ? "Yes" : "No");

    // read caids
    m_caids.clear();
    uint32_t count = request->get_U32();

    isyslog("Enabled CaIDs: ");

    // sanity check (maximum of 20 caids)
    if(count < 20) {
        for(uint32_t i = 0; i < count; i++) {
            int caid = request->get_U32();
            m_caids.push_back(caid);
            isyslog("%04X", caid);
        }
    }

    m_languageIndex = I18nLanguageIndex(language);
    m_channelCount = channelCount();

    MsgPacket* response = createResponse(request);

    std::string groupName;

    LOCK_CHANNELS_READ;
    for(const cChannel* channel = Channels->First(); channel; channel = Channels->Next(channel)) {

        if(channel->GroupSep()) {
            groupName = m_toUtf8.convert(channel->Name());
            continue;
        }

        // skip disabled channels if filtering is enabled
        if(!channelCache.isEnabled(channel)) {
            continue;
        }

        if(!isChannelWanted(channel, type)) {
            continue;
        }

        addChannelToPacket(channel, response, groupName.c_str());
    }

    isyslog("client got %i channels", m_channelCount);
    return response;
}
Exemplo n.º 11
0
ByteArray VirtualSingleParam::createResponse(const ByteArray&, bool includeLen)
{
  return createResponse(includeLen);
}
Exemplo n.º 12
0
/**
 *  Wątek obsługujący pojedynczą wiadomość przesłaną do serwera.
 */
void Server::handleMessage(tcp::socket* socket){
    boost::array<char, 8192> messageBuffer;
    boost::system::error_code error;
    ioService.run();
    socket->read_some(boost::asio::buffer(messageBuffer), error);
    if (error){
        cerr<<error<<endl;
        socket->close();
        delete socket;
        return;
    }

    Message message;
    deserialize(message, messageBuffer.data());

    cout<<"Otrzymano wiadomość: "<<endl;
    cout<<message.toString()<<endl;

    int result;
    string response;
    string sessionId;
    History emptyHistory;
    vector<string> mismatchingParameters;
    History* history;

    if(message.getAction()!=REGISTER
       && message.getAction()!=LOGIN
       && message.getAction()!=UNREGISTER
       && (serverStore.getSessionId(message.getUserId())!=message.getSessionId()
        || serverStore.getSessionId(message.getUserId())==""))
    {
        response = createResponse(NOT_LOGGED_IN);
        socket->write_some(boost::asio::buffer(response), error);
        socket->close();
        delete socket;
        return;
    }

    switch(message.getAction()){
        case REGISTER:
        {
            // muszą być dwa parametry
            if (message.getParameters().size() != 2)
            {
                response = createResponse(WRONG_SYNTAX);
                socket->write_some(boost::asio::buffer(response), error);
            }
            else
            {
                // tworzymy użyszkodnika
                result = serverStore.registerUser(message.getParameters()[0], message.getParameters()[1]);
                switch (result)
                {
                    case 0: // użytkownik dodany poprawnie
                        response = createResponse(OK);
                        break;
                    case -1: // login zajęty
                        response = createResponse(INCORRECT_LOGIN);
                        break;
                }
                socket->write_some(boost::asio::buffer(response), error);
            }
            break;
        }
        case LOGIN:
        {
            // muszą być dwa parametry
            if (message.getParameters().size() != 2)
            {
                response = createResponse(WRONG_SYNTAX, "", &emptyHistory);
                socket->write_some(boost::asio::buffer(response), error);
            }
            else
            {
                // logowanie użyszkodnika
                result = serverStore.loginUser(message.getParameters()[0], message.getParameters()[1]);
                switch (result)
                {
                    case 0: // użytkownik zalogowany poprawnie
                        history = serverStore.getHistory(message.getUserId());
                        if(history==NULL){
                            history = &emptyHistory;
                        }
                        sessionId = generateSessionId();
                        serverStore.setSessionId(message.getUserId(), sessionId);
                        response = createResponse(OK, sessionId, history);
                        serverStore.clearHistory(message.getUserId());
                        break;
                    case -1: // niepoprawny login
                        response = createResponse(INCORRECT_LOGIN, "", &emptyHistory);
                        break;
                    case -2: // niepoprawne haslo
                        response = createResponse(INCORRECT_PASSWORD, "", &emptyHistory);
                        break;
                }
                socket->write_some(boost::asio::buffer(response), error);
            }
            break;
        }
        case LOGOUT:
        {
            serverStore.setSessionId(message.getUserId(), "");
            response = createResponse(OK);
            socket->write_some(boost::asio::buffer(response), error);
            break;
        }
        case UNREGISTER:
        {
            // muszą być dwa parametry
            if (message.getParameters().size() != 2)
            {
                response = createResponse(WRONG_SYNTAX);
                socket->write_some(boost::asio::buffer(response), error);
            }
            else
            {
                // usuwamy użyszkodnika
                result = serverStore.unregisterUser(message.getParameters()[0], message.getParameters()[1]);
                switch (result)
                {
                    case 0: // użytkownik usunięty poprawnie
                        response = createResponse(OK);
                        break;
                    case -1: // login błędny
                        response = createResponse(INCORRECT_LOGIN);
                        break;
                    case -2: // hasło błędne
                        response = createResponse(INCORRECT_PASSWORD);
                        break;
                }
                socket->write_some(boost::asio::buffer(response), error);
            }
            break;
        }
        case LIST:
        {
            //jeśli podano parametry - błąd
            if(message.getParameters().size()!=0){
                response = createResponse(WRONG_SYNTAX);
                socket->write_some(boost::asio::buffer(response), error);
                break;
            }

            vector<string> filenames = serverStore.list(message.getUserId());
            response = createResponse(OK, filenames);
            socket->write_some(boost::asio::buffer(response), error);
            filenames.clear();
            break;
        }
        case LIST_SHARED:
        {
            //jeśli podano parametry - błąd
            if(message.getParameters().size()!=0){
                response = createResponse(WRONG_SYNTAX);
                socket->write_some(boost::asio::buffer(response), error);
                break;
            }

            vector<string> names = serverStore.listShared(message.getUserId());
            response = createResponse(OK, names);
            socket->write_some(boost::asio::buffer(response), error);
            names.clear();
            break;
        }
        case UPLOAD:
            //jeśli nie podano parametrów - błąd
            if(message.getParameters().size()==0){
                response = createResponse(WRONG_SYNTAX);
                socket->write_some(boost::asio::buffer(response), error);
                break;
            }



            //żądanie poprawne, rozpocznij transfer
            dataPortAccessMutex.lock();
            response = createResponse(OK);
            socket->write_some(boost::asio::buffer(response), error);
            for(unsigned int i=0; i<message.getParameters().size(); ++i){
                cout<<"Użytkownik "<<message.getUserId()<<" przesyła plik "<<message.getParameters()[i]<<endl;
                result = fileTransferManager.receiveFile(message.getSource(), createFilePath(message.getUserId(), message.getParameters()[i]), i!=0);
                if(!result){
                    cerr<<"Nie przesłano pliku"<<endl;
                    break;
                }
                serverStore.add(message.getUserId(), message.getParameters()[i]);
                if(serverStore.fileExists(message.getUserId(), message.getParameters()[i])){
                    serverStore.updateHistory(FILE_MODIFIED, message.getUserId(), message.getParameters()[i]);
                }
                cout<<"Gotowe."<<endl;
            }
            dataPortAccessMutex.unlock();
            break;

        case DOWNLOAD:
            //jeśli nie podano parametrów - błąd
            if(message.getParameters().size()==0){
                response = createResponse(WRONG_SYNTAX);
                socket->write_some(boost::asio::buffer(response), error);
                break;
            }
            //jeśli któreś z podanych plików nie istnieją - błąd.
            //zwróć nazwy nieistniejących plików.
            for(unsigned int i=0; i<message.getParameters().size(); ++i){
                if(!serverStore.fileExists(message.getUserId(), message.getParameters()[i])){
                    mismatchingParameters.push_back(message.getParameters()[i]);
                }
            }
            if(mismatchingParameters.size()>0){
                response = createResponse(NO_SUCH_FILE, mismatchingParameters);
                socket->write_some(boost::asio::buffer(response), error);
                break;
            }

            //żądanie poprawne, rozpocznij transfer
            dataPortAccessMutex.lock();
            response = createResponse(OK);
            socket->write_some(boost::asio::buffer(response), error);
            for(unsigned int i=0; i<message.getParameters().size(); ++i){
                cout<<"Użytkownik "<<message.getUserId()<<" pobiera plik "<<message.getParameters()[i]<<endl;
                result = fileTransferManager.sendFile(message.getSource(), createFilePath(message.getUserId(), message.getParameters()[i]), true);
                if(!result){
                    cerr<<"Nie przesłano pliku"<<endl;
                    break;
                }
                cout<<"Gotowe."<<endl;
            }
            dataPortAccessMutex.unlock();
            break;

        case DOWNLOAD_SHARED:
            //musi być podany użytkownik oraz min. 1 plik, jeśli nie jest - błąd
            if(message.getParameters().size()<2){
                response = createResponse(WRONG_SYNTAX);
                socket->write_some(boost::asio::buffer(response), error);
                break;
            }

            //jeśli nie ma takiego użytkownika - błąd
            if(!serverStore.userExists(message.getParameters()[0])){
                response = createResponse(NO_SUCH_USER);
                socket->write_some(boost::asio::buffer(response), error);
                break;
            }

            //jeśli któreś z podanych plików nie istnieją - błąd.
            //zwróć nazwy nieistniejących plików.
            for(unsigned int i=1; i<message.getParameters().size(); ++i){
                if(!serverStore.fileExists(message.getParameters()[0], message.getParameters()[i])){
                    mismatchingParameters.push_back(message.getParameters()[i]);
                }
            }
            if(mismatchingParameters.size()>0){
                response = createResponse(NO_SUCH_FILE, mismatchingParameters);
                socket->write_some(boost::asio::buffer(response), error);
                break;
            }

            //jeśli użytkownik nie ma dostępu do któregoś z plików - błąd.
            //zwróć nazwy tychże plików.
            for(unsigned int i=1; i<message.getParameters().size(); ++i){
                if(!serverStore.hasAccess(message.getUserId(), message.getParameters()[0], message.getParameters()[i])){
                    mismatchingParameters.push_back(message.getParameters()[i]);
                }
            }
            if(mismatchingParameters.size()>0){
                response = createResponse(ACCESS_DENIED, mismatchingParameters);
                socket->write_some(boost::asio::buffer(response), error);
                break;
            }

            //żądanie poprawne, rozpocznij transfer
            dataPortAccessMutex.lock();
            response = createResponse(OK);
            socket->write_some(boost::asio::buffer(response), error);
            for(unsigned int i=1; i<message.getParameters().size(); ++i){
                cout<<"Użytkownik "<<message.getUserId()<<" pobiera plik "<<message.getParameters()[i]<<" należący do użytkownika "<<message.getParameters()[0]<<endl;
                result = fileTransferManager.sendFile(message.getSource(), createFilePath(message.getParameters()[0], message.getParameters()[i]), true);
                if(!result){
                    cerr<<"Nie przesłano pliku"<<endl;
                    break;
                }
                cout<<"Gotowe."<<endl;
            }
            dataPortAccessMutex.unlock();
            break;

        case REMOVE:
            //jeśli nie podano parametrów - błąd
            if(message.getParameters().size()==0){
                response = createResponse(WRONG_SYNTAX);
                socket->write_some(boost::asio::buffer(response), error);
                break;
            }

            //usuń pliki, jeśli istnieją, zapisz nazwy tych, które nie istnieją
            int result;
            for(unsigned int i=0; i<message.getParameters().size(); ++i){
                serverStore.updateHistory(FILE_REMOVED, message.getUserId(), message.getParameters()[i]);
                result = serverStore.remove(message.getUserId(), message.getParameters()[i]);
                if(result==0){
                    remove(createFilePath(message.getUserId(), message.getParameters()[i]).c_str());
                }else{
                    mismatchingParameters.push_back(message.getParameters()[i]);
                }
            }

            //wyślij zwrotny komunikat
            if(mismatchingParameters.size()>0){
                response = createResponse(NO_SUCH_FILE, mismatchingParameters);
            }else{
                response = createResponse(OK);
            }
            socket->write_some(boost::asio::buffer(response), error);
            break;

        case RENAME:
            //jeśli liczba parametrów różna od 2 - błąd
            if(message.getParameters().size()!=2){
                response = createResponse(WRONG_SYNTAX);
                socket->write_some(boost::asio::buffer(response), error);
                break;
            }
            result = serverStore.rename(message.getUserId(),
                message.getParameters()[0], message.getParameters()[1]);
            switch(result){
            case 0:
                serverStore.updateHistory(FILE_RENAMED, message.getUserId(), message.getParameters()[1], message.getParameters()[0]);
                rename(createFilePath(message.getUserId(), message.getParameters()[0]).c_str(), createFilePath(message.getUserId(), message.getParameters()[1]).c_str());
                response = createResponse(OK);
                break;
            case -2:
                mismatchingParameters.push_back(message.getParameters()[0]);
                response = createResponse(NO_SUCH_FILE, mismatchingParameters);
                break;
            case -3:
                mismatchingParameters.push_back(message.getParameters()[1]);
                response = createResponse(FILE_EXISTS, mismatchingParameters);
                break;
            }
            socket->write_some(boost::asio::buffer(response), error);
            break;
        case GIVE_ACCESS:
            if(message.getParameters().size()<2){
                response = createResponse(WRONG_SYNTAX);
                socket->write_some(boost::asio::buffer(response), error);
                break;
            }

            for(unsigned int i=1; i<message.getParameters().size(); ++i){
                result = serverStore.giveAccess(message.getUserId().c_str(), message.getParameters()[0].c_str(), message.getParameters()[i].c_str());
                switch(result){
                case 0:
                    serverStore.updateHistory(ACCESS_GRANTED, message.getUserId(), message.getParameters()[i], message.getParameters()[0]);
                    response = createResponse(OK);
                    break;
                case -1:
                    mismatchingParameters.push_back(message.getParameters()[i]);
                    response = createResponse(NO_SUCH_USER, mismatchingParameters);
                    break;
                case -2:
                    mismatchingParameters.push_back(message.getParameters()[i]);
                    response = createResponse(NO_SUCH_FILE, mismatchingParameters);
                    break;
                case -3:
                    mismatchingParameters.push_back(message.getParameters()[i]);
                    response = createResponse(NO_SUCH_USER, mismatchingParameters);
                    break;
                case -4:
                    mismatchingParameters.push_back(message.getParameters()[i]);
                    response = createResponse(ALREADY_HAVE_ACCESS, mismatchingParameters);
                    break;
                case -5:
                    mismatchingParameters.push_back(message.getParameters()[i]);
                    response = createResponse(OWN_FILE, mismatchingParameters);
                    break;
                }
                if(result!=0){
                    break;
                }
            }
            socket->write_some(boost::asio::buffer(response), error);
            break;
        case REVOKE_ACCESS:
            if(message.getParameters().size()<2){
                response = createResponse(WRONG_SYNTAX);
                socket->write_some(boost::asio::buffer(response), error);
                break;
            }
            for(unsigned int i=1; i<message.getParameters().size(); ++i){
                result = serverStore.revokeAccess(message.getUserId().c_str(), message.getParameters()[0].c_str(), message.getParameters()[i].c_str());
                switch(result){
                case 0:
                    serverStore.updateHistory(ACCESS_REVOKED, message.getUserId(), message.getParameters()[i], message.getParameters()[0]);
                    response = createResponse(OK);
                    break;
                case -1:
                    mismatchingParameters.push_back(message.getParameters()[i]);
                    response = createResponse(NO_SUCH_USER, mismatchingParameters);
                    break;
                case -2:
                    mismatchingParameters.push_back(message.getParameters()[i]);
                    response = createResponse(NO_SUCH_FILE, mismatchingParameters);
                    break;
                case -3:
                    mismatchingParameters.push_back(message.getParameters()[i]);
                    response = createResponse(NO_SUCH_USER, mismatchingParameters);
                    break;
                case -4:
                    mismatchingParameters.push_back(message.getParameters()[i]);
                    response = createResponse(ALREADY_NO_ACCESS, mismatchingParameters);
                    break;
                case -5:
                    mismatchingParameters.push_back(message.getParameters()[i]);
                    response = createResponse(OWN_FILE, mismatchingParameters);
                    break;
                }
                if(result!=0){
                    break;
                }
            }
            socket->write_some(boost::asio::buffer(response), error);
            break;
        default:
            response = createResponse(WRONG_SYNTAX);
            socket->write_some(boost::asio::buffer(response), error);
    }
    socket->close();
    delete socket;
}
Exemplo n.º 13
0
    // Stolen directly from RPCServerHandler
    std::string processRequest (std::string const& request, std::string const& remoteAddress)
    {
        Json::Value jvRequest;
        {
            Json::Reader reader;

            if (! reader.parse (request, jvRequest) ||
                jvRequest.isNull () ||
                ! jvRequest.isObject ())
            {
                return createResponse (400, "Unable to parse request");
            }
        }

        Config::Role const role (getConfig ().getAdminRole (jvRequest, remoteAddress));

        // Parse id now so errors from here on will have the id
        //
        // VFALCO NOTE Except that "id" isn't included in the following errors...
        //
        Json::Value const id = jvRequest ["id"];

        Json::Value const method = jvRequest ["method"];

        if (method.isNull ())
        {
            return createResponse (400, "Null method");
        }
        else if (! method.isString ())
        {
            return createResponse (400, "method is not string");
        }

        std::string strMethod = method.asString ();

        // Parse params
        Json::Value params = jvRequest ["params"];

        if (params.isNull ())
        {
            params = Json::Value (Json::arrayValue);
        }
        else if (!params.isArray ())
        {
            return HTTPReply (400, "params unparseable");
        }

        // VFALCO TODO Shouldn't we handle this earlier?
        //
        if (role == Config::FORBID)
        {
            // VFALCO TODO Needs implementing
            // FIXME Needs implementing
            // XXX This needs rate limiting to prevent brute forcing password.
            return HTTPReply (403, "Forbidden");
        }

        // This code does all the work on the io_service thread and
        // has no rate-limiting based on source IP or anything.
        // This is a temporary safety
        if ((role != Config::ADMIN) && (getApp().getFeeTrack().isLoadedLocal()))
        {
            return HTTPReply (503, "Unable to service at this time");
        }

        std::string response;

        m_journal.debug << "Query: " << strMethod << params;

        RPCHandler rpcHandler (&m_networkOPs);

        LoadType loadType = LT_RPCReference;

        Json::Value const result (rpcHandler.doRpcCommand (
            strMethod, params, role, &loadType));
        // VFALCO NOTE We discard loadType since there is no endpoint to punish

        m_journal.debug << "Reply: " << result;

        response = JSONRPCReply (result, Json::Value (), id);

        return createResponse (200, response);
    }
Exemplo n.º 14
0
HttpHandler::status_t PathHandler::execute() {
  std::vector<std::string> const& names = _request->suffix();
  std::string name = path;
  std::string last;

  if (names.empty() && !defaultFile.empty()) {
    std::string url = _request->requestPath();

    if (!url.empty() && url[url.size() - 1] != '/') {
      url += '/';
    }
    url += defaultFile;

    createResponse(GeneralResponse::ResponseCode::MOVED_PERMANENTLY);

    _response->setHeaderNC(StaticStrings::Location, url);
    _response->setContentType(HttpResponse::CONTENT_TYPE_HTML);

    _response->body().appendText(
        "<html><head><title>Moved</title></head><body><h1>Moved</h1><p>This "
        "page has moved to <a href=\"");
    _response->body().appendText(url);
    _response->body().appendText(">");
    _response->body().appendText(url);
    _response->body().appendText("</a>.</p></body></html>");

    return status_t(HANDLER_DONE);
  }

  for (std::vector<std::string>::const_iterator j = names.begin();
       j != names.end(); ++j) {
    std::string const& next = *j;

    if (next == ".") {
      LOG(WARN) << "file '" << name << "' contains '.'";

      createResponse(GeneralResponse::ResponseCode::FORBIDDEN);
      _response->body().appendText("path contains '.'");
      return status_t(HANDLER_DONE);
    }

    if (next == "..") {
      LOG(WARN) << "file '" << name << "' contains '..'";

      createResponse(GeneralResponse::ResponseCode::FORBIDDEN);
      _response->body().appendText("path contains '..'");
      return status_t(HANDLER_DONE);
    }

    std::string::size_type sc = next.find_first_not_of(AllowedChars);

    if (sc != std::string::npos) {
      LOG(WARN) << "file '" << name << "' contains illegal character";

      createResponse(GeneralResponse::ResponseCode::FORBIDDEN);
      _response->body().appendText("path contains illegal character '" +
                                   std::string(1, next[sc]) + "'");
      return status_t(HANDLER_DONE);
    }

    if (!path.empty()) {
      if (!FileUtils::isDirectory(path)) {
        LOG(WARN) << "file '" << name << "' not found";

        createResponse(GeneralResponse::ResponseCode::NOT_FOUND);
        _response->body().appendText("file not found");
        return status_t(HANDLER_DONE);
      }
    }

    name += "/" + next;
    last = next;

    if (!allowSymbolicLink && FileUtils::isSymbolicLink(name)) {
      LOG(WARN) << "file '" << name << "' contains symbolic link";

      createResponse(GeneralResponse::ResponseCode::FORBIDDEN);
      _response->body().appendText("symbolic links are not allowed");
      return status_t(HANDLER_DONE);
    }
  }

  if (!FileUtils::isRegularFile(name)) {
    LOG(WARN) << "file '" << name << "' not found";

    createResponse(GeneralResponse::ResponseCode::NOT_FOUND);
    _response->body().appendText("file not found");
    return status_t(HANDLER_DONE);
  }

  createResponse(GeneralResponse::ResponseCode::OK);

  try {
    FileUtils::slurp(name, _response->body());
  } catch (...) {
    LOG(WARN) << "file '" << name << "' not readable";

    createResponse(GeneralResponse::ResponseCode::NOT_FOUND);
    _response->body().appendText("file not readable");
    return status_t(HANDLER_DONE);
  }

  // check if we should use caching and this is an HTTP GET request
  if (cacheMaxAge > 0 &&
      _request->requestType() == GeneralRequest::RequestType::GET) {
    // yes, then set a pro-caching header
    _response->setHeaderNC(StaticStrings::CacheControl, maxAgeHeader);
  }

  std::string::size_type d = last.find_last_of('.');

  if (d != std::string::npos) {
    std::string suffix = last.substr(d + 1);

    if (suffix.size() > 0) {
      // look up the mimetype
      char const* mimetype = TRI_GetMimetype(suffix.c_str());

      if (mimetype != nullptr) {
        _response->setContentType(mimetype);

        return status_t(HANDLER_DONE);
      }
    } else {
      // note: changed the log level to debug. an unknown content-type does not
      // justify a warning
      LOG(TRACE) << "unknown suffix '" << suffix << "'";
    }
  }

  _response->setContentType(contentType);

  return status_t(HANDLER_DONE);
}
Exemplo n.º 15
0
void PathHandler::handleError(Exception const&) {
  createResponse(GeneralResponse::ResponseCode::SERVER_ERROR);
}