1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:18:11 +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/GApplication.h>
#include <LibGUI/GHttpRequest.h> #include <LibCore/CHttpRequest.h>
#include <LibGUI/GHttpResponse.h> #include <LibCore/CHttpResponse.h>
#include <LibGUI/GNetworkJob.h> #include <LibCore/CNetworkJob.h>
#include <stdio.h> #include <stdio.h>
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
GApplication app(argc, argv); GApplication app(argc, argv);
GHttpRequest request; CHttpRequest request;
request.set_hostname("www.google.com"); request.set_hostname("www.google.com");
request.set_path("/"); request.set_path("/");
@ -18,7 +18,7 @@ int main(int argc, char** argv)
dbgprintf("on_finish: request failed :(\n"); dbgprintf("on_finish: request failed :(\n");
return; 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("%s{%p}: on_receive: code=%d\n", job->class_name(), job, response.code());
//printf("payload:\n"); //printf("payload:\n");
//printf("%s", response.payload().pointer()); //printf("%s", response.payload().pointer());

View file

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

View file

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

View file

@ -1,24 +1,23 @@
#include <LibGUI/GHttpRequest.h> #include <LibCore/CHttpRequest.h>
#include <LibGUI/GHttpJob.h> #include <LibCore/CHttpJob.h>
#include <LibGUI/GEventLoop.h>
#include <AK/StringBuilder.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(); job->start();
return job; return job;
} }
String GHttpRequest::method_name() const String CHttpRequest::method_name() const
{ {
switch (m_method) { switch (m_method) {
case Method::GET: 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; StringBuilder builder;
builder.append(method_name()); builder.append(method_name());

View file

@ -2,14 +2,14 @@
#include <AK/AKString.h> #include <AK/AKString.h>
class GNetworkJob; class CNetworkJob;
class GHttpRequest { class CHttpRequest {
public: public:
enum Method { Invalid, HEAD, GET, POST }; enum Method { Invalid, HEAD, GET, POST };
GHttpRequest(); CHttpRequest();
~GHttpRequest(); ~CHttpRequest();
String hostname() const { return m_hostname; } String hostname() const { return m_hostname; }
int port() const { return m_port; } int port() const { return m_port; }
@ -24,7 +24,7 @@ public:
String method_name() const; String method_name() const;
ByteBuffer to_raw_request() const; ByteBuffer to_raw_request() const;
GNetworkJob* schedule(); CNetworkJob* schedule();
private: private:
String m_hostname; 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 #pragma once
#include <LibGUI/GNetworkResponse.h> #include <LibCore/CNetworkResponse.h>
#include <AK/AKString.h> #include <AK/AKString.h>
#include <AK/HashMap.h> #include <AK/HashMap.h>
class GHttpResponse : public GNetworkResponse { class CHttpResponse : public CNetworkResponse {
public: public:
virtual ~GHttpResponse() override; virtual ~CHttpResponse() override;
static Retained<GHttpResponse> create(int code, HashMap<String, String>&& headers, ByteBuffer&& payload) 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; } int code() const { return m_code; }
const HashMap<String, String>& headers() const { return m_headers; } const HashMap<String, String>& headers() const { return m_headers; }
private: private:
GHttpResponse(int code, HashMap<String, String>&&, ByteBuffer&&); CHttpResponse(int code, HashMap<String, String>&&, ByteBuffer&&);
int m_code { 0 }; int m_code { 0 };
HashMap<String, String> m_headers; HashMap<String, String> m_headers;

View file

@ -1,16 +1,16 @@
#include <LibGUI/GNetworkJob.h> #include <LibCore/CNetworkJob.h>
#include <LibGUI/GNetworkResponse.h> #include <LibCore/CNetworkResponse.h>
#include <stdio.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); m_response = move(response);
printf("%s{%p} job did_finish!\n", class_name(), this); printf("%s{%p} job did_finish!\n", class_name(), this);
@ -18,7 +18,7 @@ void GNetworkJob::did_finish(Retained<GNetworkResponse>&& response)
on_finish(true); on_finish(true);
} }
void GNetworkJob::did_fail(Error error) void CNetworkJob::did_fail(Error error)
{ {
m_error = error; m_error = error;
dbgprintf("%s{%p} job did_fail! error=%u\n", class_name(), this, (unsigned)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 <LibCore/CObject.h>
#include <AK/Function.h> #include <AK/Function.h>
class GNetworkResponse; class CNetworkResponse;
class GNetworkJob : public CObject { class CNetworkJob : public CObject {
public: public:
enum class Error { enum class Error {
None, None,
@ -13,25 +13,25 @@ public:
TransmissionFailed, TransmissionFailed,
ProtocolFailed, ProtocolFailed,
}; };
virtual ~GNetworkJob() override; virtual ~CNetworkJob() override;
Function<void(bool success)> on_finish; Function<void(bool success)> on_finish;
bool has_error() const { return m_error != Error::None; } bool has_error() const { return m_error != Error::None; }
Error error() const { return m_error; } Error error() const { return m_error; }
GNetworkResponse* response() { return m_response.ptr(); } CNetworkResponse* response() { return m_response.ptr(); }
const GNetworkResponse* response() const { return m_response.ptr(); } const CNetworkResponse* response() const { return m_response.ptr(); }
virtual void start() = 0; virtual void start() = 0;
virtual const char* class_name() const override { return "GNetworkJob"; } virtual const char* class_name() const override { return "CNetworkJob"; }
protected: protected:
GNetworkJob(); CNetworkJob();
void did_finish(Retained<GNetworkResponse>&&); void did_finish(Retained<CNetworkResponse>&&);
void did_fail(Error); void did_fail(Error);
private: private:
RetainPtr<GNetworkResponse> m_response; RetainPtr<CNetworkResponse> m_response;
Error m_error { Error::None }; 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/Retainable.h>
#include <AK/ByteBuffer.h> #include <AK/ByteBuffer.h>
class GNetworkResponse : public Retainable<GNetworkResponse> { class CNetworkResponse : public Retainable<CNetworkResponse> {
public: public:
virtual ~GNetworkResponse(); virtual ~CNetworkResponse();
bool is_error() const { return m_error; } bool is_error() const { return m_error; }
const ByteBuffer& payload() const { return m_payload; } const ByteBuffer& payload() const { return m_payload; }
protected: protected:
explicit GNetworkResponse(ByteBuffer&&); explicit CNetworkResponse(ByteBuffer&&);
bool m_error { false }; bool m_error { false };
ByteBuffer m_payload; ByteBuffer m_payload;

View file

@ -5,6 +5,11 @@ OBJS = \
CTCPSocket.o \ CTCPSocket.o \
CElapsedTimer.o \ CElapsedTimer.o \
CNotifier.o \ CNotifier.o \
CHttpRequest.o \
CHttpResponse.o \
CHttpJob.o \
CNetworkJob.o \
CNetworkResponse.o \
CObject.o \ CObject.o \
CEventLoop.o \ CEventLoop.o \
CEvent.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 \ GFileSystemModel.o \
GSplitter.o \ GSplitter.o \
GTimer.o \ GTimer.o \
GNetworkJob.o \
GNetworkResponse.o \
GHttpRequest.o \
GHttpResponse.o \
GHttpJob.o \
GSpinBox.o \ GSpinBox.o \
GGroupBox.o \ GGroupBox.o \
GWindow.o GWindow.o