예제 #1
0
파일: HttpServer.cpp 프로젝트: imace/nnt
static int begin_request(mg_connection* cnt)
{
    mg_request_info const* req = mg_get_request_info(cnt);
    
    // create http object.
    use<HttpServer> serv = req->user_data;
    HttpConnection http;
    http.connection = cnt;
    http.request = req;
    http.server = serv;
    http.update();
    
    // dispatch.
    core::string const& req_file = http.uri.filename();
    static const core::regex re_python("^\\S+.py$");
    if (re_python.match(req_file))
    {
        python::FileRequest pyreq;
        pyreq.uri = serv->config.document + http.uri;
        pyreq.method = http.method;
        if (pyreq.process())
        {
            parser::Http11Response resp;
            resp.data.append(pyreq.stream);
            http.write(resp.full());
        }
    }
    
    // send signal.
    serv->emit(kSignalNewConnection, eventobj_t::Data(&http));
    
    return 1;
}
예제 #2
0
void HttpWorker::spawnConnection(Socket* client, ServerSocket* listener)
{
	TRACE(1, "client connected; fd:%d", client->handle());

	++connectionLoad_;
	++connectionCount_;

	// XXX since socket has not been used so far, I might be able to defer its creation out of its socket descriptor
	// XXX so that I do not have to double-initialize libev's loop handles for this socket.
	client->setLoop(loop_);

	HttpConnection* c;
	if (likely(freeConnections_ != nullptr)) {
		c = freeConnections_;
		c->id_ = connectionCount_;
		freeConnections_ = c->next_;

		c->reinitialize();
	}
	else {
		c = new HttpConnection(this, connectionCount_/*id*/);
	}

	if (connections_)
		connections_->prev_ = c;

	c->next_ = connections_;
	connections_ = c;

	c->start(listener, client);
}
예제 #3
0
void HttpUploader::setRequestHeaders(const StringBuffer& luid, HttpConnection& httpConnection, InputStream& inputStream) {
    
    StringBuffer dataSize;
    int totalSize = inputStream.getTotalSize();
    LOG.debug("[%s]: input stream size is %i", __FUNCTION__, totalSize);
    LOG.debug("[%s]: totalDataToUpload size is %i", __FUNCTION__, totalDataToUpload);
    if (totalDataToUpload > 0) {
        totalSize = totalDataToUpload;
    } 
    dataSize.sprintf("%d", totalSize);
    

    httpConnection.setRequestHeader(HTTP_HEADER_ACCEPT,         "*/*");
    httpConnection.setRequestHeader(HTTP_HEADER_CONTENT_TYPE,   "application/octet-stream");

    // set transfer enconding to chunked
    //httpConnection.setRequestHeader(HTTP_HEADER_TRANSFER_ENCODING, "chunked");

    // set Funambol mandatory custom headers
    httpConnection.setRequestHeader(HTTP_HEADER_X_FUNAMBOL_FILE_SIZE, dataSize);
    httpConnection.setRequestHeader(HTTP_HEADER_X_FUNAMBOL_DEVICE_ID, deviceID);
    httpConnection.setRequestHeader(HTTP_HEADER_X_FUNAMBOL_LUID, luid);
    
    if (partialUploadedData > 0) {
        StringBuffer s;
        s.sprintf("bytes %d-%d/%d", partialUploadedData, totalSize-1, totalSize);
        
        httpConnection.setRequestHeader(HTTP_HEADER_CONTENT_RANGE, s.c_str());
    }
}
예제 #4
0
void
ProjectGiraffeTab4::OnAppControlCompleteResponseReceived(const AppId &appId, const String &operationId, AppCtrlResult appControlResult, const IMap *extraData)
{
	AppLogTag("camera1", "appid %ls opid %ls", appId.GetPointer(), operationId.GetPointer());
	if (appId.Equals(L"tizen.filemanager", true) &&
			operationId.Equals(L"http://tizen.org/appcontrol/operation/pick", true))
	{
		if (appControlResult == APP_CTRL_RESULT_SUCCEEDED) {
			AppLogTag("camera1", "Media list success.");
			String pathKey = L"path";
			String *filePath = (String *)extraData->GetValue(pathKey);

			AppLogTag("camera1", "filepath: %ls", filePath->GetPointer());

			HttpMultipartEntity* userParameters = new HttpMultipartEntity();
			userParameters->Construct();
			userParameters->AddFilePart(L"avatar", *filePath);

			HttpConnection *connection = HttpConnection::userUpdatePutConnection(this, userParameters);
			connection->begin();

			// TODO: figure out when to free
//			delete userParameters;
		} else if (appControlResult == APP_CTRL_RESULT_CANCELED) {
			AppLogTag("camera1", "Media list canceled.");
		} else if (appControlResult == APP_CTRL_RESULT_FAILED) {
			AppLogTag("camera1", "Media list failed.");
		}
	} else if (appId.Equals(L"tizen.camera", true) &&
			operationId.Equals(L"http://tizen.org/appcontrol/operation/createcontent", true))
	{
		AppLogTag("camera1", "camcam");
		if (appControlResult == APP_CTRL_RESULT_SUCCEEDED) {
			AppLogTag("camera1", "Camera capture success.");

			String pathKey = L"path";
			String *filePath = (String *)extraData->GetValue(pathKey);

			AppLogTag("camera1", "filepath: %ls", filePath->GetPointer());

			HttpMultipartEntity* userParameters = new HttpMultipartEntity();
			userParameters->Construct();
			userParameters->AddFilePart(L"avatar", *filePath);

			HttpConnection *connection = HttpConnection::userUpdatePutConnection(this, userParameters);
			connection->begin();

			// TODO: figure out when to free
			// delete userParameters;
		} else if (appControlResult == APP_CTRL_RESULT_CANCELED) {
			AppLogTag("camera1", "Camera capture canceled.");
		} else if (appControlResult == APP_CTRL_RESULT_FAILED) {
			AppLogTag("camera1", "Camera capture failed.");
		} else if (appControlResult == APP_CTRL_RESULT_TERMINATED) {
			AppLogTag("camera1", "Camera capture terminated.");
		} else if (appControlResult == APP_CTRL_RESULT_ABORTED) {
			AppLogTag("camera1", "Camera capture aborted.");
		}
	}
}
예제 #5
0
void
ProjectGiraffeTab4::updateItems()
{
	AppLog("updating items");
	HttpConnection *connection = HttpConnection::userPostsGetConnection(this,User::currentUser()->id());
	connection->begin();
}
예제 #6
0
	virtual void httpFinished(HttpConnection*, int result) {
		if(result == 304) {	//Not Modified
			printf("Program unchanged.\n");
#ifdef MA_PROF_SUPPORT_STYLUS
			printf("Tap screen or press Fire to run.\n");
#else	// MA_PROF_SUPPORT_STYLUS
			printf("Press Fire to run.\n");
#endif	// MA_PROF_SUPPORT_STYLUS
			mState = eReady;
			return;
		}
		if(result >= 200 && result <= 299) {	//OK
			printf("HTTP %i\n", result);
			String cls;
			int res = mHttp.getResponseHeader("content-length", &cls);
			if(res < 0) {
				printf("CL error: %i\n", res);
				return;
			}
			int contentLength = stringToInteger(cls);
			printf("Content-Length: %i\n", contentLength);
			maDestroyObject(mProgram);
			if(maCreateData(mProgram, contentLength) == RES_OUT_OF_MEMORY) {
				printf("Out of memory!\n");
				return;
			}
			mHttp.readToData(mProgram, 0, contentLength);
			return;
		} else {	//error
			printf("HTTP %s %i\n", (result < 0) ? "error" : "response", result);
		}
	}
