Network: Add WebService
This commit is contained in:
committed by
Jérôme Leclercq
parent
b5206ebdb7
commit
c65daba072
@@ -47,5 +47,8 @@
|
||||
#include <Nazara/Network/TcpClient.hpp>
|
||||
#include <Nazara/Network/TcpServer.hpp>
|
||||
#include <Nazara/Network/UdpSocket.hpp>
|
||||
#include <Nazara/Network/WebRequest.hpp>
|
||||
#include <Nazara/Network/WebRequestResult.hpp>
|
||||
#include <Nazara/Network/WebService.hpp>
|
||||
|
||||
#endif // NAZARA_GLOBAL_NETWORK_HPP
|
||||
|
||||
34
include/Nazara/Network/CurlFunctions.hpp
Normal file
34
include/Nazara/Network/CurlFunctions.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Network module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
// no header guards
|
||||
|
||||
#if !defined(NAZARA_CURL_FUNCTION)
|
||||
#error You must define NAZARA_CURL_FUNCTION before including this file
|
||||
#endif
|
||||
|
||||
#ifndef NAZARA_CURL_FUNCTION_LAST
|
||||
#define NAZARA_CURL_FUNCTION_LAST(F) NAZARA_CURL_FUNCTION(F)
|
||||
#endif
|
||||
|
||||
NAZARA_CURL_FUNCTION(easy_cleanup)
|
||||
NAZARA_CURL_FUNCTION(easy_getinfo)
|
||||
NAZARA_CURL_FUNCTION(easy_init)
|
||||
NAZARA_CURL_FUNCTION(easy_setopt)
|
||||
NAZARA_CURL_FUNCTION(easy_strerror)
|
||||
NAZARA_CURL_FUNCTION(global_cleanup)
|
||||
NAZARA_CURL_FUNCTION(global_init)
|
||||
NAZARA_CURL_FUNCTION(multi_add_handle)
|
||||
NAZARA_CURL_FUNCTION(multi_cleanup)
|
||||
NAZARA_CURL_FUNCTION(multi_info_read)
|
||||
NAZARA_CURL_FUNCTION(multi_init)
|
||||
NAZARA_CURL_FUNCTION(multi_perform)
|
||||
NAZARA_CURL_FUNCTION(multi_remove_handle)
|
||||
NAZARA_CURL_FUNCTION(multi_strerror)
|
||||
NAZARA_CURL_FUNCTION(slist_append)
|
||||
NAZARA_CURL_FUNCTION(slist_free_all)
|
||||
NAZARA_CURL_FUNCTION_LAST(version_info)
|
||||
|
||||
#undef NAZARA_CURL_FUNCTION
|
||||
#undef NAZARA_CURL_FUNCTION_LAST
|
||||
44
include/Nazara/Network/CurlLibrary.hpp
Normal file
44
include/Nazara/Network/CurlLibrary.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Network module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_NETWORK_CURLLIBRARY_HPP
|
||||
#define NAZARA_NETWORK_CURLLIBRARY_HPP
|
||||
|
||||
#include <Nazara/Core/DynLib.hpp>
|
||||
#include <Nazara/Network/Config.hpp>
|
||||
#include <curl/curl.h>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_NETWORK_API CurlLibrary
|
||||
{
|
||||
public:
|
||||
inline CurlLibrary();
|
||||
CurlLibrary(const CurlLibrary&) = delete;
|
||||
CurlLibrary(CurlLibrary&&) = delete;
|
||||
inline ~CurlLibrary();
|
||||
|
||||
inline bool IsLoaded() const;
|
||||
|
||||
bool Load();
|
||||
|
||||
void Unload();
|
||||
|
||||
CurlLibrary& operator=(const CurlLibrary&) = delete;
|
||||
CurlLibrary& operator=(CurlLibrary&&) = delete;
|
||||
|
||||
#define NAZARA_CURL_FUNCTION(name) decltype(&::curl_##name) name;
|
||||
#include <Nazara/Network/CurlFunctions.hpp>
|
||||
|
||||
private:
|
||||
DynLib m_library;
|
||||
bool m_isInitialized;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Network/CurlLibrary.inl>
|
||||
|
||||
#endif // NAZARA_NETWORK_CURLLIBRARY_HPP
|
||||
25
include/Nazara/Network/CurlLibrary.inl
Normal file
25
include/Nazara/Network/CurlLibrary.inl
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Network module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Network/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline CurlLibrary::CurlLibrary() :
|
||||
m_isInitialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
inline CurlLibrary::~CurlLibrary()
|
||||
{
|
||||
Unload();
|
||||
}
|
||||
|
||||
inline bool CurlLibrary::IsLoaded() const
|
||||
{
|
||||
return m_isInitialized;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Network/DebugOff.hpp>
|
||||
@@ -10,9 +10,12 @@
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Core.hpp>
|
||||
#include <Nazara/Network/Config.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class WebService;
|
||||
|
||||
class NAZARA_NETWORK_API Network : public ModuleBase<Network>
|
||||
{
|
||||
friend ModuleBase;
|
||||
@@ -20,12 +23,22 @@ namespace Nz
|
||||
public:
|
||||
using Dependencies = TypeList<Core>;
|
||||
|
||||
struct Config {};
|
||||
struct Config;
|
||||
|
||||
Network(Config /*config*/);
|
||||
Network(Config config);
|
||||
~Network();
|
||||
|
||||
std::unique_ptr<WebService> InstantiateWebService();
|
||||
|
||||
struct Config
|
||||
{
|
||||
// Initialize web services and fails module initialization if it failed to initialize them
|
||||
bool webServices = false;
|
||||
};
|
||||
|
||||
private:
|
||||
std::unique_ptr<class CurlLibrary> m_curlLibrary;
|
||||
|
||||
static Network* s_instance;
|
||||
};
|
||||
}
|
||||
|
||||
75
include/Nazara/Network/WebRequest.hpp
Normal file
75
include/Nazara/Network/WebRequest.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Network module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_NETWORK_WEBREQUEST_HPP
|
||||
#define NAZARA_NETWORK_WEBREQUEST_HPP
|
||||
|
||||
#include <Nazara/Network/Config.hpp>
|
||||
#include <Nazara/Network/Enums.hpp>
|
||||
#include <Nazara/Network/WebRequestResult.hpp>
|
||||
#include <NazaraUtils/MovablePtr.hpp>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
struct curl_slist;
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class WebService;
|
||||
|
||||
class NAZARA_NETWORK_API WebRequest
|
||||
{
|
||||
friend WebService;
|
||||
|
||||
public:
|
||||
using DataCallback = std::function<bool(const void* data, std::size_t length)>;
|
||||
using ResultCallback = std::function<void(WebRequestResult&& result)>;
|
||||
|
||||
WebRequest(WebService& owner);
|
||||
WebRequest(const WebRequest&) = delete;
|
||||
WebRequest(WebRequest&&) = default;
|
||||
~WebRequest();
|
||||
|
||||
void ForceProtocol(NetProtocol protocol);
|
||||
|
||||
inline void SetDataCallback(DataCallback callback);
|
||||
inline void SetHeader(std::string header, std::string value);
|
||||
void SetJSonContent(std::string_view encodedJSon);
|
||||
void SetMaximumFileSize(UInt64 maxFileSize);
|
||||
inline void SetResultCallback(ResultCallback callback);
|
||||
void SetServiceName(const std::string_view& serviceName);
|
||||
void SetURL(const std::string& url);
|
||||
|
||||
void SetupGet();
|
||||
void SetupPost();
|
||||
|
||||
WebRequest& operator=(const WebRequest&) = delete;
|
||||
WebRequest& operator=(WebRequest&&) = default;
|
||||
|
||||
static std::unique_ptr<WebRequest> Get(const std::string& url, ResultCallback callback = nullptr);
|
||||
static std::unique_ptr<WebRequest> Post(const std::string& url, ResultCallback callback = nullptr);
|
||||
|
||||
private:
|
||||
inline bool OnBodyResponse(const char* data, std::size_t length);
|
||||
CURL* Prepare();
|
||||
inline void TriggerCallback();
|
||||
inline void TriggerCallback(std::string errorMessage);
|
||||
|
||||
std::string m_responseBody;
|
||||
std::unordered_map<std::string, std::string> m_headers;
|
||||
WebService& m_webService;
|
||||
DataCallback m_dataCallback;
|
||||
MovablePtr<CURL> m_curlHandle;
|
||||
MovablePtr<curl_slist> m_headerList;
|
||||
ResultCallback m_resultCallback;
|
||||
bool m_isUserAgentSet;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Network/WebRequest.inl>
|
||||
|
||||
#endif // NAZARA_NETWORK_WEBREQUEST_HPP
|
||||
47
include/Nazara/Network/WebRequest.inl
Normal file
47
include/Nazara/Network/WebRequest.inl
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Network module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Network/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline void WebRequest::SetDataCallback(DataCallback callback)
|
||||
{
|
||||
m_dataCallback = std::move(callback);
|
||||
}
|
||||
|
||||
inline void WebRequest::SetResultCallback(ResultCallback callback)
|
||||
{
|
||||
m_resultCallback = std::move(callback);
|
||||
}
|
||||
|
||||
inline void WebRequest::SetHeader(std::string header, std::string value)
|
||||
{
|
||||
m_headers.insert_or_assign(std::move(header), std::move(value));
|
||||
}
|
||||
|
||||
inline bool WebRequest::OnBodyResponse(const char* data, std::size_t length)
|
||||
{
|
||||
if (!m_dataCallback)
|
||||
{
|
||||
m_responseBody.append(data, length);
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_dataCallback(data, length);
|
||||
}
|
||||
|
||||
inline void WebRequest::TriggerCallback()
|
||||
{
|
||||
m_resultCallback(WebRequestResult(m_webService, m_curlHandle.Get(), std::move(m_responseBody)));
|
||||
m_responseBody.clear();
|
||||
}
|
||||
|
||||
inline void WebRequest::TriggerCallback(std::string errorMessage)
|
||||
{
|
||||
m_resultCallback(WebRequestResult(m_webService, std::move(errorMessage)));
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Network/DebugOff.hpp>
|
||||
56
include/Nazara/Network/WebRequestResult.hpp
Normal file
56
include/Nazara/Network/WebRequestResult.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Network module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_NETWORK_WEBREQUESTRESULT_HPP
|
||||
#define NAZARA_NETWORK_WEBREQUESTRESULT_HPP
|
||||
|
||||
#include <Nazara/Network/Config.hpp>
|
||||
#include <NazaraUtils/MovablePtr.hpp>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
using CURL = void;
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class WebService;
|
||||
|
||||
class NAZARA_NETWORK_API WebRequestResult
|
||||
{
|
||||
friend class WebRequest;
|
||||
|
||||
public:
|
||||
WebRequestResult(const WebRequestResult&) = delete;
|
||||
WebRequestResult(WebRequestResult&&) = delete;
|
||||
~WebRequestResult() = default;
|
||||
|
||||
inline std::string& GetBody();
|
||||
inline const std::string& GetBody() const;
|
||||
Nz::UInt64 GetDownloadedSize() const;
|
||||
Nz::UInt64 GetDownloadSpeed() const;
|
||||
inline const std::string& GetErrorMessage() const;
|
||||
long GetReponseCode() const;
|
||||
|
||||
inline bool HasSucceeded() const;
|
||||
|
||||
inline explicit operator bool() const;
|
||||
|
||||
WebRequestResult& operator=(const WebRequestResult&) = delete;
|
||||
WebRequestResult& operator=(WebRequestResult&&) = delete;
|
||||
|
||||
private:
|
||||
inline WebRequestResult(WebService& webService, CURL* curl, std::string body);
|
||||
inline WebRequestResult(WebService& webService, std::string errMessage);
|
||||
|
||||
CURL* m_curlHandle;
|
||||
WebService& m_webService;
|
||||
std::string m_bodyOrErr;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Network/WebRequestResult.inl>
|
||||
|
||||
#endif // NAZARA_NETWORK_WEBREQUESTRESULT_HPP
|
||||
53
include/Nazara/Network/WebRequestResult.inl
Normal file
53
include/Nazara/Network/WebRequestResult.inl
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Network module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Network/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline WebRequestResult::WebRequestResult(WebService& webService, CURL* curl, std::string body) :
|
||||
m_curlHandle(curl),
|
||||
m_webService(webService),
|
||||
m_bodyOrErr(std::move(body))
|
||||
{
|
||||
}
|
||||
|
||||
inline WebRequestResult::WebRequestResult(WebService& webService, std::string errMessage) :
|
||||
m_curlHandle(nullptr),
|
||||
m_webService(webService),
|
||||
m_bodyOrErr(std::move(errMessage))
|
||||
{
|
||||
}
|
||||
|
||||
inline std::string& WebRequestResult::GetBody()
|
||||
{
|
||||
assert(HasSucceeded());
|
||||
return m_bodyOrErr;
|
||||
}
|
||||
|
||||
inline const std::string& WebRequestResult::GetBody() const
|
||||
{
|
||||
assert(HasSucceeded());
|
||||
return m_bodyOrErr;
|
||||
}
|
||||
|
||||
inline const std::string& WebRequestResult::GetErrorMessage() const
|
||||
{
|
||||
assert(!HasSucceeded());
|
||||
return m_bodyOrErr;
|
||||
}
|
||||
|
||||
inline bool WebRequestResult::HasSucceeded() const
|
||||
{
|
||||
return m_curlHandle != nullptr;
|
||||
}
|
||||
|
||||
inline WebRequestResult::operator bool() const
|
||||
{
|
||||
return HasSucceeded();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include <Nazara/Network/DebugOff.hpp>
|
||||
58
include/Nazara/Network/WebService.hpp
Normal file
58
include/Nazara/Network/WebService.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Network module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_NETWORK_WEBSERVICE_HPP
|
||||
#define NAZARA_NETWORK_WEBSERVICE_HPP
|
||||
|
||||
#include <Nazara/Network/Config.hpp>
|
||||
#include <Nazara/Network/WebRequest.hpp>
|
||||
#include <NazaraUtils/MovablePtr.hpp>
|
||||
|
||||
using CURLM = void;
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class CurlLibrary;
|
||||
class Logger;
|
||||
|
||||
class NAZARA_NETWORK_API WebService
|
||||
{
|
||||
friend WebRequest;
|
||||
friend WebRequestResult;
|
||||
|
||||
public:
|
||||
WebService(const CurlLibrary& library);
|
||||
WebService(const WebService&) = delete;
|
||||
WebService(WebService&&) = delete;
|
||||
~WebService();
|
||||
|
||||
inline std::unique_ptr<WebRequest> AllocateRequest();
|
||||
|
||||
inline std::unique_ptr<WebRequest> CreateGetRequest(const std::string& url, WebRequest::ResultCallback callback);
|
||||
inline std::unique_ptr<WebRequest> CreatePostRequest(const std::string& url, WebRequest::ResultCallback callback);
|
||||
|
||||
inline const std::string& GetUserAgent() const;
|
||||
|
||||
void Poll();
|
||||
|
||||
void QueueRequest(std::unique_ptr<WebRequest>&& request);
|
||||
|
||||
WebService& operator=(const WebService&) = delete;
|
||||
WebService& operator=(WebService&&) = delete;
|
||||
|
||||
private:
|
||||
inline const CurlLibrary& GetCurlLibrary() const;
|
||||
|
||||
std::string m_userAgent;
|
||||
std::unordered_map<CURL*, std::unique_ptr<WebRequest>> m_activeRequests;
|
||||
const CurlLibrary& m_curl;
|
||||
MovablePtr<CURLM> m_curlMulti;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Network/WebService.inl>
|
||||
|
||||
#endif // NAZARA_NETWORK_WEBSERVICE_HPP
|
||||
45
include/Nazara/Network/WebService.inl
Normal file
45
include/Nazara/Network/WebService.inl
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Network module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Network/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline std::unique_ptr<WebRequest> WebService::AllocateRequest()
|
||||
{
|
||||
return std::make_unique<WebRequest>(*this);
|
||||
}
|
||||
|
||||
inline std::unique_ptr<WebRequest> WebService::CreateGetRequest(const std::string& url, WebRequest::ResultCallback callback)
|
||||
{
|
||||
std::unique_ptr<WebRequest> request = AllocateRequest();
|
||||
request->SetURL(url);
|
||||
request->SetResultCallback(std::move(callback));
|
||||
request->SetupGet();
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
inline std::unique_ptr<WebRequest> WebService::CreatePostRequest(const std::string& url, WebRequest::ResultCallback callback)
|
||||
{
|
||||
std::unique_ptr<WebRequest> request = AllocateRequest();
|
||||
request->SetURL(url);
|
||||
request->SetResultCallback(std::move(callback));
|
||||
request->SetupPost();
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
inline const std::string& WebService::GetUserAgent() const
|
||||
{
|
||||
return m_userAgent;
|
||||
}
|
||||
|
||||
const CurlLibrary& WebService::GetCurlLibrary() const
|
||||
{
|
||||
return m_curl;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Network/DebugOff.hpp>
|
||||
Reference in New Issue
Block a user