Example #1
0
/**
 * Stream the contents of a file to a given URL.
 * @param fileContents :: The contents of the file to publish.
 * @param uploadURL    :: The REST URL to stream the data from the file to.
 */
void CatalogPublish::publish(std::istream &fileContents,
                             const std::string &uploadURL) {
  try {
    Poco::URI uri(uploadURL);
    std::string path(uri.getPathAndQuery());

    Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> certificateHandler =
        new Poco::Net::AcceptCertificateHandler(true);
    // Currently do not use any means of authentication. This should be updated
    // IDS has signed certificate.
    const Poco::Net::Context::Ptr context =
        new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", "",
                               Poco::Net::Context::VERIFY_NONE);
    // Create a singleton for holding the default context. E.g. any future
    // requests to publish are made to this certificate and context.
    Poco::Net::SSLManager::instance().initializeClient(NULL, certificateHandler,
                                                       context);
    Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort(),
                                          context);

    // Send the HTTP request, and obtain the output stream to write to. E.g. the
    // data to publish to the server.
    Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_PUT, path,
                                   Poco::Net::HTTPMessage::HTTP_1_1);
    // Sets the encoding type of the request. This enables us to stream data to
    // the server.
    request.setChunkedTransferEncoding(true);
    std::ostream &os = session.sendRequest(request);
    // Copy data from the input stream to the server (request) output stream.
    Poco::StreamCopier::copyStream(fileContents, os);

    // Close the request by requesting a response.
    Poco::Net::HTTPResponse response;
    // Store the response for use IF an error occurs (e.g. 404).
    std::istream &responseStream = session.receiveResponse(response);

    // Obtain the status returned by the server to verify if it was a success.
    Poco::Net::HTTPResponse::HTTPStatus HTTPStatus = response.getStatus();
    // The error message returned by the IDS (if one exists).
    std::string IDSError =
        CatalogAlgorithmHelper().getIDSError(HTTPStatus, responseStream);
    // Cancel the algorithm and display the message if it exists.
    if (!IDSError.empty()) {
      // As an error occurred we must cancel the algorithm.
      // We cannot throw an exception here otherwise it is caught below as
      // Poco::Exception catches runtimes,
      // and then the I/O error is thrown as it is generated above first.
      this->cancel();
      // Output an appropriate error message from the JSON object returned by
      // the IDS.
      g_log.error(IDSError);
    }
  } catch (Poco::Net::SSLException &error) {
    throw std::runtime_error(error.displayText());
  }
  // This is bad, but is needed to catch a POCO I/O error.
  // For more info see comments (of I/O error) in CatalogDownloadDataFiles.cpp
  catch (Poco::Exception &) {
  }
}
    /**
     * Downloads datafiles from the archives, and saves to the users save default directory.
     * @param URL :: The URL of the file to download.
     * @param fileName :: The name of the file to save to disk.
     * @return The full path to the saved file.
     */
    std::string CatalogDownloadDataFiles::doDownloadandSavetoLocalDrive(const std::string& URL,const std::string& fileName)
    {
      std::string pathToDownloadedDatafile;

      clock_t start;

      try
      {
        Poco::URI uri(URL);

        std::string path(uri.getPathAndQuery());
        start=clock();

        Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> certificateHandler = new Poco::Net::AcceptCertificateHandler(true);
        // Currently do not use any means of authentication. This should be updated IDS has signed certificate.
        const Poco::Net::Context::Ptr context = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", "", Poco::Net::Context::VERIFY_NONE);
        // Create a singleton for holding the default context. E.g. any future requests to publish are made to this certificate and context.
        Poco::Net::SSLManager::instance().initializeClient(NULL, certificateHandler,context);
        Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort(), context);

        Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, path, Poco::Net::HTTPMessage::HTTP_1_1);
        session.sendRequest(request);

        // Close the request by requesting a response.
        Poco::Net::HTTPResponse response;
        // Store the response for use IF an error occurs (e.g. 404).
        std::istream& responseStream = session.receiveResponse(response);

        // Obtain the status returned by the server to verify if it was a success.
        Poco::Net::HTTPResponse::HTTPStatus HTTPStatus = response.getStatus();
        // The error message returned by the IDS (if one exists).
        std::string IDSError = CatalogAlgorithmHelper().getIDSError(HTTPStatus, responseStream);
        // Cancel the algorithm and display the message if it exists.
        if(!IDSError.empty())
        {
          // As an error occurred we must cancel the algorithm to prevent success message.
          this->cancel();
          // Output an appropriate error message from the JSON object returned by the IDS.
          g_log.error(IDSError);
          return "";
        }

        // Save the file to local disk if no errors occurred on the IDS.
        pathToDownloadedDatafile = saveFiletoDisk(responseStream,fileName);

        clock_t end=clock();
        float diff = float(end - start)/CLOCKS_PER_SEC;
        g_log.information()<<"Time taken to download file "<< fileName<<" is "<<std::fixed << std::setprecision(2) << diff <<" seconds" << std::endl;

      }
      catch(Poco::Net::SSLException& error)
      {
        throw std::runtime_error(error.displayText());
      }
      // A strange error occurs (what returns: {I/O error}, while message returns: { 9: The BIO reported an error }.
      // This bug has been fixed in POCO 1.4 and is noted - http://sourceforge.net/p/poco/bugs/403/
      // I have opted to catch the exception and do nothing as this allows the load/download functionality to work.
      // However, the port the user used to download the file will be left open.
      catch(Poco::Exception&) {}

      return pathToDownloadedDatafile;
    }