예제 #7
0
SYSCALL(void, maHttpSetRequestHeader(MAHandle conn, const char* key, const char* value)) {
	LOGS("HttpSetRequestHeader %i %s: %s\n", conn, key, value);
	MAStreamConn& mac = getStreamConn(conn);
	HttpConnection* http = mac.conn->http();
	MYASSERT(http != NULL, ERR_CONN_NOT_HTTP);
	MYASSERT(http->mState == HttpConnection::SETUP, ERR_HTTP_NOT_SETUP);
	http->SetRequestHeader(key, value);
}
예제 #8
0
void
ProjectGiraffeTab1::updateItems()
{
#if kDebugUseDummyItems
	AppLog("Creating dummy items");
	User *dummyUser = new User();
	dummyUser->setUsername(L"Username");
	for (int i = 0; i < 10; i++) {
		Graffiti *graffiti = new Graffiti();
		graffiti->setUser(dummyUser);
		graffiti->setText(L"dummy string");
		_items->Add(graffiti);
	}

#else

#if kDebugUseHttpConnection

	double latitude = ProjectGiraffeMainForm::currentLatitude;
	double longitude = ProjectGiraffeMainForm::currentLongitude;
	HttpConnection *connection = HttpConnection::graffitiNearbyGetConnection(this,latitude,longitude);
	connection->begin();

#else
	// Kick off http request for items based on location.
	// Populate item source array
	HttpSession* pHttpSession = null;
	HttpTransaction* pHttpTransaction = null;
	String* pProxyAddr = null;
	String hostAddr = L"http://ec2-54-243-69-6.compute-1.amazonaws.com/";
	String uri = L"http://ec2-54-243-69-6.compute-1.amazonaws.com/";

	AppLog("Starting the HTTP Session");
	pHttpSession = new HttpSession();

	// HttpSession construction.
	pHttpSession->Construct(NET_HTTP_SESSION_MODE_NORMAL, pProxyAddr, hostAddr, null);

	// Open a new HttpTransaction.
	pHttpTransaction = pHttpSession->OpenTransactionN();

	// Add a listener.
	pHttpTransaction->AddHttpTransactionListener(*this);

	// Get an HTTP request.
	HttpRequest* pHttpRequest = pHttpTransaction->GetRequest();

	// Set the HTTP method and URI:
	pHttpRequest->SetMethod(NET_HTTP_METHOD_GET);
	pHttpRequest->SetUri(uri);

	// Submit the request:
	pHttpTransaction->Submit();
#endif

#endif
}
예제 #9
0
int HttpUploader::upload(const StringBuffer& luid, InputStream* inputStream) 
{
    int status = 0;

    // safe checks
    if (!inputStream || !inputStream->getTotalSize()) {
        LOG.error("upload error: no data to transfer");
        return 1;
    }
    if (luid.empty() || syncUrl.empty()  || sourceURI.empty()) {
        LOG.error("upload error: some params are not set");
        return 2;
    }
    
    StringBuffer fullUrl = composeURL();
    URL url(fullUrl.c_str());
    HttpConnection* httpConnection = getHttpConnection();
   
    httpConnection->setCompression(false);
    status = httpConnection->open(url, HttpConnection::MethodPost);
    
    if (status) { 
        delete httpConnection;

        return status;
    }

    httpConnection->setKeepAlive(keepalive);
    httpConnection->setRequestChunkSize(maxRequestChunkSize);
   
    // Set headers (use basic auth)
    HttpAuthentication* auth = new BasicAuthentication(username, password);
    httpConnection->setAuthentication(auth);
    setRequestHeaders(luid, *httpConnection, *inputStream);
    
    // Send the HTTP request
    StringOutputStream response;
    status = httpConnection->request(*inputStream, response);
    LOG.debug("response returned = %s", response.getString().c_str());
    
    // Manage response headers
    if (useSessionID) {
        // Server returns the jsessionId in the Set-Cookie header, can be used for 
        // the subsequent calls of upload().
        StringBuffer hdr = httpConnection->getResponseHeader(HTTP_HEADER_SET_COOKIE);
        sessionID = httpConnection->parseJSessionId(hdr);
    }
    
    httpConnection->close();
    
    delete auth;
    delete httpConnection;
    return status;
}
예제 #10
0
/*---------------------------------------------------------------------------*/
QVariant HttpRecognizer::comment( IConnection* connection )
{
	Q_ASSERT (connection);
	if (!mConnections.contains( connection->networkInfo() ))
		return "No comment yet";

	const HttpConnection con = mConnections.value( connection->networkInfo() );
	const QHttpRequestHeader request = con.lastRequestHeader();
	const QHttpResponseHeader response = con.lastResponseHeader();

	return request.method() + " " + request.value( "host" ) + request.path()
		+ (response.isValid() ? "\nHTTP " + QString::number( response.statusCode() ) + " " + response.reasonPhrase() : "" );
}
예제 #11
0
AP_MSG_HANDLER_METHOD(ServerModule, HttpServer_SendResponse)
{
  HttpConnection* pConnection = findHttpConnection(pMsg->hConnection);
  if (pConnection == 0) { throw ApException(LOG_CONTEXT, "findHttpConnection(" ApHandleFormat ") failed", ApHandlePrintf(pMsg->hConnection)); }

  String sHeader;

  if (!pMsg->sProtocol) {
    pMsg->sProtocol = "HTTP/1.1";
  }

  if (pMsg->nStatus == 0) {
    pMsg->nStatus = 200;
  }

  if (!pMsg->sMessage) {
    if (pMsg->nStatus == 200) {
      pMsg->sMessage = "OK";
    } else {
      pMsg->sMessage = "No Message";
    }
  }

  sHeader.appendf("%s %d %s\r\n", _sz(pMsg->sProtocol), pMsg->nStatus, _sz(pMsg->sMessage));
  
  {
    for (Apollo::KeyValueElem* e = 0; (e = pMsg->kvHeader.nextElem(e)) != 0; ) {
      sHeader.appendf("%s: %s\r\n", _sz(e->getKey()), _sz(e->getString()));
    }
  }

  if (pMsg->sbBody.Length() > 0) {
    if (pMsg->kvHeader.find("content-length", Apollo::KeyValueList::IgnoreCase)) {
    } else {
      sHeader.appendf("Content-length: %d\r\n", pMsg->sbBody.Length());
    }
  } else {
    sHeader.appendf("Content-length: 0\r\n");
  }

  //sHeader += "Connection: close\r\n";
  sHeader += "\r\n";
  
  pConnection->DataOut((unsigned char*) sHeader.c_str(), sHeader.bytes());

  if (pMsg->sbBody.Length() > 0) {
    pConnection->DataOut(pMsg->sbBody.Data(), pMsg->sbBody.Length());
  }

  pMsg->apStatus = ApMessage::Ok;
}
예제 #12
0
	void startDownload() {

		if(0 == strcmp(URL, ""))
		{
			printf("No url provided, \nsee source code for \ninformation on how \nto use this example");
			return;
		}

		printf("Downloading from %s\n", URL);
		//in case of re-download
		mHttp.close();

		mHttp.create(URL, HTTP_GET);
		if(mLastModified.length() > 0)
			mHttp.setRequestHeader("If-Modified-Since", mLastModified.c_str());
		mHttp.finish();
	}
