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; }
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); }
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()); } }
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."); } } }
void ProjectGiraffeTab4::updateItems() { AppLog("updating items"); HttpConnection *connection = HttpConnection::userPostsGetConnection(this,User::currentUser()->id()); connection->begin(); }
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); } }
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); }
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 }
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; }
/*---------------------------------------------------------------------------*/ 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() : "" ); }
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; }
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(); }
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(); }
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); }
/** * 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(); }
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 ++; } } }
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; }
/*! 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(); } }
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; }
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; }
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; }
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); } } } }
// 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); } }
HttpMessageBodyChunk::HttpMessageBodyChunk( HttpConnection& connection, YO_NEW_REF Buffer* data ) : yield::http::HttpMessageBodyChunk(data), connection(connection.inc_ref()) { }
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); }