|
1 | 1 | /*************************************************************** |
2 | 2 | * |
3 | | - * Copyright (C) 2024, Pelican Project, Morgridge Institute for Research |
| 3 | + * Copyright (C) 2025, Pelican Project, Morgridge Institute for Research |
4 | 4 | * |
5 | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you |
6 | 6 | * may not use this file except in compliance with the License. You may |
@@ -277,6 +277,15 @@ size_t HTTPRequest::ReadCallback(char *buffer, size_t size, size_t n, void *v) { |
277 | 277 | return CURL_READFUNC_ABORT; |
278 | 278 | } |
279 | 279 |
|
| 280 | + if (payload->m_parent.m_log.getMsgMask() & LogMask::Dump) { |
| 281 | + payload->m_parent.m_log.Log( |
| 282 | + LogMask::Dump, "ReadCallback", |
| 283 | + ("sentSoFar=" + std::to_string(payload->sentSoFar) + |
| 284 | + " data.size=" + std::to_string(payload->data.size()) + |
| 285 | + " final=" + std::to_string(payload->final)) |
| 286 | + .c_str()); |
| 287 | + } |
| 288 | + |
280 | 289 | if (payload->sentSoFar == static_cast<off_t>(payload->data.size())) { |
281 | 290 | payload->sentSoFar = 0; |
282 | 291 | if (payload->final) { |
@@ -778,19 +787,30 @@ void HTTPRequest::ProcessCurlResult(CURL *curl, CURLcode rv) { |
778 | 787 |
|
779 | 788 | HTTPUpload::~HTTPUpload() {} |
780 | 789 |
|
781 | | -bool HTTPUpload::SendRequest(const std::string &payload, off_t offset, |
782 | | - size_t size) { |
783 | | - if (offset != 0 || size != 0) { |
784 | | - std::string range; |
785 | | - formatstr(range, "bytes=%lld-%lld", static_cast<long long int>(offset), |
786 | | - static_cast<long long int>(offset + size - 1)); |
787 | | - headers["Range"] = range.c_str(); |
788 | | - } |
789 | | - |
| 790 | +bool HTTPUpload::SendRequest(const std::string &payload) { |
790 | 791 | httpVerb = "PUT"; |
| 792 | + expectedResponseCode = 201; |
791 | 793 | return SendHTTPRequest(payload); |
792 | 794 | } |
793 | 795 |
|
| 796 | +bool HTTPUpload::StartStreamingRequest(const std::string_view payload, |
| 797 | + off_t object_size) { |
| 798 | + httpVerb = "PUT"; |
| 799 | + expectedResponseCode = 201; |
| 800 | + headers["Content-Type"] = "binary/octet-stream"; |
| 801 | + return sendPreparedRequest(hostUrl, payload, object_size, false); |
| 802 | +} |
| 803 | + |
| 804 | +bool HTTPUpload::ContinueStreamingRequest(const std::string_view payload, |
| 805 | + off_t object_size, bool final) { |
| 806 | + // Note that despite the fact that final gets passed through here, |
| 807 | + // in reality the way that curl determines whether the data transfer is |
| 808 | + // done is by seeing if the total amount of data sent is equal to the |
| 809 | + // expected size of the entire payload, stored in m_object_size. |
| 810 | + // See HTTPRequest::ReadCallback for more info |
| 811 | + return sendPreparedRequest(hostUrl, payload, object_size, final); |
| 812 | +} |
| 813 | + |
794 | 814 | void HTTPRequest::Init(XrdSysError &log) { |
795 | 815 | if (!m_workers_initialized) { |
796 | 816 | for (unsigned idx = 0; idx < CurlWorker::GetPollThreads(); idx++) { |
@@ -837,3 +857,46 @@ bool HTTPHead::SendRequest() { |
837 | 857 | } |
838 | 858 |
|
839 | 859 | // --------------------------------------------------------------------------- |
| 860 | + |
| 861 | +int HTTPRequest::HandleHTTPError(const HTTPRequest &request, XrdSysError &log, |
| 862 | + const char *operation, const char *context) { |
| 863 | + auto httpCode = request.getResponseCode(); |
| 864 | + if (httpCode) { |
| 865 | + std::stringstream ss; |
| 866 | + ss << operation << " failed: " << request.getResponseCode() << ": " |
| 867 | + << request.getResultString(); |
| 868 | + if (context) { |
| 869 | + ss << " (context: " << context << ")"; |
| 870 | + } |
| 871 | + log.Log(LogMask::Warning, "HTTPRequest::HandleHTTPError", |
| 872 | + ss.str().c_str()); |
| 873 | + |
| 874 | + switch (httpCode) { |
| 875 | + case 404: |
| 876 | + return -ENOENT; |
| 877 | + case 500: |
| 878 | + return -EIO; |
| 879 | + case 403: |
| 880 | + return -EPERM; |
| 881 | + case 401: |
| 882 | + return -EACCES; |
| 883 | + case 400: |
| 884 | + return -EINVAL; |
| 885 | + case 503: |
| 886 | + return -EAGAIN; |
| 887 | + default: |
| 888 | + return -EIO; |
| 889 | + } |
| 890 | + } else { |
| 891 | + std::stringstream ss; |
| 892 | + ss << "Failed to send " << operation |
| 893 | + << " command: " << request.getErrorCode() << ": " |
| 894 | + << request.getErrorMessage(); |
| 895 | + if (context) { |
| 896 | + ss << " (context: " << context << ")"; |
| 897 | + } |
| 898 | + log.Log(LogMask::Warning, "HTTPRequest::HandleHTTPError", |
| 899 | + ss.str().c_str()); |
| 900 | + return -EIO; |
| 901 | + } |
| 902 | +} |
0 commit comments