예제 #13
0
SYSCALL(int, maHttpGetResponseHeader(MAHandle conn, const char* key, char* buffer, int bufSize)) {
	SYSCALL_THIS->ValidateMemRange(buffer, bufSize);
	MAStreamConn& mac = getStreamConn(conn);
	HttpConnection* http = mac.conn->http();
	MYASSERT(http != NULL, ERR_CONN_NOT_HTTP);
	MYASSERT(http->mState == HttpConnection::FINISHED, ERR_HTTP_NOT_FINISHED);

	const std::string* valueP = http->GetResponseHeader(key);
	if(valueP == NULL)
		return CONNERR_NOHEADER;

	if(bufSize > (int)valueP->length()) {
		memcpy(buffer, valueP->c_str(), valueP->length() + 1);
	}

	return valueP->length();
}
예제 #14
0
파일: HttpWorker.cpp 프로젝트: liveck/x0
void HttpWorker::spawnConnection(Socket* client, ServerSocket* listener)
{
	TRACE("client connected; fd:%d", client->handle());

	++connectionLoad_;
	++connectionCount_;

	// XXX since socket has not been used so far, I might be able to defer its creation out of its socket descriptor
	// XXX so that I do not have to double-initialize libev's loop handles for this socket.
	client->setLoop(loop_);

	HttpConnection* c = new HttpConnection(this, connectionCount_/*id*/);

	connections_.push_front(c);
	ConnectionHandle i = connections_.begin();

	c->start(listener, client, i);
}
예제 #15
0
    /**
     * Tests a GET on a specific URL, prints the response.
     */
    void testGET(const URL& testURL) 
    {
        LOG.debug("test GET on %s", testURL.fullURL);
        int ret = httpConnection.open(testURL, HttpConnection::MethodGet);
        LOG.debug("open, ret = %d", ret);
        
        BufferInputStream inputStream("");
        StringOutputStream outputStream;
        
        httpConnection.setRequestHeader(HTTP_HEADER_ACCEPT,          "*/*");
        httpConnection.setRequestHeader(HTTP_HEADER_CONTENT_LENGTH,  0);

        ret = httpConnection.request(inputStream, outputStream);
        LOG.debug("request, ret = %d", ret);
        LOG.debug("response = \n%s", outputStream.getString().c_str());
        
        httpConnection.close();
    }
