summaryrefslogtreecommitdiff
path: root/llvm/lib/Debuginfod/Debuginfod.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
commit145449b1e420787bb99721a429341fa6be3adfb6 (patch)
tree1d56ae694a6de602e348dd80165cf881a36600ed /llvm/lib/Debuginfod/Debuginfod.cpp
parentecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff)
Vendor import of llvm-project main llvmorg-15-init-15358-g53dc0f107877.vendor/llvm-project/llvmorg-15-init-15358-g53dc0f107877
Diffstat (limited to 'llvm/lib/Debuginfod/Debuginfod.cpp')
-rw-r--r--llvm/lib/Debuginfod/Debuginfod.cpp63
1 files changed, 44 insertions, 19 deletions
diff --git a/llvm/lib/Debuginfod/Debuginfod.cpp b/llvm/lib/Debuginfod/Debuginfod.cpp
index 27614572766d..7b1c36fdbe09 100644
--- a/llvm/lib/Debuginfod/Debuginfod.cpp
+++ b/llvm/lib/Debuginfod/Debuginfod.cpp
@@ -115,6 +115,41 @@ Expected<std::string> getCachedOrDownloadArtifact(StringRef UniqueKey,
getDefaultDebuginfodTimeout());
}
+namespace {
+
+/// A simple handler which streams the returned data to a cache file. The cache
+/// file is only created if a 200 OK status is observed.
+class StreamedHTTPResponseHandler : public HTTPResponseHandler {
+ using CreateStreamFn =
+ std::function<Expected<std::unique_ptr<CachedFileStream>>()>;
+ CreateStreamFn CreateStream;
+ HTTPClient &Client;
+ std::unique_ptr<CachedFileStream> FileStream;
+
+public:
+ StreamedHTTPResponseHandler(CreateStreamFn CreateStream, HTTPClient &Client)
+ : CreateStream(CreateStream), Client(Client) {}
+ virtual ~StreamedHTTPResponseHandler() = default;
+
+ Error handleBodyChunk(StringRef BodyChunk) override;
+};
+
+} // namespace
+
+Error StreamedHTTPResponseHandler::handleBodyChunk(StringRef BodyChunk) {
+ if (!FileStream) {
+ if (Client.responseCode() != 200)
+ return Error::success();
+ Expected<std::unique_ptr<CachedFileStream>> FileStreamOrError =
+ CreateStream();
+ if (!FileStreamOrError)
+ return FileStreamOrError.takeError();
+ FileStream = std::move(*FileStreamOrError);
+ }
+ *FileStream->OS << BodyChunk;
+ return Error::success();
+}
+
Expected<std::string> getCachedOrDownloadArtifact(
StringRef UniqueKey, StringRef UrlPath, StringRef CacheDirectoryPath,
ArrayRef<StringRef> DebuginfodUrls, std::chrono::milliseconds Timeout) {
@@ -155,28 +190,18 @@ Expected<std::string> getCachedOrDownloadArtifact(
SmallString<64> ArtifactUrl;
sys::path::append(ArtifactUrl, sys::path::Style::posix, ServerUrl, UrlPath);
- Expected<HTTPResponseBuffer> ResponseOrErr = Client.get(ArtifactUrl);
- if (!ResponseOrErr)
- return ResponseOrErr.takeError();
+ // Perform the HTTP request and if successful, write the response body to
+ // the cache.
+ StreamedHTTPResponseHandler Handler([&]() { return CacheAddStream(Task); },
+ Client);
+ HTTPRequest Request(ArtifactUrl);
+ Error Err = Client.perform(Request, Handler);
+ if (Err)
+ return std::move(Err);
- HTTPResponseBuffer &Response = *ResponseOrErr;
- if (Response.Code != 200)
+ if (Client.responseCode() != 200)
continue;
- // We have retrieved the artifact from this server, and now add it to the
- // file cache.
- Expected<std::unique_ptr<CachedFileStream>> FileStreamOrErr =
- CacheAddStream(Task);
- if (!FileStreamOrErr)
- return FileStreamOrErr.takeError();
- std::unique_ptr<CachedFileStream> &FileStream = *FileStreamOrErr;
- if (!Response.Body)
- return createStringError(
- errc::io_error, "Unallocated MemoryBuffer in HTTPResponseBuffer.");
-
- *FileStream->OS << StringRef(Response.Body->getBufferStart(),
- Response.Body->getBufferSize());
-
// Return the path to the artifact on disk.
return std::string(AbsCachedArtifactPath);
}