1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:48:10 +00:00

LibCore: Move HTTP classes from LibGUI to LibCore.

This commit is contained in:
Andreas Kling 2019-04-10 22:28:10 +02:00
parent cfd6e6cc36
commit ab1c84cf53
15 changed files with 92 additions and 93 deletions

View file

@ -1,14 +1,14 @@
#include <LibGUI/GApplication.h>
#include <LibGUI/GHttpRequest.h>
#include <LibGUI/GHttpResponse.h>
#include <LibGUI/GNetworkJob.h>
#include <LibCore/CHttpRequest.h>
#include <LibCore/CHttpResponse.h>
#include <LibCore/CNetworkJob.h>
#include <stdio.h>
int main(int argc, char** argv)
{
GApplication app(argc, argv);
GHttpRequest request;
CHttpRequest request;
request.set_hostname("www.google.com");
request.set_path("/");
@ -18,7 +18,7 @@ int main(int argc, char** argv)
dbgprintf("on_finish: request failed :(\n");
return;
}
auto& response = static_cast<const GHttpResponse&>(*job->response());
auto& response = static_cast<const CHttpResponse&>(*job->response());
printf("%s{%p}: on_receive: code=%d\n", job->class_name(), job, response.code());
//printf("payload:\n");
//printf("%s", response.payload().pointer());

View file

@ -1,19 +1,19 @@
#include <LibGUI/GHttpJob.h>
#include <LibGUI/GHttpResponse.h>
#include <LibCore/CHttpJob.h>
#include <LibCore/CHttpResponse.h>
#include <LibCore/CTCPSocket.h>
#include <stdio.h>
#include <unistd.h>
GHttpJob::GHttpJob(const GHttpRequest& request)
CHttpJob::CHttpJob(const CHttpRequest& request)
: m_request(request)
{
}
GHttpJob::~GHttpJob()
CHttpJob::~CHttpJob()
{
}
void GHttpJob::on_socket_connected()
void CHttpJob::on_socket_connected()
{
auto raw_request = m_request.to_raw_request();
#if 0
@ -22,7 +22,7 @@ void GHttpJob::on_socket_connected()
bool success = m_socket->send(raw_request);
if (!success)
return deferred_invoke([this](auto&){ did_fail(GNetworkJob::Error::TransmissionFailed); });
return deferred_invoke([this](auto&){ did_fail(CNetworkJob::Error::TransmissionFailed); });
Vector<byte> buffer;
while (m_socket->is_connected()) {
@ -33,18 +33,18 @@ void GHttpJob::on_socket_connected()
auto line = m_socket->read_line(PAGE_SIZE);
if (line.is_null()) {
printf("Expected HTTP status\n");
return deferred_invoke([this](auto&){ did_fail(GNetworkJob::Error::TransmissionFailed); });
return deferred_invoke([this](auto&){ did_fail(CNetworkJob::Error::TransmissionFailed); });
}
auto parts = String::from_byte_buffer(line, Chomp).split(' ');
if (parts.size() < 3) {
printf("Expected 3-part HTTP status, got '%s'\n", line.pointer());
return deferred_invoke([this](auto&){ did_fail(GNetworkJob::Error::ProtocolFailed); });
return deferred_invoke([this](auto&){ did_fail(CNetworkJob::Error::ProtocolFailed); });
}
bool ok;
m_code = parts[1].to_uint(ok);
if (!ok) {
printf("Expected numeric HTTP status\n");
return deferred_invoke([this](auto&){ did_fail(GNetworkJob::Error::ProtocolFailed); });
return deferred_invoke([this](auto&){ did_fail(CNetworkJob::Error::ProtocolFailed); });
}
m_state = State::InHeaders;
continue;
@ -55,7 +55,7 @@ void GHttpJob::on_socket_connected()
auto line = m_socket->read_line(PAGE_SIZE);
if (line.is_null()) {
printf("Expected HTTP header\n");
return did_fail(GNetworkJob::Error::ProtocolFailed);
return did_fail(CNetworkJob::Error::ProtocolFailed);
}
auto chomped_line = String::from_byte_buffer(line, Chomp);
if (chomped_line.is_empty()) {
@ -65,12 +65,12 @@ void GHttpJob::on_socket_connected()
auto parts = chomped_line.split(':');
if (parts.is_empty()) {
printf("Expected HTTP header with key/value\n");
return deferred_invoke([this](auto&){ did_fail(GNetworkJob::Error::ProtocolFailed); });
return deferred_invoke([this](auto&){ did_fail(CNetworkJob::Error::ProtocolFailed); });
}
auto name = parts[0];
if (chomped_line.length() < name.length() + 2) {
printf("Malformed HTTP header: '%s' (%d)\n", chomped_line.characters(), chomped_line.length());
return deferred_invoke([this](auto&){ did_fail(GNetworkJob::Error::ProtocolFailed); });
return deferred_invoke([this](auto&){ did_fail(CNetworkJob::Error::ProtocolFailed); });
}
auto value = chomped_line.substring(name.length() + 2, chomped_line.length() - name.length() - 2);
m_headers.set(name, value);
@ -84,18 +84,18 @@ void GHttpJob::on_socket_connected()
m_state = State::Finished;
break;
}
return deferred_invoke([this](auto&){ did_fail(GNetworkJob::Error::ProtocolFailed); });
return deferred_invoke([this](auto&){ did_fail(CNetworkJob::Error::ProtocolFailed); });
}
buffer.append(payload.pointer(), payload.size());
}
auto response = GHttpResponse::create(m_code, move(m_headers), ByteBuffer::copy(buffer.data(), buffer.size()));
auto response = CHttpResponse::create(m_code, move(m_headers), ByteBuffer::copy(buffer.data(), buffer.size()));
deferred_invoke([this, response] (auto&) {
did_finish(move(response));
});
}
void GHttpJob::start()
void CHttpJob::start()
{
ASSERT(!m_socket);
m_socket = new CTCPSocket(this);
@ -105,5 +105,5 @@ void GHttpJob::start()
};
bool success = m_socket->connect(m_request.hostname(), m_request.port());
if (!success)
return did_fail(GNetworkJob::Error::ConnectionFailed);
return did_fail(CNetworkJob::Error::ConnectionFailed);
}