예제 #16
0
void HttpServer::checkConnections()
{
	if(this->closed){
		for(vector<HttpConnection*>::iterator it = this->connections.begin();
			it!=this->connections.end(); it++)
			(*it)->close();
	}
	for(vector<HttpConnection*>::iterator it = this->connections.begin();
		it!=this->connections.end(); ){
		HttpConnection* conn = *it;
		if(conn->isClosed()){
			conn->joinThread();
			delete conn;
			this->connections.erase(it);
		}else{
			it ++;
		}
	}
}
예제 #17
0
int HttpListener::addConnection( struct conn_data * pCur, int *iCount )
{
    int fd = pCur->fd;
    if ( checkAccess( pCur ))
    {
        no_timewait( fd );
        close( fd );
        --(*iCount);
        return 0;
    }
    HttpConnection* pConn = HttpConnPool::getConnection();
    if ( !pConn )
    {
        ERR_NO_MEM( "HttpConnPool::getConnection()" );
        close( fd );
        --(*iCount);
        return -1;
    }
    VHostMap * pMap;
    if ( m_pSubIpMap )
    {
        pMap = getSubMap( fd );
    }
    else
        pMap = getVHostMap();
    pConn->setVHostMap( pMap );
    pConn->setLogger( getLogger());
    pConn->setRemotePort( ntohs( ((sockaddr_in *)(pCur->achPeerAddr))->sin_port) );
    if ( pConn->setLink( pCur->fd, pCur->pInfo, pMap->getSSLContext() ) )
    {
        HttpConnPool::recycle( pConn );
        close( fd );
        --(*iCount);
        return -1;
    }
    fcntl( fd, F_SETFD, FD_CLOEXEC );
    fcntl( fd, F_SETFL, HttpGlobals::getMultiplexer()->getFLTag() );
    //pConn->tryRead();
    return 0;
}
예제 #18
0
/*! Actually aborts all active connections.
 *
 * \note Must be invoked from within the worker's thread.
 *
 * \see HttpConnection::abort()
 */
