IdLastModified MessagesClient::modifyMeta( const IdLastModified &idlm, const std::vector<unsigned char> &meta) { auto url = baseUserUrl() + "/messages/" + std::to_string(idlm.id) + "?lastModified=" + std::to_string(idlm.lastModified); Json::Value jsonBody(Json::objectValue); jsonBody["meta"] = Base64::encode(meta); sendRequest(Http::Request( Http::HttpMethod::Patch, url, makeHeaders(Authenticated::True)), jsonBody); auto json = parseJsonBody(); try { return parseJsonIdLastModified(json); } catch (ConversionException) { std::throw_with_nested(ProtocolError("Failed to parse idLastModified")); } }
ProfileInfo ProfileClient::uploadChange(ProfileInfo newValue) { auto url = baseUserUrl() + "/profile/" + newValue.key + "?lastModified=" + std::to_string(newValue.lastModified); Json::Value jsonBody(Json::objectValue); jsonBody["value"] = newValue.value; sendRequest(Http::Request( Http::HttpMethod::Put, url, makeHeaders(Authenticated::True)), jsonBody); auto json = parseJsonBody(); try { auto result = parseJsonKeyLastModified(json); if (result.key != newValue.key) { throw ProtocolError("Server sent the wrong record"); } result.value = newValue.value; return result; } catch (ConversionException) { std::throw_with_nested(ProtocolError("Failed to parse body")); } }
/** * @brief HTTPS::send_request * @return */ int HTTPS::send_request() { std::string headers = makeHeaders(m_url, m_path); // make header string if (SSL_write(ssl, headers.c_str(), headers.length()) <= 0) // write the data { throw ISAException("Error - SSL sending failed."); } return 0; }
/** * @brief HTTP::send_request * @return int */ int HTTP::send_request() { std::string query = makeHeaders(m_url, m_path); // prepare the headers auto tmp = send(m_sock, query.c_str(), query.length(), 0); // send request if (tmp == -1) { close(m_sock); throw ISAException("Error - Sending request"); } return 0; }
/** * Log out from SCARF. In practice, it trashes the cookie (if we were * successfully logged in). * * As the authentication method is specific to SCARF, this logout * method has been placed here as specific to SCARF too. Most likely * it is general to other LSF systems without any/much changes. * * @param username Username to use (should have authenticated * before). Leave it empty to log out the last (maybe only) user that * logged in with authenticate(). */ void SCARFLSFJobManager::logout(const std::string &username) { if (g_tokenStash.empty()) { throw std::runtime_error("Logout failed. No one is currenlty logged in."); } std::map<std::string, Token>::iterator it; if (!username.empty()) { it = g_tokenStash.find(username); if (g_tokenStash.end() == it) { throw std::invalid_argument( "Logout failed. The username given is not logged in: " + username); } } // only support for single-user Token tok = g_tokenStash.begin()->second; // logout query, needs headers = {'Content-Type': 'text/plain', 'Cookie': // token, // 'Accept': 'text/plain,application/xml,text/xml'} const std::string token = tok.m_token_str; const Poco::URI fullURL = makeFullURI(tok.m_url, g_logoutPath); const StringToStringMap headers = makeHeaders(std::string("text/plain"), token, g_acceptType); int code = 0; std::stringstream ss; try { code = doSendRequestGetResponse(fullURL, ss, headers); } catch (Kernel::Exception::InternetError &ie) { throw std::runtime_error("Error while sending HTTP request to log out: " + std::string(ie.what())); } if (Mantid::Kernel::InternetHelper::HTTP_OK == code) { g_log.notice() << "Logged out." << std::endl; g_log.debug() << "Response from server: " << ss.str() << std::endl; } else { throw std::runtime_error("Failed to logout from the web service at: " + fullURL.toString() + ". Please check your username."); } // successfully logged out, forget the token if (username.empty()) { // delete first one g_tokenStash.erase(g_tokenStash.begin()); } else { // delete requested one if (g_tokenStash.end() != it) g_tokenStash.erase(it); } }
MessagesClient::GetMessagesResult MessagesClient::getMessages( lastModified_type modifiedAfter) { auto url = baseUserUrl() + "/messages?modifiedAfter=" + std::to_string(modifiedAfter) + "&includeData=true"; sendRequest(Http::Request( Http::HttpMethod::Get, url, makeHeaders(Authenticated::True))); auto json = parseJsonBody(); if (!json.isObject()) { throw ProtocolError("Malformed JSON document (object expected)"); } auto resultsTotal = CheckedConverter::toUint32(json["resultsTotal"]); auto resultsReturned = CheckedConverter::toUint32(json["resultsReturned"]); auto data = json["data"]; if (!data.isArray()) { throw ProtocolError("Malformed JSON document (array expected)"); } auto messages = std::vector<Message>(); messages.reserve(data.size()); for (const auto &msgJson : data) { try { messages.push_back(parseJsonMessage(msgJson)); } catch (ConversionException) { std::throw_with_nested(ProtocolError("Failed to parse messages array")); } } GetMessagesResult result; result.messages = std::move(messages); result.countReturned = resultsReturned; result.countLeft = resultsTotal; return result; }
MessagesClient::SendMessageResult MessagesClient::doSendMessage( const KulloAddress *recipient, const SendableMessage &message, const std::vector<unsigned char> &meta, const boost::optional<ProgressHandler> &onProgress) { bool toSelf = !recipient; kulloAssert((!toSelf && meta.empty()) || (toSelf && !meta.empty())); auto auth = (toSelf) ? Authenticated::True : Authenticated::False; Util::MimeMultipart multipart; multipart.addPart("keySafe", message.keySafe); multipart.addPart("content", message.content); if (!meta.empty()) multipart.addPart("meta", meta); multipart.addPart("attachments", message.attachments); auto contentType = std::string("multipart/form-data; boundary=\"") + multipart.boundary() + "\""; auto body = multipart.toString(); sendRequest(Http::Request( Http::HttpMethod::Post, baseUserUrl(recipient) + "/messages", makeHeaders(auth, contentType, body.size())), body, onProgress); SendMessageResult result; if (toSelf) { auto json = parseJsonBody(); try { result.messageSent = parseJsonMessageSent(json); result.messageSent->size = body.size(); result.requestBodySize = body.size(); } catch (ConversionException) { std::throw_with_nested( ProtocolError("Failed to parse message sent data")); } } return result; }
MessageAttachments MessagesClient::getMessageAttachments( id_type id, const Protocol::ProgressHandler &onProgress) { auto url = baseUserUrl() + "/messages/" + std::to_string(id) + "/attachments"; sendRequest(Http::Request( Http::HttpMethod::Get, url, makeHeaders(Authenticated::True)), onProgress); MessageAttachments attachments; attachments.id = id; attachments.attachments = responseBody_; responseBody_.clear(); return attachments; }
std::vector<ProfileInfo> ProfileClient::downloadChanges( lastModified_type modifiedAfter) { sendRequest(Http::Request( Http::HttpMethod::Get, baseUserUrl() + "/profile?modifiedAfter=" + std::to_string(modifiedAfter), makeHeaders(Authenticated::True))); auto json = parseJsonBody(); if (!json.isObject()) { throw ProtocolError("Malformed JSON document (object expected)"); } auto data = json["data"]; if (!data.isArray()) { throw ProtocolError("Malformed JSON document (array expected)"); } auto result = std::vector<ProfileInfo>(); result.reserve(data.size()); for (const auto &profileInfoJson : data) { try { result.push_back(parseJsonProfileInfo(profileInfoJson)); } catch (ConversionException) { std::throw_with_nested( ProtocolError("Failed to parse profile info array")); } } return result; }
/** * Ping the server to see if the web service is active/available. * Note that this method does not need the user to be logged in. * * For now this ping method sits here as specific to SCARF. It is not * clear at the moment if it is general to LSF. It could well be * possible to pull this into LSFJobManager. * * @return true if the web service responds. */ bool SCARFLSFJobManager::ping() { // Job ping, needs these headers: // headers = {'Content-Type': 'application/xml', 'Accept': ACCEPT_TYPE} const Poco::URI fullURL = makeFullURI(Poco::URI(g_pingBaseURL), g_pingPath); const StringToStringMap headers = makeHeaders(std::string("text/plain"), "", g_acceptType); int code = 0; std::stringstream ss; try { code = doSendRequestGetResponse(fullURL, ss, headers); } catch (Kernel::Exception::InternetError &ie) { throw std::runtime_error("Error while sending HTTP request to ping the " "server " + std::string(ie.what())); } bool ok = false; if (Mantid::Kernel::InternetHelper::HTTP_OK == code) { std::string resp = ss.str(); if (std::string::npos != resp.find("Web Services are ready")) { g_log.notice() << "Pinged compute resource with apparently good response: " << resp << '\n'; ok = true; } else { g_log.warning() << "Pinged compute resource but got what looks like an " "error message: " << resp << '\n'; } } else { throw std::runtime_error( "Failed to ping the web service at: " + fullURL.toString() + ". Please check your parameters, software version, " "etc."); } return ok; }
IdLastModified MessagesClient::deleteMessage( const IdLastModified &idlm) { auto url = baseUserUrl() + "/messages/" + std::to_string(idlm.id) + "?lastModified=" + std::to_string(idlm.lastModified); sendRequest(Http::Request( Http::HttpMethod::Delete, url, makeHeaders(Authenticated::True))); auto json = parseJsonBody(); try { return parseJsonIdLastModified(json); } catch (ConversionException) { std::throw_with_nested(ProtocolError("Failed to parse idLastModified")); } }
int main(int argc, const char* argv[]) { // // Parse arguments // std::string outputFolder("output"); std::string inputFolder; for (int i = 1; i < argc; ++i) { if (strncmp(argv[i], "-h", 2) == 0) { printUsage(); return EXIT_SUCCESS; } else if (strncmp(argv[i], "-v", 2) == 0) { printVersion(); return EXIT_SUCCESS; } else if (strncmp(argv[i], "-o", 2) == 0) { i++; if (i == argc) { logError("The output folder is missing!\n"); printUsage(); return EXIT_FAILURE; } outputFolder = std::string(argv[i]); } else { inputFolder = std::string(argv[i]); if (i != argc - 1) { logError("Not support more than one input file folder!\n"); printUsage(); return EXIT_FAILURE; } } } if (inputFolder == "") { logError("Invalid input path!\n"); printUsage(); return EXIT_FAILURE; } // // Create directory of output // if (!CreateDirectoryA(outputFolder.c_str(), NULL)) { DWORD err = GetLastError(); if (err == ERROR_PATH_NOT_FOUND) { logError("Some intermediate directories in the path (%s) are missing.\n", outputFolder.c_str()); return EXIT_FAILURE; } } if (!makeHeaders(inputFolder.c_str(), outputFolder.c_str())) { return EXIT_FAILURE; } // If debugger is present, a pause is required to keep the console output // visible. Otherwise the pause is automatic. if (IsDebuggerPresent()) { system("pause"); } return EXIT_SUCCESS; }