View file

@ -1,19 +1,19 @@
#pragma once
#include <LibGUI/GNetworkJob.h>
#include <LibGUI/GHttpRequest.h>
#include <LibCore/CNetworkJob.h>
#include <LibCore/CHttpRequest.h>
#include <AK/HashMap.h>
class CTCPSocket;
class GHttpJob final : public GNetworkJob {
class CHttpJob final : public CNetworkJob {
public:
explicit GHttpJob(const GHttpRequest&);
virtual ~GHttpJob() override;
explicit CHttpJob(const CHttpRequest&);
virtual ~CHttpJob() override;
virtual void start() override;
virtual const char* class_name() const override { return "GHttpJob"; }
virtual const char* class_name() const override { return "CHttpJob"; }
private:
void on_socket_connected();
@ -25,7 +25,7 @@ private:
Finished,
};
GHttpRequest m_request;
CHttpRequest m_request;
CTCPSocket* m_socket { nullptr };
State m_state { State::InStatus };
int m_code { -1 };

View file

@ -1,24 +1,23 @@
#include <LibGUI/GHttpRequest.h>
#include <LibGUI/GHttpJob.h>
#include <LibGUI/GEventLoop.h>
#include <LibCore/CHttpRequest.h>
#include <LibCore/CHttpJob.h>
#include <AK/StringBuilder.h>
GHttpRequest::GHttpRequest()
CHttpRequest::CHttpRequest()
{
}
GHttpRequest::~GHttpRequest()
CHttpRequest::~CHttpRequest()
{
}
GNetworkJob* GHttpRequest::schedule()
CNetworkJob* CHttpRequest::schedule()
{
auto* job = new GHttpJob(*this);
auto* job = new CHttpJob(*this);
job->start();
return job;
}
String GHttpRequest::method_name() const
String CHttpRequest::method_name() const
{
switch (m_method) {
case Method::GET:
@ -32,7 +31,7 @@ String GHttpRequest::method_name() const
}
}
ByteBuffer GHttpRequest::to_raw_request() const
ByteBuffer CHttpRequest::to_raw_request() const
{
StringBuilder builder;
builder.append(method_name());

View file

@ -2,14 +2,14 @@
#include <AK/AKString.h>
class GNetworkJob;
class CNetworkJob;
class GHttpRequest {
class CHttpRequest {
public:
enum Method { Invalid, HEAD, GET, POST };
GHttpRequest();
~GHttpRequest();
CHttpRequest();
~CHttpRequest();
String hostname() const { return m_hostname; }
int port() const { return m_port; }
@ -24,7 +24,7 @@ public:
String method_name() const;
ByteBuffer to_raw_request() const;
GNetworkJob* schedule();
CNetworkJob* schedule();
private:
String m_hostname;

12
LibCore/CHttpResponse.cpp Normal file
View file

@ -0,0 +1,12 @@
#include <LibCore/CHttpResponse.h>
CHttpResponse::CHttpResponse(int code, HashMap<String, String>&& headers, ByteBuffer&& payload)
: CNetworkResponse(move(payload))
, m_code(code)
, m_headers(move(headers))
{
}
CHttpResponse::~CHttpResponse()
{
}

View file

@ -1,22 +1,22 @@
#pragma once
#include <LibGUI/GNetworkResponse.h>
#include <LibCore/CNetworkResponse.h>
#include <AK/AKString.h>
#include <AK/HashMap.h>
class GHttpResponse : public GNetworkResponse {
class CHttpResponse : public CNetworkResponse {
public:
virtual ~GHttpResponse() override;
static Retained<GHttpResponse> create(int code, HashMap<String, String>&& headers, ByteBuffer&& payload)
virtual ~CHttpResponse() override;
static Retained<CHttpResponse> create(int code, HashMap<String, String>&& headers, ByteBuffer&& payload)
{
return adopt(*new GHttpResponse(code, move(headers), move(payload)));
return adopt(*new CHttpResponse(code, move(headers), move(payload)));
}
int code() const { return m_code; }
const HashMap<String, String>& headers() const { return m_headers; }
private:
GHttpResponse(int code, HashMap<String, String>&&, ByteBuffer&&);
CHttpResponse(int code, HashMap<String, String>&&, ByteBuffer&&);
int m_code { 0 };
HashMap<String, String> m_headers;

View file

@ -1,16 +1,16 @@
#include <LibGUI/GNetworkJob.h>
#include <LibGUI/GNetworkResponse.h>
#include <LibCore/CNetworkJob.h>
#include <LibCore/CNetworkResponse.h>
#include <stdio.h>
GNetworkJob::GNetworkJob()
CNetworkJob::CNetworkJob()
{
}
GNetworkJob::~GNetworkJob()
CNetworkJob::~CNetworkJob()
{
}
void GNetworkJob::did_finish(Retained<GNetworkResponse>&& response)
void CNetworkJob::did_finish(Retained<CNetworkResponse>&& response)
{
m_response = move(response);
printf("%s{%p} job did_finish!\n", class_name(), this);
@ -18,7 +18,7 @@ void GNetworkJob::did_finish(Retained<GNetworkResponse>&& response)
on_finish(true);
}
void GNetworkJob::did_fail(Error error)
void CNetworkJob::did_fail(Error error)
{
m_error = error;
dbgprintf("%s{%p} job did_fail! error=%u\n", class_name(), this, (unsigned)error);

View file

@ -3,9 +3,9 @@
#include <LibCore/CObject.h>
#include <AK/Function.h>
class GNetworkResponse;
class CNetworkResponse;
class GNetworkJob : public CObject {
class CNetworkJob : public CObject {
public:
enum class Error {
None,
@ -13,25 +13,25 @@ public:
TransmissionFailed,
ProtocolFailed,
};
virtual ~GNetworkJob() override;
virtual ~CNetworkJob() override;
Function<void(bool success)> on_finish;
bool has_error() const { return m_error != Error::None; }
Error error() const { return m_error; }
GNetworkResponse* response() { return m_response.ptr(); }
const GNetworkResponse* response() const { return m_response.ptr(); }
CNetworkResponse* response() { return m_response.ptr(); }
const CNetworkResponse* response() const { return m_response.ptr(); }
virtual void start() = 0;
virtual const char* class_name() const override { return "GNetworkJob"; }
virtual const char* class_name() const override { return "CNetworkJob"; }
protected:
GNetworkJob();
void did_finish(Retained<GNetworkResponse>&&);
CNetworkJob();
void did_finish(Retained<CNetworkResponse>&&);
void did_fail(Error);
private:
RetainPtr<GNetworkResponse> m_response;
RetainPtr<CNetworkResponse> m_response;
Error m_error { Error::None };
};

View file

@ -0,0 +1,10 @@
#include <LibCore/CNetworkResponse.h>
CNetworkResponse::CNetworkResponse(ByteBuffer&& payload)
: m_payload(payload)
{
}
CNetworkResponse::~CNetworkResponse()
{
}

View file

@ -3,15 +3,15 @@
#include <AK/Retainable.h>
#include <AK/ByteBuffer.h>
class GNetworkResponse : public Retainable<GNetworkResponse> {
class CNetworkResponse : public Retainable<CNetworkResponse> {
public:
virtual ~GNetworkResponse();
virtual ~CNetworkResponse();
bool is_error() const { return m_error; }
const ByteBuffer& payload() const { return m_payload; }
protected:
explicit GNetworkResponse(ByteBuffer&&);
explicit CNetworkResponse(ByteBuffer&&);
bool m_error { false };
ByteBuffer m_payload;

View file

@ -5,6 +5,11 @@ OBJS = \
CTCPSocket.o \
CElapsedTimer.o \
CNotifier.o \
CHttpRequest.o \
CHttpResponse.o \
CHttpJob.o \
CNetworkJob.o \
CNetworkResponse.o \
CObject.o \
CEventLoop.o \
CEvent.o

View file

@ -1,12 +0,0 @@
#include <LibGUI/GHttpResponse.h>
GHttpResponse::GHttpResponse(int code, HashMap<String, String>&& headers, ByteBuffer&& payload)
: GNetworkResponse(move(payload))
, m_code(code)
, m_headers(move(headers))
{
}
GHttpResponse::~GHttpResponse()
{
}

View file

@ -1,10 +0,0 @@
#include <LibGUI/GNetworkResponse.h>
GNetworkResponse::GNetworkResponse(ByteBuffer&& payload)
: m_payload(payload)
{
}
GNetworkResponse::~GNetworkResponse()
{
}

View file

@ -50,11 +50,6 @@ LIBGUI_OBJS = \
GFileSystemModel.o \
GSplitter.o \
GTimer.o \
GNetworkJob.o \
GNetworkResponse.o \
GHttpRequest.o \
GHttpResponse.o \
GHttpJob.o \
GSpinBox.o \
GGroupBox.o \
GWindow.o