void HttpWorker::_kill()
{
	TRACE(1, "_kill()");
	while (connections_) {
		std::list<HttpConnection*> copy;

		for (HttpConnection* c = connections_; c != nullptr; c = c->next_)
			copy.push_back(c);

		for (auto c: copy)
			c->abort();

#ifndef XZERO_NDEBUG
		for (HttpConnection* c = connections_; c != nullptr; c = c->next_)
			c->log(Severity::debug, "connection still open");
#endif
	}

	for (auto handler: killHandler_) {
		TRACE(1, "_kill: invoke kill handler");
		handler();
	}
}
예제 #19
0
void HttpServer::process()
{
        if(!this->listenSocket.bind(1998)){
            cerr << "Failed to bind server port 1998." << endl;
        }

	this->listenSocket.listen();
	
	while(!this->closed){
		HttpSocket* sock = this->listenSocket.accept();
		if(sock == NULL)
			continue;
		
		HttpConnection* conn = new HttpConnection(sock);
		conn->startThread();
		
		this->connections.push_back(conn);
		checkConnections();
	}
	
	
	checkConnections();
    cout << "httpserver ends." << endl;
}
예제 #20
0
	virtual void connReadFinished(Connection*, int result) {
		if(result < 0) {
			printf("Read error %i\n", result);
			return;
		}

		//save Last-Modified header to cache
		mHttp.getResponseHeader("last-modified", &mLastModified);
		MAHandle data = maCreatePlaceholder();
		maCreateData(data, mLastModified.length());
		maWriteData(data, mLastModified.c_str(), 0, mLastModified.length());
		MAHandle store = maOpenStore(MODSAV, MAS_CREATE_IF_NECESSARY);
		if(store < 0) {
			printf("Meta-cache open error: %i\n", store);
		} else {
			int res = maWriteStore(store, data);
			if(res < 0) {
				printf("Meta-cache write error: %i\n", res);
			}
			maCloseStore(store, 0);
		}
		maDestroyPlaceholder(data);

		//save program to cache
		store = maOpenStore(SAV, MAS_CREATE_IF_NECESSARY);
		if(store < 0) {
			printf("Cache open error: %i\n", store);
		} else {
			int res = maWriteStore(store, mProgram);
			if(res < 0) {
				printf("Cache write error: %i\n", res);
			}
			maCloseStore(store, 0);
		}

		printf("Program downloaded.\n");
#ifdef MA_PROF_SUPPORT_STYLUS
		printf("Tap screen or press Fire to run.\n");
#else	// MA_PROF_SUPPORT_STYLUS
		printf("Press Fire to run.\n");
#endif	// MA_PROF_SUPPORT_STYLUS
		mState = eReady;
	}
/*
    Returns the token for wassup based authentication or an empty string if errors occur
    Parameters:
                username: as inserted by the user
                password: as inserted by the user
                err: output flag to check for errors
 */
std::string WassupTokenRequestManager::getToken(std::string username, std::string password, bool *err, int* requestCode)
{
    std::string token = "";
    *err = false;
    *requestCode = HTTP_OK;
    
    //request token over http
    LOG.debug("Getting wassup token");
    
    StringOutputStream response;
    HttpConnection *httpConnection = NULL;
    URL requestUrl;

    std::string formattedURL(_wassupURI);
    std::stringstream ss;
    std::string xmlResponse;

    //URL encode usr and pwd
    const char * usernameEncoded = URL::urlEncode(username.c_str());
    const char * passwordEncoded = URL::urlEncode(password.c_str());
    
    ss << _wassupURI << "?" << _wassupUsrParam << usernameEncoded << "&" << _wassupPwdParam << passwordEncoded << "&" << _wassupAdditionalParam;
    
    formattedURL = ss.str();
    
    requestUrl.setURL(formattedURL.c_str());
    
    httpConnection = new HttpConnection(_userAgent);
    httpConnection->setSSLVerifyServer(verifyServerSSL);
    
    if (httpConnection->open(requestUrl, HttpConnection::MethodGet, false)!= 0) {
        LOG.error("%s: error opening connection", __FUNCTION__);
        *err = true;
        *requestCode = -1;
        delete httpConnection;
   
        return "";
    } else {
        int requestStatus = HTTP_OK;
        
        if ((requestStatus = httpConnection->request(NULL, response, false)) != HTTP_OK) {
            LOG.error("%s: error sending Wassup access token request", __FUNCTION__);
            *err = true;
            if ((requestStatus == HttpConnection::StatusNetworkError) || 
                (requestStatus == HttpConnection::StatusReadingError) ||
                (requestStatus == HttpConnection::StatusTimeoutError) ||
                (requestStatus == HttpConnection::StatusWritingError)) {
                *requestCode = -1;
            } else {
                *requestCode = requestStatus;
            }
            
            httpConnection->close();
            delete httpConnection;
   
            return "";
        } else {
            xmlResponse.assign(response.getString().c_str());
            //LOG.debug("Wassup access token request response received: %s", xmlResponse.c_str());
        }
    }
    
    httpConnection->close();
    delete httpConnection;
    
    //parse response to extract token
    unsigned int startPos = 0;
    unsigned int endPos   = 0;
    bool found = false;
    while(!found & !*err)
    {
        if(XMLProcessor::getElementAttributes(xmlResponse.c_str(), "ident", &startPos, &endPos)==NULL)
        {
            LOG.error("%s: error parsing XML response", __FUNCTION__);
            *err = true;
        }
        else
        {
            std::string attributeName = xmlResponse.substr(startPos+6, 6);
            int tokenStartIndex = startPos + 21;
            int tokenEndIndex   = endPos - 3;
            int tokenLenght     = tokenEndIndex - tokenStartIndex + 1;
            
            if (attributeName=="cooses") {
                token = xmlResponse.substr(tokenStartIndex, tokenLenght);
                found = true;
            }
            else//try next tag
            {
                xmlResponse = xmlResponse.substr(endPos+1);
            }
        }
    }
        
    return token;
}
예제 #22
0
int HttpListener::batchAddConn( struct conn_data * pBegin,
                            struct conn_data *pEnd, int *iCount )
{
    struct conn_data * pCur = pBegin;
    int n = pEnd - pBegin;
    while( pCur < pEnd )
    {
        if ( checkAccess( pCur))
        {
            no_timewait( pCur->fd );
            close( pCur->fd );
            pCur->fd = -1;
            --(*iCount);
            --n;
        }
        ++pCur;
    }
    if ( n <= 0 )
        return 0;
    HttpConnection* pConns[CONN_BATCH_SIZE];
    int ret = HttpConnPool::getConnections( pConns, n);
    pCur = pBegin;
    if ( ret <= 0 )
    {
        ERR_NO_MEM( "HttpConnPool::getConnections()" );
        LOG_ERR(( "need %d connections, allocated %d connections!", n, ret ));
        while( pCur < pEnd )
        {
            if ( pCur->fd != -1 )
            {
                close( pCur->fd );
                --(*iCount);
            }
            ++pCur;
        }
        return -1;
    }
    HttpConnection** pConnEnd = &pConns[ret];
    HttpConnection** pConnCur = pConns;
    VHostMap * pMap;
    int flag = HttpGlobals::getMultiplexer()->getFLTag();
    while( pCur < pEnd )
    {
        register int fd = pCur->fd;
        if ( fd != -1 )
        {
            assert( pConnCur < pConnEnd );
            HttpConnection * pConn = *pConnCur;

            if ( m_pSubIpMap )
            {
                pMap = getSubMap( fd );
            }
            else
                pMap = getVHostMap();

            pConn->setVHostMap( pMap );
            pConn->setLogger( getLogger());
            pConn->setRemotePort( ntohs( ((sockaddr_in *)(pCur->achPeerAddr))->sin_port) );

        //    if ( getDedicated() )
        //    {
        //        //pConn->accessGranted();
        //    }
            if ( !pConn->setLink( fd, pCur->pInfo, pMap->getSSLContext() ) )
            {
                fcntl( fd, F_SETFD, FD_CLOEXEC );
                fcntl( fd, F_SETFL, flag );
                ++pConnCur;
                //pConn->tryRead();
            }
            else
            {
                close( fd );
                --(*iCount);
            }
        }
        ++pCur;
    }
    if ( pConnCur < pConnEnd )
    {
        HttpConnPool::recycle( pConnCur, pConnEnd - pConnCur);
    }

