diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
| commit | 145449b1e420787bb99721a429341fa6be3adfb6 (patch) | |
| tree | 1d56ae694a6de602e348dd80165cf881a36600ed /llvm/lib/Debuginfod/Debuginfod.cpp | |
| parent | ecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (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.cpp | 63 |
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); } |
