Serialize HTTP service

This commit is contained in:
Hamish Milne 2019-12-30 15:20:13 +00:00 committed by zhupengfei
parent 74361fa3fb
commit 8bd3e8cd27
4 changed files with 130 additions and 6 deletions

2
TODO
View File

@ -84,7 +84,7 @@
✔ GSP @done(19-12-30 12:45)
☐ Fix the global weak_ptr to gsp
✔ HID @done(19-12-30 14:46)
☐ HTTP
✔ HTTP @done(19-12-30 15:18)
☐ IR
☐ LDR_RO
☐ MIC

2
externals/boost vendored

@ -1 +1 @@
Subproject commit 1c857c04195db89c66c347ddfad93a7f3666f2d3
Subproject commit 65dc954e93b22870b8423701e225147c75e3b31b

View File

@ -4,6 +4,7 @@
#include <cryptopp/aes.h>
#include <cryptopp/modes.h>
#include "common/archives.h"
#include "core/core.h"
#include "core/file_sys/archive_ncch.h"
#include "core/file_sys/file_backend.h"
@ -14,6 +15,9 @@
#include "core/hle/service/http_c.h"
#include "core/hw/aes/key.h"
SERIALIZE_EXPORT_IMPL(Service::HTTP::HTTP_C)
SERIALIZE_EXPORT_IMPL(Service::HTTP::SessionData)
namespace Service::HTTP {
namespace ErrCodes {

View File

@ -5,10 +5,16 @@
#pragma once
#include <memory>
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>
#include <boost/optional.hpp>
#include <boost/serialization/optional.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/unordered_map.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/weak_ptr.hpp>
#include "core/hle/kernel/shared_memory.h"
#include "core/hle/service/service.h"
@ -50,6 +56,17 @@ struct ClientCertContext {
u8 cert_id;
std::vector<u8> certificate;
std::vector<u8> private_key;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& handle;
ar& session_id;
ar& cert_id;
ar& certificate;
ar& private_key;
}
friend class boost::serialization::access;
};
/// Represents a root certificate chain, it contains a list of DER-encoded certificates for
@ -61,12 +78,30 @@ struct RootCertChain {
Handle handle;
u32 session_id;
std::vector<u8> certificate;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& handle;
ar& session_id;
ar& certificate;
}
friend class boost::serialization::access;
};
using Handle = u32;
Handle handle;
u32 session_id;
std::vector<RootCACert> certificates;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& handle;
ar& session_id;
ar& certificates;
}
friend class boost::serialization::access;
};
/// Represents an HTTP context.
@ -86,30 +121,74 @@ public:
std::string username;
std::string password;
u16 port;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& url;
ar& username;
ar& password;
ar& port;
}
friend class boost::serialization::access;
};
struct BasicAuth {
std::string username;
std::string password;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& username;
ar& password;
}
friend class boost::serialization::access;
};
struct RequestHeader {
RequestHeader(std::string name, std::string value) : name(name), value(value){};
std::string name;
std::string value;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& name;
ar& value;
}
friend class boost::serialization::access;
};
struct PostData {
// TODO(Subv): Support Binary and Raw POST elements.
PostData(std::string name, std::string value) : name(name), value(value){};
PostData() = default;
std::string name;
std::string value;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& name;
ar& value;
}
friend class boost::serialization::access;
};
struct SSLConfig {
u32 options;
std::weak_ptr<ClientCertContext> client_cert_ctx;
std::weak_ptr<RootCertChain> root_ca_chain;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& options;
ar& client_cert_ctx;
ar& root_ca_chain;
}
friend class boost::serialization::access;
};
Handle handle;
@ -117,18 +196,35 @@ public:
std::string url;
RequestMethod method;
RequestState state = RequestState::NotStarted;
std::optional<Proxy> proxy;
std::optional<BasicAuth> basic_auth;
boost::optional<Proxy> proxy;
boost::optional<BasicAuth> basic_auth;
SSLConfig ssl_config{};
u32 socket_buffer_size;
std::vector<RequestHeader> headers;
std::vector<PostData> post_data;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& handle;
ar& session_id;
ar& url;
ar& method;
ar& state;
ar& proxy;
ar& basic_auth;
ar& ssl_config;
ar& socket_buffer_size;
ar& headers;
ar& post_data;
}
friend class boost::serialization::access;
};
struct SessionData : public Kernel::SessionRequestHandler::SessionDataBase {
/// The HTTP context that is currently bound to this session, this can be empty if no context
/// has been bound. Certain commands can only be called on a session with a bound context.
std::optional<Context::Handle> current_http_context;
boost::optional<Context::Handle> current_http_context;
u32 session_id;
@ -140,6 +236,17 @@ struct SessionData : public Kernel::SessionRequestHandler::SessionDataBase {
/// Whether this session has been initialized in some way, be it via Initialize or
/// InitializeConnectionSession.
bool initialized = false;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& current_http_context;
ar& session_id;
ar& num_http_contexts;
ar& num_client_certs;
ar& initialized;
}
friend class boost::serialization::access;
};
class HTTP_C final : public ServiceFramework<HTTP_C, SessionData> {
@ -326,8 +433,21 @@ private:
std::vector<u8> private_key;
bool init = false;
} ClCertA;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<Kernel::SessionRequestHandler>(*this);
ar& ClCertA.certificate;
ar& ClCertA.private_key;
ar& ClCertA.init;
}
friend class boost::serialization::access;
};
void InstallInterfaces(Core::System& system);
} // namespace Service::HTTP
BOOST_CLASS_EXPORT_KEY(Service::HTTP::HTTP_C)
BOOST_CLASS_EXPORT_KEY(Service::HTTP::SessionData)