    return 0;
}
예제 #23
0
void ProxyResourceHandler::operator()(BtpAction* action)
{
   // get request host
   HttpRequestHeader* hrh = action->getRequest()->getHeader();
   string host = hrh->getFieldValue("X-Forwarded-Host");
   if(host.length() == 0)
   {
      host = hrh->getFieldValue("Host");
   }

   // find a rule
   Rule* rule = findRule(action, host);
   if(rule == NULL)
   {
      // delegate to rest resource handler
      RestResourceHandler::operator()(action);
   }
   else
   {
      // get URL to proxy or redirect to
      UrlRef url = rule->url;

      // get url host
      string urlHost;
      HttpResponse* res = action->getResponse();
      bool secure = res->getConnection()->isSecure();

      // if URL has no host, reuse incoming host
      if(url->getHost().length() == 0)
      {
         urlHost = host;
      }
      // if URL has no port or uses a default port number, only use URL host
      else if(
         (url->getPort() == 0) ||
         (secure && url->getPort() == 443) ||
         (!secure && url->getPort() == 80))
      {
         urlHost = url->getHost();
      }
      // use URL host and port
      else
      {
         urlHost = url->getHostAndPort();
      }

      // handle 0.0.0.0 (any host) by replacing it with the request host
      if(strncmp(urlHost.c_str(), "0.0.0.0", 8) == 0)
      {
         // 0.0.0.0 is 8 chars long
         urlHost.replace(0, 8, host.substr(0, host.find(':')).c_str());
      }

      // rewrite the request path if it does not match URL path
      string path = hrh->getPath();
      if(strcmp(path.c_str(), url->getPath().c_str()) != 0)
      {
         // check for path wildcard
         if(strcmp(rule->path, "*") == 0)
         {
            // since a wildcard is used, prepend the URL path to the
            // resource (if the url path isn't '/')
            string urlPath = url->getPath();
            if(urlPath.length() > 1)
            {
               path.insert(0, url->getPath().c_str());
            }
         }
         else
         {
            // replace the part of the resource that matched the proxy
            // rule with the rewrite path from the proxy URL
            path.replace(0, strlen(rule->path), url->getPath().c_str());
         }
      }

      // do redirect if appropriate
      if(rule->type == Rule::Redirect)
      {
         // set response code
         HttpResponseHeader* header = res->getHeader();
         if(rule->permanent)
         {
            header->setStatus(301, "Moved Permanently");
         }
         else
         {
            header->setStatus(302, "Found");
         }

         // build new location url
         bool secure = res->getConnection()->isSecure();
         header->setField("Location", StringTools::format("%s://%s%s",
            secure ? "https" : "http", urlHost.c_str(), path.c_str()));
         action->sendResult();
      }
      // do proxy
      else if(rule->type == Rule::Proxy)
      {
         // get client-side request
         HttpRequest* req = action->getRequest();

         // do path rewrite
         hrh->setPath(path.c_str());

         // add X-Forwarded headers
         hrh->appendFieldValue("X-Forwarded-For",
            req->getConnection()->getRemoteAddress()->toString(true).c_str());
         hrh->appendFieldValue("X-Forwarded-Host",
            hrh->getFieldValue("Host").c_str());
         hrh->appendFieldValue("X-Forwarded-Server",
            SocketTools::getHostname().c_str());

         // rewrite host if rule specifies it
         if(rule->rewriteHost)
         {
            hrh->setField("Host", urlHost.c_str());
         }

         // do proxy:
         MO_CAT_INFO(BM_NODE_CAT,
            "ProxyResourceHandler proxying %s%s => %s%s",
            host.c_str(), hrh->getPath(), urlHost.c_str(), path.c_str());
         MO_CAT_DEBUG(BM_NODE_CAT,
            "ProxyResourceHandler request header for %s%s => %s%s:\n%s",
            host.c_str(), hrh->getPath(),
            urlHost.c_str(), path.c_str(),
            hrh->toString().c_str());

         // get a connection
         BtpClient* btpc = mNode->getMessenger()->getBtpClient();
         HttpConnection* conn = btpc->createConnection(false, &(*url));
         if(conn == NULL)
         {
            // send service unavailable
            HttpResponseHeader* header = action->getResponse()->getHeader();
            header->setStatus(503, "Service Unavailable");
            string content =
               "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"
               "<html><head>\n"
               "<title>503 Service Unavailable</title>\n"
               "</head><body>\n"
               "<h1>Service Unavailable</h1>\n"
               "<p>The service was not available.</p>\n"
               "</body></html>";
            ByteBuffer b(content.length());
            b.put(content.c_str(), content.length(), false);
            ByteArrayInputStream bais(&b);
            action->sendResult(&bais);
         }
         else
         {
            // proxy the client's request and receive server's header (by
            // writing it into the client's response header)
            HttpResponse* res = action->getResponse();
            if(_proxyHttp(req->getHeader(), req->getConnection(), conn) &&
               conn->receiveHeader(res->getHeader()))
            {
               // proxy the server's response, consider result sent
               _proxyHttp(res->getHeader(), conn, req->getConnection());
               action->setResultSent(true);
            }

            // close connection
            conn->close();

            // clean up
            delete conn;
         }

         if(!action->isResultSent())
         {
            // send exception (client's fault if code < 500)
            ExceptionRef e = Exception::get();
            action->sendException(e, e->getCode() < 500);
         }
      }
   }
}
예제 #24
0
    // Process Response
    static void processHttpResponse(HttpResponse* response, std::string& errorStr)
    {
        auto request = response->getHttpRequest();
        long responseCode = -1;
        int retValue = 0;
        HttpConnection xhr;
        bool ok = false;
        bool manualAuthReqd = false;

        // Process the request -> get response packet
        switch (request->getRequestType())
        {
        case HttpRequest::Type::GET: // HTTP GET
            ok = (xhr.init(request) && xhr.open("GET", manualAuthReqd, s_cookieFilename) && xhr.send());
            break;

        case HttpRequest::Type::POST: // HTTP POST
            ok = (xhr.init(request) && xhr.open("POST", manualAuthReqd, s_cookieFilename) && xhr.send());
            break;

        case HttpRequest::Type::PUT: // HTTP PUT
            ok = (xhr.init(request) && xhr.open("PUT", manualAuthReqd, s_cookieFilename) && xhr.send());
            break;

        case HttpRequest::Type::DELETE: // HTTP DELETE
            ok = (xhr.init(request) && xhr.open("DELETE", manualAuthReqd, s_cookieFilename) && xhr.send());
            break;

        default:
            CCASSERT(true, "CCHttpClient: unknown request type, only GET and POST are supported");
            break;
        }

        writeData(xhr.getResponseHeader(), response->getResponseHeader());
        writeData(xhr.getResponseData(), response->getResponseData());
        retValue = ok ? 0 : 1;
        errorStr = xhr.getErrorMessage();
        responseCode = xhr.getStatusCode();

        // write data to HttpResponse
        response->setResponseCode(responseCode);

        if (retValue != 0)
        {
            response->setSucceed(false);
            response->setErrorBuffer(errorStr.c_str());
        }
        else
        {
            response->setSucceed(true);
        }
    }
