Http[s]Download: Make the constructor's initialization DRY

Problem:
- `HttpDownload()` and `HttpsDownload()` implementations are the same
  except for types and certificates.

Solution:
- Follow the "Don't Repeat Yourself" mantra and de-duplicate the code
  using templates.
This commit is contained in:
Lenny Maiorani 2021-01-14 12:06:54 -07:00 committed by Andreas Kling
parent 0f7efd5bf1
commit 9f64424661
Notes: sideshowbarker 2024-07-18 23:48:32 +09:00
4 changed files with 43 additions and 54 deletions

View file

@ -55,9 +55,6 @@ public:
void set_download_fd(int fd) { m_download_fd = fd; }
int download_fd() const { return m_download_fd; }
protected:
explicit Download(ClientConnection&, NonnullOwnPtr<OutputFileStream>&&);
void did_finish(bool success);
void did_progress(Optional<u32> total_size, u32 downloaded_size);
void set_status_code(u32 status_code) { m_status_code = status_code; }
@ -66,6 +63,9 @@ protected:
void set_downloaded_size(size_t size) { m_downloaded_size = size; }
const OutputFileStream& output_stream() const { return *m_output_stream; }
protected:
explicit Download(ClientConnection&, NonnullOwnPtr<OutputFileStream>&&);
private:
ClientConnection& m_client;
i32 m_id { 0 };

View file

@ -28,14 +28,50 @@
#include <AK/ByteBuffer.h>
#include <AK/HashMap.h>
#include <AK/NonnullOwnPtr.h>
#include <AK/Optional.h>
#include <AK/OwnPtr.h>
#include <AK/String.h>
#include <AK/Types.h>
#include <LibHTTP/HttpRequest.h>
#include <ProtocolServer/ClientConnection.h>
#include <ProtocolServer/Download.h>
namespace ProtocolServer::Detail {
template<typename TSelf, typename TJob>
void init(TSelf* self, TJob job)
{
job->on_headers_received = [&](auto& headers, auto response_code) {
if (response_code.has_value())
self->set_status_code(response_code.value());
self->set_response_headers(headers);
};
job->on_finish = [&](bool success) {
if (auto* response = job->response()) {
self->set_status_code(response->code());
self->set_response_headers(response->headers());
self->set_downloaded_size(self->output_stream().size());
}
// if we didn't know the total size, pretend that the download finished successfully
// and set the total size to the downloaded size
if (!self->total_size().has_value())
self->did_progress(self->downloaded_size(), self->downloaded_size());
self->did_finish(success);
};
job->on_progress = [&](Optional<u32> total, u32 current) {
self->did_progress(total, current);
};
if constexpr (requires { job->on_certificate_requested; }) {
job->on_certificate_requested = [&](auto&) {
self->did_request_certificates();
};
}
}
template<typename TBadgedProtocol, typename TPipeResult>
OwnPtr<Download> start_download(TBadgedProtocol&& protocol, ClientConnection& client, const String& method, const URL& url, const HashMap<String, String>& headers, ReadonlyBytes body, TPipeResult&& pipe_result)
{

View file

@ -25,7 +25,7 @@
*/
#include <LibHTTP/HttpJob.h>
#include <LibHTTP/HttpResponse.h>
#include <ProtocolServer/HttpCommon.h>
#include <ProtocolServer/HttpDownload.h>
#include <ProtocolServer/HttpProtocol.h>
@ -35,29 +35,7 @@ HttpDownload::HttpDownload(ClientConnection& client, NonnullRefPtr<HTTP::HttpJob
: Download(client, move(output_stream))
, m_job(job)
{
m_job->on_headers_received = [this](auto& headers, auto response_code) {
if (response_code.has_value())
set_status_code(response_code.value());
set_response_headers(headers);
};
m_job->on_finish = [this](bool success) {
if (auto* response = m_job->response()) {
set_status_code(response->code());
set_response_headers(response->headers());
set_downloaded_size(this->output_stream().size());
}
// if we didn't know the total size, pretend that the download finished successfully
// and set the total size to the downloaded size
if (!total_size().has_value())
did_progress(downloaded_size(), downloaded_size());
did_finish(success);
};
m_job->on_progress = [this](Optional<u32> total, u32 current) {
did_progress(total, current);
};
Detail::init(this, job);
}
HttpDownload::~HttpDownload()

View file

@ -24,8 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <LibHTTP/HttpResponse.h>
#include <LibHTTP/HttpsJob.h>
#include <ProtocolServer/HttpCommon.h>
#include <ProtocolServer/HttpsDownload.h>
#include <ProtocolServer/HttpsProtocol.h>
@ -35,32 +35,7 @@ HttpsDownload::HttpsDownload(ClientConnection& client, NonnullRefPtr<HTTP::Https
: Download(client, move(output_stream))
, m_job(job)
{
m_job->on_headers_received = [this](auto& headers, auto response_code) {
if (response_code.has_value())
set_status_code(response_code.value());
set_response_headers(headers);
};
m_job->on_finish = [this](bool success) {
if (auto* response = m_job->response()) {
set_status_code(response->code());
set_response_headers(response->headers());
set_downloaded_size(this->output_stream().size());
}
// if we didn't know the total size, pretend that the download finished successfully
// and set the total size to the downloaded size
if (!total_size().has_value())
did_progress(downloaded_size(), downloaded_size());
did_finish(success);
};
m_job->on_progress = [this](Optional<u32> total, u32 current) {
did_progress(total, current);
};
m_job->on_certificate_requested = [this](auto&) {
did_request_certificates();
};
Detail::init(this, job);
}
void HttpsDownload::set_certificate(String certificate, String key)