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; }
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(); }
/** * 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(); }
/* 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; }
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); } } } }