예제 #25
0
HttpMessageBodyChunk::HttpMessageBodyChunk(
  HttpConnection& connection,
  YO_NEW_REF Buffer* data
) : yield::http::HttpMessageBodyChunk(data),
  connection(connection.inc_ref()) {
}
예제 #26
0
int HttpServer::run(void* runArg)
{
    OsConnectionSocket* requestSocket = NULL;

    if (!mpServerSocket->isOk())
    {
        OsSysLog::add( FAC_SIP, PRI_ERR, "HttpServer: port not ok" );
        httpStatus = OS_PORT_IN_USE;
    }

    while(!isShuttingDown() && mpServerSocket->isOk())
    {
        requestSocket = mpServerSocket->accept();

        if(requestSocket)
        {
            if (mbPersistentConnection)
            {
                // Take this opportunity to check for any old HttpConnections that can be deleted
                int items = mpHttpConnectionList->entries();
                if (items != 0)
                {
                    int deleted = 0;

                    UtlSListIterator iterator(*mpHttpConnectionList);
                    HttpConnection* connection;
                    while ((connection = dynamic_cast<HttpConnection*>(iterator())))
                    {
                        if (connection->toBeDeleted())
                        {
                           OsSysLog::add(FAC_SIP, PRI_DEBUG,
                                         "HttpServer: destroying connection %p",
                                         connection);
                           mpHttpConnectionList->destroy(connection);
                           ++deleted;

                           if (mHttpConnections > 0)
                           {
                              --mHttpConnections;
                           }
                        }
                    }
                    items = mpHttpConnectionList->entries();
                    OsSysLog::add(FAC_SIP, PRI_DEBUG,
                                  "HttpServer: "
                                  "destroyed %d inactive HttpConnections, %d remaining",
                                  deleted, items);
                }
                // Create new persistent connection
                if (mHttpConnections < MAX_PERSISTENT_HTTP_CONNECTIONS)
                {
                    ++mHttpConnections;
                    HttpConnection* newConnection = new HttpConnection(requestSocket, this);
                    mpHttpConnectionList->append(newConnection);
                    OsSysLog::add(FAC_SIP, PRI_INFO,
                                  "HttpServer::run starting persistent connection %d (%p)",
                                  mHttpConnections, newConnection);
                    newConnection->start();
                }
                else
                {
                   OsSysLog::add(FAC_SIP, PRI_ERR,
                                 "HttpServer::run exceeded persistent connection limit (%d):"
                                 " sending 503",
                                 MAX_PERSISTENT_HTTP_CONNECTIONS);
                    HttpMessage request;
                    HttpMessage response;
                    // Read the http request from the socket
                    request.read(requestSocket);

                    // Send out-of-resources message
                    response.setResponseFirstHeaderLine(HTTP_PROTOCOL_VERSION,
                                                        HTTP_OUT_OF_RESOURCES_CODE,
                                                        HTTP_OUT_OF_RESOURCES_TEXT);
                    response.write(requestSocket);
                    requestSocket->close();
                    delete requestSocket;
                    requestSocket = NULL;
                }
            }
            else
            {
                HttpMessage request;
                // Read a http request from the socket
                request.read(requestSocket);

                UtlString remoteIp;
                requestSocket->getRemoteHostIp(&remoteIp);

                HttpMessage* response = NULL;

                // If request from Valid IP Address
                if( processRequestIpAddr(remoteIp, request, response))
                {
                   // If the request is authorized
                   processRequest(request, response, requestSocket);
                }

                if(response)
                {
                    response->write(requestSocket);
                    delete response;
                    response = NULL;
                }

                requestSocket->close();
                delete requestSocket;
                requestSocket = NULL;
            }
        }
        else
        {
           httpStatus = OS_PORT_IN_USE;
        }
    } // while (!isShuttingDown && mpServerSocket->isOk())

    if ( !isShuttingDown() )
    {
       OsSysLog::add( FAC_SIP, PRI_ERR, "HttpServer: exit due to port failure" );
    }

    httpStatus = OS_TASK_NOT_STARTED;

    return(TRUE);
}