예제 #1
0
std::istream &RemoteJobManager::httpGet(const std::string &path,
                                        const std::string &query_str,
                                        const std::string &username,
                                        const std::string &password) {
  Poco::Net::HTTPRequest req;
  initGetRequest(req, path, query_str);

  if (username.length() > 0) {
    // Set the Authorization header (base64 encoded)
    std::ostringstream encodedAuth;
    Poco::Base64Encoder encoder(encodedAuth);
    encoder << username << ":" << password;
    encoder.close();
    req.setCredentials("Basic", encodedAuth.str());
  }

  m_session->sendRequest(req);

  std::istream &respStream = m_session->receiveResponse(m_response);

  // For as yet unknown reasons, we don't always get a session cookie back from
  // the
  // server. In that case, we don't want to overwrite the cookie we're currently
  // using...
  // Note: This won't work properly if we ever use cookies other than a
  // session cookie.
  std::vector<Poco::Net::HTTPCookie> newCookies;
  m_response.getCookies(newCookies);
  if (!newCookies.empty()) {
    m_cookies = newCookies;
  }

  return respStream;
}
예제 #2
0
std::istream &RemoteJobManager::httpPost(const std::string &path,
                                         const PostDataMap &postData,
                                         const PostDataMap &fileData,
                                         const std::string &username,
                                         const std::string &password) {
  Poco::Net::HTTPRequest req;
  initPostRequest(req, path);

  if (username.length() > 0) {
    // Set the Authorization header (base64 encoded)
    std::ostringstream encodedAuth;
    Poco::Base64Encoder encoder(encodedAuth);
    encoder << username << ":" << password;
    encoder.close();
    req.setCredentials("Basic", encodedAuth.str());
  }

  // We have to do a POST with multipart MIME encoding. MIME is rather picky
  // about
  // how the parts are delimited. See RFC 2045 & 2046 for details.

  char httpLineEnd[3] = {0x0d, 0x0a,
                         0x00}; // HTTP uses CRLF for its line endings

  // boundary can be almost anything (again, see RFC 2046). The important part
  // is that it
  // cannot appear anywhere in the actual data
  std::string boundary = "112233MantidHTTPBoundary44556677";
  std::string boundaryLine = "--" + boundary + httpLineEnd;
  std::string finalBoundaryLine = "--" + boundary + "--" + httpLineEnd;

  req.setContentType("multipart/form-data; boundary=" + boundary);

  // Need to be able to specify the content length, so build up the post body
  // here.
  std::ostringstream postBody;
  auto it = postData.cbegin();
  while (it != postData.cend()) {
    postBody << boundaryLine;
    postBody << "Content-Disposition: form-data; name=\"" << (*it).first
             << "\"";
    postBody << httpLineEnd << httpLineEnd;
    postBody << (*it).second;
    postBody << httpLineEnd;
    ++it;
  }

  // file data is treated the same as post data, except that we set the filename
  // field
  // in the Content-Disposition header and add the Content-Type header
  it = fileData.begin();
  while (it != fileData.end()) {
    postBody << boundaryLine;
    postBody << "Content-Disposition: form-data; name=\"" << (*it).first
             << "\"; filename=\"" << (*it).first << "\"";
    postBody << httpLineEnd;
    postBody << "Content-Type: application/octet-stream";
    postBody << httpLineEnd << httpLineEnd;
    postBody << (*it).second;
    postBody << httpLineEnd;
    ++it;
  }

  postBody << finalBoundaryLine;

  req.setContentLength(static_cast<int>(postBody.str().size()));

  std::ostream &postStream = m_session->sendRequest(req);

  // upload the actual HTTP body
  postStream << postBody.str() << std::flush;

  std::istream &respStream = m_session->receiveResponse(m_response);

  // For as yet unknown reasons, we don't always get a session cookie back from
  // the
  // server. In that case, we don't want to overwrite the cookie we're currently
  // using...
  // Note: This won't work properly if we ever use cookies other than a
  // session cookie.
  std::vector<Poco::Net::HTTPCookie> newCookies;
  m_response.getCookies(newCookies);
  if (!newCookies.empty()) {
    m_cookies = newCookies;
  }

  return respStream;
}