mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 14:57:35 +00:00
LibCore+LibHTTP: Move out the HTTP handler and add HTTPS
This commit is contained in:
parent
8d20a526e5
commit
7670e5ccf0
27 changed files with 613 additions and 70 deletions
|
@ -36,9 +36,6 @@ class ElapsedTime;
|
|||
class Event;
|
||||
class EventLoop;
|
||||
class File;
|
||||
class HttpJob;
|
||||
class HttpRequest;
|
||||
class HttpResponse;
|
||||
class IODevice;
|
||||
class LocalServer;
|
||||
class LocalSocket;
|
||||
|
|
|
@ -1,216 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <LibCore/Gzip.h>
|
||||
#include <LibCore/HttpJob.h>
|
||||
#include <LibCore/HttpResponse.h>
|
||||
#include <LibCore/TCPSocket.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//#define CHTTPJOB_DEBUG
|
||||
|
||||
namespace Core {
|
||||
|
||||
static ByteBuffer handle_content_encoding(const ByteBuffer& buf, const String& content_encoding)
|
||||
{
|
||||
#ifdef CHTTPJOB_DEBUG
|
||||
dbg() << "HttpJob::handle_content_encoding: buf has content_encoding = " << content_encoding;
|
||||
#endif
|
||||
|
||||
if (content_encoding == "gzip") {
|
||||
if (!Gzip::is_compressed(buf)) {
|
||||
dbg() << "HttpJob::handle_content_encoding: buf is not gzip compressed!";
|
||||
}
|
||||
|
||||
#ifdef CHTTPJOB_DEBUG
|
||||
dbg() << "HttpJob::handle_content_encoding: buf is gzip compressed!";
|
||||
#endif
|
||||
|
||||
auto uncompressed = Gzip::decompress(buf);
|
||||
if (!uncompressed.has_value()) {
|
||||
dbg() << "HttpJob::handle_content_encoding: Gzip::decompress() failed. Returning original buffer.";
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifdef CHTTPJOB_DEBUG
|
||||
dbg() << "HttpJob::handle_content_encoding: Gzip::decompress() successful.\n"
|
||||
<< " Input size = " << buf.size() << "\n"
|
||||
<< " Output size = " << uncompressed.value().size();
|
||||
#endif
|
||||
|
||||
return uncompressed.value();
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
HttpJob::HttpJob(const HttpRequest& request)
|
||||
: m_request(request)
|
||||
{
|
||||
}
|
||||
|
||||
HttpJob::~HttpJob()
|
||||
{
|
||||
}
|
||||
|
||||
void HttpJob::on_socket_connected()
|
||||
{
|
||||
auto raw_request = m_request.to_raw_request();
|
||||
#if 0
|
||||
dbg() << "HttpJob: raw_request:";
|
||||
dbg() << String::copy(raw_request).characters();
|
||||
#endif
|
||||
|
||||
bool success = m_socket->send(raw_request);
|
||||
if (!success)
|
||||
return deferred_invoke([this](auto&) { did_fail(NetworkJob::Error::TransmissionFailed); });
|
||||
|
||||
m_socket->on_ready_to_read = [&] {
|
||||
if (is_cancelled())
|
||||
return;
|
||||
if (m_state == State::InStatus) {
|
||||
if (!m_socket->can_read_line())
|
||||
return;
|
||||
auto line = m_socket->read_line(PAGE_SIZE);
|
||||
if (line.is_null()) {
|
||||
fprintf(stderr, "HttpJob: Expected HTTP status\n");
|
||||
return deferred_invoke([this](auto&) { did_fail(NetworkJob::Error::TransmissionFailed); });
|
||||
}
|
||||
auto parts = String::copy(line, Chomp).split(' ');
|
||||
if (parts.size() < 3) {
|
||||
fprintf(stderr, "HttpJob: Expected 3-part HTTP status, got '%s'\n", line.data());
|
||||
return deferred_invoke([this](auto&) { did_fail(NetworkJob::Error::ProtocolFailed); });
|
||||
}
|
||||
bool ok;
|
||||
m_code = parts[1].to_uint(ok);
|
||||
if (!ok) {
|
||||
fprintf(stderr, "HttpJob: Expected numeric HTTP status\n");
|
||||
return deferred_invoke([this](auto&) { did_fail(NetworkJob::Error::ProtocolFailed); });
|
||||
}
|
||||
m_state = State::InHeaders;
|
||||
return;
|
||||
}
|
||||
if (m_state == State::InHeaders) {
|
||||
if (!m_socket->can_read_line())
|
||||
return;
|
||||
auto line = m_socket->read_line(PAGE_SIZE);
|
||||
if (line.is_null()) {
|
||||
fprintf(stderr, "HttpJob: Expected HTTP header\n");
|
||||
return did_fail(NetworkJob::Error::ProtocolFailed);
|
||||
}
|
||||
auto chomped_line = String::copy(line, Chomp);
|
||||
if (chomped_line.is_empty()) {
|
||||
m_state = State::InBody;
|
||||
return;
|
||||
}
|
||||
auto parts = chomped_line.split(':');
|
||||
if (parts.is_empty()) {
|
||||
fprintf(stderr, "HttpJob: Expected HTTP header with key/value\n");
|
||||
return deferred_invoke([this](auto&) { did_fail(NetworkJob::Error::ProtocolFailed); });
|
||||
}
|
||||
auto name = parts[0];
|
||||
if (chomped_line.length() < name.length() + 2) {
|
||||
fprintf(stderr, "HttpJob: Malformed HTTP header: '%s' (%zu)\n", chomped_line.characters(), chomped_line.length());
|
||||
return deferred_invoke([this](auto&) { did_fail(NetworkJob::Error::ProtocolFailed); });
|
||||
}
|
||||
auto value = chomped_line.substring(name.length() + 2, chomped_line.length() - name.length() - 2);
|
||||
m_headers.set(name, value);
|
||||
#ifdef CHTTPJOB_DEBUG
|
||||
dbg() << "HttpJob: [" << name << "] = '" << value << "'";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
ASSERT(m_state == State::InBody);
|
||||
ASSERT(m_socket->can_read());
|
||||
auto payload = m_socket->receive(64 * KB);
|
||||
if (!payload) {
|
||||
if (m_socket->eof())
|
||||
return finish_up();
|
||||
return deferred_invoke([this](auto&) { did_fail(NetworkJob::Error::ProtocolFailed); });
|
||||
}
|
||||
m_received_buffers.append(payload);
|
||||
m_received_size += payload.size();
|
||||
|
||||
auto content_length_header = m_headers.get("Content-Length");
|
||||
if (content_length_header.has_value()) {
|
||||
bool ok;
|
||||
if (m_received_size >= content_length_header.value().to_uint(ok) && ok)
|
||||
return finish_up();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void HttpJob::finish_up()
|
||||
{
|
||||
m_state = State::Finished;
|
||||
auto flattened_buffer = ByteBuffer::create_uninitialized(m_received_size);
|
||||
u8* flat_ptr = flattened_buffer.data();
|
||||
for (auto& received_buffer : m_received_buffers) {
|
||||
memcpy(flat_ptr, received_buffer.data(), received_buffer.size());
|
||||
flat_ptr += received_buffer.size();
|
||||
}
|
||||
m_received_buffers.clear();
|
||||
|
||||
auto content_encoding = m_headers.get("Content-Encoding");
|
||||
if (content_encoding.has_value()) {
|
||||
flattened_buffer = handle_content_encoding(flattened_buffer, content_encoding.value());
|
||||
}
|
||||
|
||||
auto response = HttpResponse::create(m_code, move(m_headers), move(flattened_buffer));
|
||||
deferred_invoke([this, response](auto&) {
|
||||
did_finish(move(response));
|
||||
});
|
||||
}
|
||||
|
||||
void HttpJob::start()
|
||||
{
|
||||
ASSERT(!m_socket);
|
||||
m_socket = TCPSocket::construct(this);
|
||||
m_socket->on_connected = [this] {
|
||||
#ifdef CHTTPJOB_DEBUG
|
||||
dbg() << "HttpJob: on_connected callback";
|
||||
#endif
|
||||
on_socket_connected();
|
||||
};
|
||||
bool success = m_socket->connect(m_request.url().host(), m_request.url().port());
|
||||
if (!success) {
|
||||
deferred_invoke([this](auto&) {
|
||||
return did_fail(NetworkJob::Error::ConnectionFailed);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void HttpJob::shutdown()
|
||||
{
|
||||
if (!m_socket)
|
||||
return;
|
||||
m_socket->on_ready_to_read = nullptr;
|
||||
m_socket->on_connected = nullptr;
|
||||
remove_child(*m_socket);
|
||||
m_socket = nullptr;
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/HashMap.h>
|
||||
#include <LibCore/HttpRequest.h>
|
||||
#include <LibCore/HttpResponse.h>
|
||||
#include <LibCore/NetworkJob.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class HttpJob final : public NetworkJob {
|
||||
C_OBJECT(HttpJob)
|
||||
public:
|
||||
explicit HttpJob(const HttpRequest&);
|
||||
virtual ~HttpJob() override;
|
||||
|
||||
virtual void start() override;
|
||||
virtual void shutdown() override;
|
||||
|
||||
HttpResponse* response() { return static_cast<HttpResponse*>(NetworkJob::response()); }
|
||||
const HttpResponse* response() const { return static_cast<const HttpResponse*>(NetworkJob::response()); }
|
||||
|
||||
private:
|
||||
void on_socket_connected();
|
||||
void finish_up();
|
||||
|
||||
enum class State {
|
||||
InStatus,
|
||||
InHeaders,
|
||||
InBody,
|
||||
Finished,
|
||||
};
|
||||
|
||||
HttpRequest m_request;
|
||||
RefPtr<TCPSocket> m_socket;
|
||||
State m_state { State::InStatus };
|
||||
int m_code { -1 };
|
||||
HashMap<String, String> m_headers;
|
||||
Vector<ByteBuffer> m_received_buffers;
|
||||
size_t m_received_size { 0 };
|
||||
};
|
||||
|
||||
}
|
|
@ -1,180 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibCore/HttpJob.h>
|
||||
#include <LibCore/HttpRequest.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
HttpRequest::HttpRequest()
|
||||
{
|
||||
}
|
||||
|
||||
HttpRequest::~HttpRequest()
|
||||
{
|
||||
}
|
||||
|
||||
RefPtr<NetworkJob> HttpRequest::schedule()
|
||||
{
|
||||
auto job = HttpJob::construct(*this);
|
||||
job->start();
|
||||
return job;
|
||||
}
|
||||
|
||||
String HttpRequest::method_name() const
|
||||
{
|
||||
switch (m_method) {
|
||||
case Method::GET:
|
||||
return "GET";
|
||||
case Method::HEAD:
|
||||
return "HEAD";
|
||||
case Method::POST:
|
||||
return "POST";
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
ByteBuffer HttpRequest::to_raw_request() const
|
||||
{
|
||||
StringBuilder builder;
|
||||
builder.append(method_name());
|
||||
builder.append(' ');
|
||||
builder.append(m_url.path());
|
||||
builder.append(" HTTP/1.0\r\nHost: ");
|
||||
builder.append(m_url.host());
|
||||
builder.append("\r\n\r\n");
|
||||
return builder.to_byte_buffer();
|
||||
}
|
||||
|
||||
Optional<HttpRequest> HttpRequest::from_raw_request(const ByteBuffer& raw_request)
|
||||
{
|
||||
enum class State {
|
||||
InMethod,
|
||||
InResource,
|
||||
InProtocol,
|
||||
InHeaderName,
|
||||
InHeaderValue,
|
||||
};
|
||||
|
||||
State state { State::InMethod };
|
||||
size_t index = 0;
|
||||
|
||||
auto peek = [&](int offset = 0) -> u8 {
|
||||
if (index + offset >= raw_request.size())
|
||||
return 0;
|
||||
return raw_request[index + offset];
|
||||
};
|
||||
|
||||
auto consume = [&]() -> u8 {
|
||||
ASSERT(index < raw_request.size());
|
||||
return raw_request[index++];
|
||||
};
|
||||
|
||||
Vector<u8, 256> buffer;
|
||||
|
||||
String method;
|
||||
String resource;
|
||||
String protocol;
|
||||
Vector<Header> headers;
|
||||
Header current_header;
|
||||
|
||||
auto commit_and_advance_to = [&](auto& output, State new_state) {
|
||||
output = String::copy(buffer);
|
||||
buffer.clear();
|
||||
state = new_state;
|
||||
};
|
||||
|
||||
while (index < raw_request.size()) {
|
||||
// FIXME: Figure out what the appropriate limitations should be.
|
||||
if (buffer.size() > 65536)
|
||||
return {};
|
||||
switch (state) {
|
||||
case State::InMethod:
|
||||
if (peek() == ' ') {
|
||||
consume();
|
||||
commit_and_advance_to(method, State::InResource);
|
||||
break;
|
||||
}
|
||||
buffer.append(consume());
|
||||
break;
|
||||
case State::InResource:
|
||||
if (peek() == ' ') {
|
||||
consume();
|
||||
commit_and_advance_to(resource, State::InProtocol);
|
||||
break;
|
||||
}
|
||||
buffer.append(consume());
|
||||
break;
|
||||
case State::InProtocol:
|
||||
if (peek(0) == '\r' && peek(1) == '\n') {
|
||||
consume();
|
||||
consume();
|
||||
commit_and_advance_to(protocol, State::InHeaderName);
|
||||
break;
|
||||
}
|
||||
buffer.append(consume());
|
||||
break;
|
||||
case State::InHeaderName:
|
||||
if (peek(0) == ':' && peek(1) == ' ') {
|
||||
consume();
|
||||
consume();
|
||||
commit_and_advance_to(current_header.name, State::InHeaderValue);
|
||||
break;
|
||||
}
|
||||
buffer.append(consume());
|
||||
break;
|
||||
case State::InHeaderValue:
|
||||
if (peek(0) == '\r' && peek(1) == '\n') {
|
||||
consume();
|
||||
consume();
|
||||
commit_and_advance_to(current_header.value, State::InHeaderName);
|
||||
headers.append(move(current_header));
|
||||
break;
|
||||
}
|
||||
buffer.append(consume());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HttpRequest request;
|
||||
if (method == "GET")
|
||||
request.m_method = Method::GET;
|
||||
else if (method == "HEAD")
|
||||
request.m_method = Method::HEAD;
|
||||
else if (method == "POST")
|
||||
request.m_method = Method::POST;
|
||||
else
|
||||
return {};
|
||||
|
||||
request.m_resource = resource;
|
||||
request.m_headers = move(headers);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/URL.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibCore/Forward.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class HttpRequest {
|
||||
public:
|
||||
enum Method {
|
||||
Invalid,
|
||||
HEAD,
|
||||
GET,
|
||||
POST
|
||||
};
|
||||
|
||||
struct Header {
|
||||
String name;
|
||||
String value;
|
||||
};
|
||||
|
||||
HttpRequest();
|
||||
~HttpRequest();
|
||||
|
||||
const String& resource() const { return m_resource; }
|
||||
const Vector<Header>& headers() const { return m_headers; }
|
||||
|
||||
const URL& url() const { return m_url; }
|
||||
void set_url(const URL& url) { m_url = url; }
|
||||
|
||||
Method method() const { return m_method; }
|
||||
void set_method(Method method) { m_method = method; }
|
||||
|
||||
String method_name() const;
|
||||
ByteBuffer to_raw_request() const;
|
||||
|
||||
RefPtr<NetworkJob> schedule();
|
||||
|
||||
static Optional<HttpRequest> from_raw_request(const ByteBuffer&);
|
||||
|
||||
private:
|
||||
URL m_url;
|
||||
String m_resource;
|
||||
Method m_method { GET };
|
||||
Vector<Header> m_headers;
|
||||
};
|
||||
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <LibCore/HttpResponse.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
HttpResponse::HttpResponse(int code, HashMap<String, String>&& headers, ByteBuffer&& payload)
|
||||
: NetworkResponse(move(payload))
|
||||
, m_code(code)
|
||||
, m_headers(move(headers))
|
||||
{
|
||||
}
|
||||
|
||||
HttpResponse::~HttpResponse()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibCore/NetworkResponse.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class HttpResponse : public NetworkResponse {
|
||||
public:
|
||||
virtual ~HttpResponse() override;
|
||||
static NonnullRefPtr<HttpResponse> create(int code, HashMap<String, String>&& headers, ByteBuffer&& payload)
|
||||
{
|
||||
return adopt(*new HttpResponse(code, move(headers), move(payload)));
|
||||
}
|
||||
|
||||
int code() const { return m_code; }
|
||||
const HashMap<String, String>& headers() const { return m_headers; }
|
||||
|
||||
private:
|
||||
HttpResponse(int code, HashMap<String, String>&&, ByteBuffer&&);
|
||||
|
||||
int m_code { 0 };
|
||||
HashMap<String, String> m_headers;
|
||||
};
|
||||
|
||||
}
|
|
@ -9,9 +9,6 @@ OBJS = \
|
|||
EventLoop.o \
|
||||
File.o \
|
||||
Gzip.o \
|
||||
HttpJob.o \
|
||||
HttpRequest.o \
|
||||
HttpResponse.o \
|
||||
IODevice.o \
|
||||
LocalServer.o \
|
||||
LocalSocket.o \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue