예제 #1
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;
}
예제 #2
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();
	}
예제 #3
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();
    }
/*
    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);
         }
      }
   }
}