mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-19 10:35:50 +00:00
Add HTTPClientType and HTTPMessage related helpers
This commit is contained in:
@@ -84,11 +84,21 @@
|
||||
<ClInclude Include="..\..\modules\beast_asio\async\SharedHandlerAllocator.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\async\SharedHandlerPtr.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\async\SharedHandlerType.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\ContentBodyBuffer.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\BufferType.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\FixedInputBuffer.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\PeerRole.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\SSLContext.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\beast_asio.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPClientType.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPField.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPHeaders.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPMessage.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPParserImpl.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPParser.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPResponse.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPVersion.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\UniformResourceLocator.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\parsehttp\http_parser.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\protocol\HandshakeDetectLogic.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\protocol\HandshakeDetectLogicPROXY.h" />
|
||||
@@ -97,7 +107,6 @@
|
||||
<ClInclude Include="..\..\modules\beast_asio\protocol\HandshakeDetector.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\protocol\InputParser.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\protocol\PrefilledReadStream.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\protocol\UniformResourceLocator.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\Socket.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\SocketBase.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\SocketWrapper.h" />
|
||||
@@ -350,6 +359,12 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\basics\ContentBodyBuffer.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\basics\PeerRole.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
@@ -361,6 +376,54 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\beast_asio.cpp" />
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\HTTPClientType.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\HTTPField.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\HTTPHeaders.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\HTTPMessage.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\HTTPParser.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\HTTPResponse.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\HTTPVersion.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\UniformResourceLocator.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\parsehttp\http_parser.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
@@ -373,12 +436,6 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\protocol\UniformResourceLocator.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\sockets\Socket.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
|
||||
@@ -176,6 +176,9 @@
|
||||
<Filter Include="beast_asio\protocol">
|
||||
<UniqueIdentifier>{c0724499-ab69-40c3-90e2-65242dbd2eaa}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_asio\http">
|
||||
<UniqueIdentifier>{f7252567-a5bb-4be2-bbd0-c9d9b62298de}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\modules\beast_core\beast_core.h">
|
||||
@@ -989,12 +992,39 @@
|
||||
<ClInclude Include="..\..\modules\beast_asio\protocol\PrefilledReadStream.h">
|
||||
<Filter>beast_asio\protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\protocol\UniformResourceLocator.h">
|
||||
<Filter>beast_asio\protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\functional\SharedFunction.h">
|
||||
<Filter>beast_core\functional</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\ContentBodyBuffer.h">
|
||||
<Filter>beast_asio\basics</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPResponse.h">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPClientType.h">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPMessage.h">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPVersion.h">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPField.h">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPHeaders.h">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPParser.h">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPParserImpl.h">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\http\UniformResourceLocator.h">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\modules\beast_core\beast_core.cpp">
|
||||
@@ -1483,8 +1513,32 @@
|
||||
<ClCompile Include="..\..\modules\beast_asio\protocol\HandshakeDetectLogicPROXY.cpp">
|
||||
<Filter>beast_asio\protocol</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\protocol\UniformResourceLocator.cpp">
|
||||
<Filter>beast_asio\protocol</Filter>
|
||||
<ClCompile Include="..\..\modules\beast_asio\basics\ContentBodyBuffer.cpp">
|
||||
<Filter>beast_asio\basics</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\HTTPResponse.cpp">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\HTTPClientType.cpp">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\HTTPMessage.cpp">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\HTTPVersion.cpp">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\HTTPField.cpp">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\HTTPHeaders.cpp">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\HTTPParser.cpp">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\http\UniformResourceLocator.cpp">
|
||||
<Filter>beast_asio\http</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace beast
|
||||
|
||||
#include "async/SharedHandler.cpp"
|
||||
|
||||
#include "basics/ContentBodyBuffer.cpp"
|
||||
#include "basics/PeerRole.cpp"
|
||||
#include "basics/SSLContext.cpp"
|
||||
|
||||
@@ -37,7 +38,15 @@ namespace beast
|
||||
#include "protocol/HandshakeDetectLogicPROXY.cpp"
|
||||
|
||||
# include "parsehttp/http_parser.h"
|
||||
#include "protocol/UniformResourceLocator.cpp"
|
||||
# include "http/HTTPParserImpl.h"
|
||||
#include "http/HTTPParser.cpp"
|
||||
#include "http/UniformResourceLocator.cpp"
|
||||
#include "http/HTTPClientType.cpp"
|
||||
#include "http/HTTPField.cpp"
|
||||
#include "http/HTTPHeaders.cpp"
|
||||
#include "http/HTTPMessage.cpp"
|
||||
#include "http/HTTPResponse.cpp"
|
||||
#include "http/HTTPVersion.cpp"
|
||||
|
||||
#include "tests/PeerTest.cpp"
|
||||
#include "tests/TestPeerBasics.cpp"
|
||||
|
||||
@@ -63,7 +63,8 @@ namespace beast
|
||||
# include "async/ComposedAsyncOperation.h"
|
||||
#include "async/SharedHandlerAllocator.h"
|
||||
|
||||
#include "basics/BufferType.h"
|
||||
# include "basics/BufferType.h"
|
||||
#include "basics/ContentBodyBuffer.h"
|
||||
#include "basics/FixedInputBuffer.h"
|
||||
#include "basics/PeerRole.h"
|
||||
#include "basics/SSLContext.h"
|
||||
@@ -73,6 +74,15 @@ namespace beast
|
||||
# include "sockets/SocketWrapper.h"
|
||||
#include "sockets/SocketWrapperStrand.h"
|
||||
|
||||
# include "http/HTTPVersion.h"
|
||||
# include "http/HTTPField.h"
|
||||
# include "http/HTTPHeaders.h"
|
||||
# include "http/HTTPMessage.h"
|
||||
# include "http/HTTPResponse.h"
|
||||
# include "http/HTTPParser.h"
|
||||
# include "http/UniformResourceLocator.h"
|
||||
#include "http/HTTPClientType.h"
|
||||
|
||||
# include "protocol/InputParser.h"
|
||||
# include "protocol/HandshakeDetectLogic.h"
|
||||
#include "protocol/HandshakeDetectLogicPROXY.h"
|
||||
@@ -80,7 +90,6 @@ namespace beast
|
||||
#include "protocol/HandshakeDetectLogicSSL3.h"
|
||||
#include "protocol/HandshakeDetector.h"
|
||||
#include "protocol/PrefilledReadStream.h"
|
||||
#include "protocol/UniformResourceLocator.h"
|
||||
|
||||
#include "tests/TestPeerBasics.h"
|
||||
#include "tests/TestPeer.h"
|
||||
|
||||
838
Subtrees/beast/modules/beast_asio/http/HTTPClientType.cpp
Normal file
838
Subtrees/beast/modules/beast_asio/http/HTTPClientType.cpp
Normal file
@@ -0,0 +1,838 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
class HTTPClientType : public HTTPClientBase, public Uncopyable
|
||||
{
|
||||
private:
|
||||
using HTTPClientBase::Listener;
|
||||
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
class ListenerHandler
|
||||
{
|
||||
public:
|
||||
ListenerHandler ()
|
||||
: m_owner (nullptr)
|
||||
, m_listener (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
ListenerHandler (HTTPClientType* owner, Listener* listener = nullptr)
|
||||
: m_owner (owner)
|
||||
, m_listener (listener)
|
||||
{
|
||||
}
|
||||
|
||||
ListenerHandler (ListenerHandler const& other)
|
||||
: m_owner (other.m_owner)
|
||||
, m_listener (other.m_listener)
|
||||
{
|
||||
}
|
||||
|
||||
ListenerHandler& operator= (ListenerHandler const& other)
|
||||
{
|
||||
m_owner = other.m_owner;
|
||||
m_listener = other.m_listener;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void operator() (error_code)
|
||||
{
|
||||
if (m_listener != nullptr)
|
||||
m_listener->onHTTPRequestComplete (
|
||||
*m_owner, m_owner->result ());
|
||||
}
|
||||
|
||||
private:
|
||||
HTTPClientType* m_owner;
|
||||
Listener* m_listener;
|
||||
};
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
HTTPClientType (
|
||||
double timeoutSeconds,
|
||||
std::size_t messageLimitBytes,
|
||||
std::size_t bufferSize)
|
||||
: m_timeoutSeconds (timeoutSeconds)
|
||||
, m_messageLimitBytes (messageLimitBytes)
|
||||
, m_bufferSize (bufferSize)
|
||||
{
|
||||
}
|
||||
|
||||
~HTTPClientType ()
|
||||
{
|
||||
m_async_op = nullptr;
|
||||
}
|
||||
|
||||
Result const& result () const
|
||||
{
|
||||
return m_result;
|
||||
}
|
||||
|
||||
Result const& get (UniformResourceLocator const& url)
|
||||
{
|
||||
boost::asio::io_service io_service;
|
||||
async_get (io_service, nullptr, url);
|
||||
io_service.run ();
|
||||
cancel ();
|
||||
return result ();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_get (boost::asio::io_service& io_service, Listener* listener,
|
||||
UniformResourceLocator const& url)
|
||||
{
|
||||
async_get (io_service, url, ListenerHandler (this, listener));
|
||||
}
|
||||
|
||||
// Handler signature is void(error_code)
|
||||
//
|
||||
template <typename Handler>
|
||||
void async_get (boost::asio::io_service& io_service,
|
||||
UniformResourceLocator const& url,
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler)
|
||||
{
|
||||
async_get (io_service, url, newErrorHandler (
|
||||
BOOST_ASIO_MOVE_CAST(Handler)(handler)));
|
||||
}
|
||||
|
||||
void async_get (boost::asio::io_service& io_service,
|
||||
UniformResourceLocator const& url, SharedHandlerPtr handler)
|
||||
{
|
||||
// This automatically dispatches
|
||||
m_async_op = new AsyncGetOp (
|
||||
*this, io_service, url, handler,
|
||||
m_timeoutSeconds, m_messageLimitBytes, m_bufferSize);
|
||||
}
|
||||
|
||||
void cancel ()
|
||||
{
|
||||
if (m_async_op != nullptr)
|
||||
{
|
||||
m_async_op->cancel ();
|
||||
m_async_op = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Helper function to get a const_buffer from a String. */
|
||||
static boost::asio::const_buffers_1 stringBuffer (String const& s)
|
||||
{
|
||||
return boost::asio::const_buffers_1 (s.getCharPointer (), s.length ());
|
||||
}
|
||||
|
||||
/** Helper function to fill out a Query from a URL. */
|
||||
template <typename Query>
|
||||
static Query queryFromURL (UniformResourceLocator const& url)
|
||||
{
|
||||
if (url.port () != 0)
|
||||
{
|
||||
return Query (
|
||||
url.host().toStdString(),
|
||||
url.port_string().toStdString(),
|
||||
Query::numeric_service);
|
||||
}
|
||||
|
||||
return Query (
|
||||
url.host().toStdString(),
|
||||
url.scheme().toStdString());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
class AsyncGetOp : public ComposedAsyncOperation
|
||||
{
|
||||
private:
|
||||
typedef boost::asio::ip::tcp Protocol;
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
typedef Protocol::resolver resolver;
|
||||
typedef resolver::query query;
|
||||
typedef resolver::iterator iterator;
|
||||
typedef iterator::value_type resolver_entry;
|
||||
typedef Protocol::socket socket;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
enum State
|
||||
{
|
||||
stateStart,
|
||||
stateResolveComplete,
|
||||
stateConnectComplete,
|
||||
stateHandshakeComplete,
|
||||
stateWriteComplete,
|
||||
stateShutdownComplete
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
struct TimerHandler : SharedHandlerPtr
|
||||
{
|
||||
explicit TimerHandler (AsyncGetOp* owner)
|
||||
: SharedHandlerPtr (owner)
|
||||
, m_owner (owner)
|
||||
{
|
||||
}
|
||||
void operator() (error_code const& ec)
|
||||
{
|
||||
m_owner->timerCompletion (ec);
|
||||
}
|
||||
|
||||
AsyncGetOp* m_owner;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
AsyncGetOp (HTTPClientType& owner,
|
||||
boost::asio::io_service& io_service,
|
||||
UniformResourceLocator const& url,
|
||||
SharedHandlerPtr const& handler,
|
||||
double timeoutSeconds,
|
||||
std::size_t messageLimitBytes,
|
||||
std::size_t bufferSize)
|
||||
: ComposedAsyncOperation (sizeof (*this), handler)
|
||||
, m_owner (owner)
|
||||
, m_io_service (io_service)
|
||||
, m_strand (m_io_service)
|
||||
, m_url (url)
|
||||
, m_handler (handler)
|
||||
, m_timer (io_service)
|
||||
, m_resolver (io_service)
|
||||
, m_socket (io_service)
|
||||
, m_context (boost::asio::ssl::context::sslv23)
|
||||
, m_buffer (bufferSize)
|
||||
, m_parser (HTTPParser::typeResponse)
|
||||
, m_timer_canceled (false)
|
||||
, m_timer_expired (false)
|
||||
, m_messageLimitBytes (messageLimitBytes)
|
||||
, m_bytesReceived (0)
|
||||
{
|
||||
m_context.set_default_verify_paths ();
|
||||
m_context.set_options (
|
||||
boost::asio::ssl::context::no_sslv2 |
|
||||
boost::asio::ssl::context::single_dh_use |
|
||||
boost::asio::ssl::context::default_workarounds);
|
||||
//m_context.set_verify_mode (boost::asio::ssl::verify_peer);
|
||||
|
||||
if (timeoutSeconds > 0)
|
||||
{
|
||||
m_timer.expires_from_now (
|
||||
boost::posix_time::milliseconds (
|
||||
long (timeoutSeconds * 1000)));
|
||||
|
||||
++m_io_pending;
|
||||
m_timer.async_wait (TimerHandler (this));
|
||||
}
|
||||
|
||||
// Count as pending i/o
|
||||
++m_io_pending;
|
||||
m_io_service.dispatch (
|
||||
m_strand.wrap (StartHandler (this)));
|
||||
}
|
||||
|
||||
~AsyncGetOp ()
|
||||
{
|
||||
}
|
||||
|
||||
// Cancel all pending I/O, if any, and block until
|
||||
// there are no more completion handler calls pending.
|
||||
//
|
||||
void cancel ()
|
||||
{
|
||||
cancel_all ();
|
||||
m_done.wait ();
|
||||
}
|
||||
|
||||
private:
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// Counts a pending i/o as canceled
|
||||
//
|
||||
void cancel_io ()
|
||||
{
|
||||
bassert (m_io_pending.get () > 0);
|
||||
if (--m_io_pending == 0)
|
||||
m_done.signal ();
|
||||
}
|
||||
|
||||
// Cancels the deadline timer.
|
||||
//
|
||||
void cancel_timer ()
|
||||
{
|
||||
m_timer_canceled = true;
|
||||
error_code ec;
|
||||
m_timer.cancel (ec);
|
||||
}
|
||||
|
||||
// Called to notify the original handler the operation is complete.
|
||||
//
|
||||
void complete (error_code const& ec)
|
||||
{
|
||||
m_owner.m_result.error = ec;
|
||||
|
||||
cancel_timer ();
|
||||
|
||||
bassert (m_io_pending.get () > 0);
|
||||
|
||||
cancel_io ();
|
||||
|
||||
// We call the handler directly since we know
|
||||
// we are already in the right context, and
|
||||
// because we need to do some things afterwards.
|
||||
//
|
||||
m_handler->operator() (ec);
|
||||
}
|
||||
|
||||
// Called every time an async operation completes.
|
||||
// The return value indicates if the handler should
|
||||
// stop additional activity and return immediately.
|
||||
//
|
||||
bool io_complete (error_code const& ec)
|
||||
{
|
||||
if (m_timer_expired ||
|
||||
ec == boost::asio::error::operation_aborted)
|
||||
{
|
||||
cancel_io ();
|
||||
return true;
|
||||
}
|
||||
else if (ec != 0 && ec != boost::asio::error::eof)
|
||||
{
|
||||
complete (ec);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cancels/closes all i/o objects.
|
||||
//
|
||||
void cancel_all ()
|
||||
{
|
||||
cancel_timer ();
|
||||
m_resolver.cancel ();
|
||||
error_code ec;
|
||||
m_socket.close (ec);
|
||||
}
|
||||
|
||||
// Called when the deadline timer expires or is canceled.
|
||||
//
|
||||
void timerCompletion (error_code ec)
|
||||
{
|
||||
if (ec == boost::asio::error::operation_aborted)
|
||||
{
|
||||
bassert (m_timer_canceled);
|
||||
return cancel_io ();
|
||||
}
|
||||
|
||||
check_invariant (ec == 0);
|
||||
|
||||
// Handle the case where the timer completion has already
|
||||
// been queued for dispatch but we have finished the operation
|
||||
// and queued the completion handler for dispatch.
|
||||
//
|
||||
if (! m_timer_canceled)
|
||||
{
|
||||
m_timer_expired = true;
|
||||
|
||||
ec = error_code (boost::asio::error::timed_out,
|
||||
boost::asio::error::get_system_category ());
|
||||
|
||||
complete (ec);
|
||||
|
||||
io_complete (ec);
|
||||
|
||||
m_resolver.cancel ();
|
||||
m_socket.close (ec);
|
||||
}
|
||||
else
|
||||
{
|
||||
cancel_io ();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
struct StartHandler : SharedHandlerPtr
|
||||
{
|
||||
explicit StartHandler (AsyncGetOp* owner)
|
||||
: SharedHandlerPtr (owner)
|
||||
, m_owner (owner)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() ()
|
||||
{
|
||||
m_owner->start_complete ();
|
||||
}
|
||||
|
||||
AsyncGetOp* m_owner;
|
||||
};
|
||||
|
||||
struct ResolveHandler : SharedHandlerPtr
|
||||
{
|
||||
explicit ResolveHandler (AsyncGetOp* owner)
|
||||
: SharedHandlerPtr (owner)
|
||||
, m_owner (owner)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() (error_code const& ec, iterator iter)
|
||||
{
|
||||
m_owner->resolve_complete (ec, iter);
|
||||
}
|
||||
|
||||
AsyncGetOp* m_owner;
|
||||
};
|
||||
|
||||
struct ConnectHandler : SharedHandlerPtr
|
||||
{
|
||||
explicit ConnectHandler (AsyncGetOp* owner)
|
||||
: SharedHandlerPtr (owner)
|
||||
, m_owner (owner)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() (error_code const& ec)
|
||||
{
|
||||
m_owner->connect_complete (ec);
|
||||
}
|
||||
|
||||
AsyncGetOp* m_owner;
|
||||
};
|
||||
|
||||
struct HandshakeHandler : SharedHandlerPtr
|
||||
{
|
||||
explicit HandshakeHandler (AsyncGetOp* owner)
|
||||
: SharedHandlerPtr (owner)
|
||||
, m_owner (owner)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() (error_code const& ec)
|
||||
{
|
||||
m_owner->handshake_complete (ec);
|
||||
}
|
||||
|
||||
AsyncGetOp* m_owner;
|
||||
};
|
||||
|
||||
struct WriteHandler : SharedHandlerPtr
|
||||
{
|
||||
explicit WriteHandler (AsyncGetOp* owner)
|
||||
: SharedHandlerPtr (owner)
|
||||
, m_owner (owner)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() (error_code const& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
m_owner->write_complete (ec, bytes_transferred);
|
||||
}
|
||||
|
||||
AsyncGetOp* m_owner;
|
||||
};
|
||||
|
||||
struct ReadHandler : SharedHandlerPtr
|
||||
{
|
||||
explicit ReadHandler (AsyncGetOp* owner)
|
||||
: SharedHandlerPtr (owner)
|
||||
, m_owner (owner)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() (error_code const& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
m_owner->read_complete (ec, bytes_transferred);
|
||||
}
|
||||
|
||||
AsyncGetOp* m_owner;
|
||||
};
|
||||
|
||||
struct ShutdownHandler : SharedHandlerPtr
|
||||
{
|
||||
explicit ShutdownHandler (AsyncGetOp* owner)
|
||||
: SharedHandlerPtr (owner)
|
||||
, m_owner (owner)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() (error_code const& ec)
|
||||
{
|
||||
m_owner->shutdown_complete (ec);
|
||||
}
|
||||
|
||||
AsyncGetOp* m_owner;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void async_read_some ()
|
||||
{
|
||||
boost::asio::mutable_buffers_1 buf (
|
||||
m_buffer.getData (), m_buffer.getSize ());
|
||||
|
||||
m_stream->async_read_some (buf,
|
||||
m_strand.wrap (ReadHandler (this)));
|
||||
}
|
||||
|
||||
// Called when the HTTP parser returns an error
|
||||
void parse_error ()
|
||||
{
|
||||
//unsigned char const http_errno (m_parser.error ());
|
||||
String const http_errmsg (m_parser.message ());
|
||||
|
||||
// VFALCO TODO put the parser error in ec
|
||||
error_code ec (
|
||||
boost::system::errc::invalid_argument,
|
||||
boost::system::system_category ());
|
||||
|
||||
complete (ec);
|
||||
}
|
||||
|
||||
// Called to create an error when the message is over the limit
|
||||
error_code message_limit_error ()
|
||||
{
|
||||
// VFALCO TODO Make a suitable error code
|
||||
return error_code (
|
||||
boost::system::errc::invalid_argument,
|
||||
boost::system::system_category ());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void start_complete ()
|
||||
{
|
||||
query q (queryFromURL <query> (m_url));
|
||||
m_resolver.async_resolve (q,
|
||||
m_strand.wrap (ResolveHandler (this)));
|
||||
}
|
||||
|
||||
void resolve_complete (error_code ec, iterator iter)
|
||||
{
|
||||
if (io_complete (ec))
|
||||
return;
|
||||
|
||||
resolver_entry const entry (*iter);
|
||||
m_socket.async_connect (entry.endpoint (),
|
||||
m_strand.wrap (ConnectHandler (this)));
|
||||
}
|
||||
|
||||
void connect_complete (error_code ec)
|
||||
{
|
||||
if (io_complete (ec))
|
||||
return;
|
||||
|
||||
if (m_url.scheme () == "https")
|
||||
{
|
||||
typedef boost::asio::ssl::stream <socket&> ssl_stream;
|
||||
m_stream = new SocketWrapper <ssl_stream> (m_socket, m_context);
|
||||
/*
|
||||
m_stream->set_verify_mode (
|
||||
boost::asio::ssl::verify_peer |
|
||||
boost::asio::ssl::verify_fail_if_no_peer_cert);
|
||||
*/
|
||||
m_stream->async_handshake (
|
||||
Socket::client, HandshakeHandler (this));
|
||||
return;
|
||||
}
|
||||
|
||||
m_stream = new SocketWrapper <socket&> (m_socket);
|
||||
handshake_complete (ec);
|
||||
}
|
||||
|
||||
void handshake_complete (error_code ec)
|
||||
{
|
||||
if (io_complete (ec))
|
||||
return;
|
||||
|
||||
m_get_string =
|
||||
"GET " + m_url.path() + " HTTP/1.1\r\n" +
|
||||
"Host: " + m_url.host() + "\r\n" +
|
||||
"Accept: */*\r\n" +
|
||||
"Connection: close\r\n\r\n";
|
||||
|
||||
boost::asio::async_write (
|
||||
*m_stream, stringBuffer (m_get_string),
|
||||
m_strand.wrap (WriteHandler (this)));
|
||||
++m_io_pending;
|
||||
|
||||
async_read_some ();
|
||||
}
|
||||
|
||||
void write_complete (error_code ec, std::size_t)
|
||||
{
|
||||
if (io_complete (ec))
|
||||
return;
|
||||
|
||||
if (! m_stream->needs_handshake ())
|
||||
{
|
||||
m_socket.shutdown (socket::shutdown_send, ec);
|
||||
if (ec != 0)
|
||||
return complete (ec);
|
||||
}
|
||||
|
||||
// deduct one i/o since we aren't issuing any new one
|
||||
cancel_io ();
|
||||
}
|
||||
|
||||
void read_complete (error_code ec, std::size_t bytes_transferred)
|
||||
{
|
||||
m_bytesReceived += bytes_transferred;
|
||||
if (m_bytesReceived > m_messageLimitBytes)
|
||||
ec = message_limit_error ();
|
||||
|
||||
if (io_complete (ec))
|
||||
return;
|
||||
|
||||
std::size_t const bytes_parsed (m_parser.process (
|
||||
m_buffer.getData (), bytes_transferred));
|
||||
|
||||
if (m_parser.error ())
|
||||
{
|
||||
parse_error ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (bytes_parsed != bytes_transferred)
|
||||
{
|
||||
// VFALCO TODO put an appropriate error in ec
|
||||
ec = error_code (
|
||||
boost::system::errc::invalid_argument,
|
||||
boost::system::system_category ());
|
||||
return complete (ec);
|
||||
}
|
||||
|
||||
if (ec == boost::asio::error::eof)
|
||||
{
|
||||
m_parser.process_eof ();
|
||||
}
|
||||
|
||||
if (m_parser.finished ())
|
||||
{
|
||||
m_state = stateShutdownComplete;
|
||||
if (m_stream->needs_handshake ())
|
||||
m_stream->async_shutdown (ShutdownHandler (this));
|
||||
else
|
||||
shutdown_complete (error_code ());
|
||||
return;
|
||||
}
|
||||
|
||||
async_read_some ();
|
||||
}
|
||||
|
||||
void shutdown_complete (error_code ec)
|
||||
{
|
||||
if (io_complete (ec))
|
||||
return;
|
||||
|
||||
m_owner.m_result.response = m_parser.response ();
|
||||
if (ec == boost::asio::error::eof)
|
||||
ec = error_code ();
|
||||
|
||||
return complete (ec);
|
||||
}
|
||||
|
||||
private:
|
||||
WaitableEvent m_done;
|
||||
Atomic <int> m_io_pending;
|
||||
HTTPClientType& m_owner;
|
||||
boost::asio::io_service& m_io_service;
|
||||
boost::asio::io_service& m_strand;
|
||||
UniformResourceLocator m_url;
|
||||
SharedHandlerPtr m_handler;
|
||||
boost::asio::deadline_timer m_timer;
|
||||
resolver m_resolver;
|
||||
socket m_socket;
|
||||
ScopedPointer <Socket> m_stream;
|
||||
boost::asio::ssl::context m_context;
|
||||
MemoryBlock m_buffer;
|
||||
State m_state;
|
||||
HTTPParser m_parser;
|
||||
String m_get_string;
|
||||
bool m_timer_canceled;
|
||||
bool m_timer_expired;
|
||||
std::size_t m_messageLimitBytes;
|
||||
std::size_t m_bytesReceived;
|
||||
};
|
||||
|
||||
double m_timeoutSeconds;
|
||||
std::size_t m_messageLimitBytes;
|
||||
std::size_t m_bufferSize;
|
||||
boost::asio::io_service m_io_service;
|
||||
SharedPtr <AsyncGetOp> m_async_op;
|
||||
Result m_result;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
HTTPClientBase* HTTPClientBase::New (
|
||||
double timeoutSeconds, std::size_t messageLimitBytes, std::size_t bufferSize)
|
||||
{
|
||||
ScopedPointer <HTTPClientBase> object (new HTTPClientType
|
||||
(timeoutSeconds, messageLimitBytes, bufferSize));
|
||||
return object.release ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class HTTPClientTests
|
||||
: public UnitTest
|
||||
, public HTTPClientBase::Listener
|
||||
{
|
||||
public:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
class IoServiceThread : protected Thread
|
||||
{
|
||||
public:
|
||||
explicit IoServiceThread (String name = "io_service")
|
||||
: Thread (name)
|
||||
{
|
||||
}
|
||||
|
||||
~IoServiceThread ()
|
||||
{
|
||||
join ();
|
||||
}
|
||||
|
||||
boost::asio::io_service& get_io_service ()
|
||||
{
|
||||
return m_service;
|
||||
}
|
||||
|
||||
void start ()
|
||||
{
|
||||
startThread ();
|
||||
}
|
||||
|
||||
void join ()
|
||||
{
|
||||
this->waitForThreadToExit ();
|
||||
}
|
||||
|
||||
private:
|
||||
void run ()
|
||||
{
|
||||
m_service.run ();
|
||||
}
|
||||
|
||||
private:
|
||||
boost::asio::io_service m_service;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void log (HTTPMessage const& m)
|
||||
{
|
||||
for (std::size_t i = 0; i < m.headers().size(); ++i)
|
||||
{
|
||||
HTTPField const f (m.headers()[i]);
|
||||
String s;
|
||||
s = "[ '" + f.name() +
|
||||
"' , '" + f.value() + "' ]";
|
||||
logMessage (s);
|
||||
}
|
||||
}
|
||||
|
||||
void log (HTTPClientBase::Result const& result)
|
||||
{
|
||||
if (result.error != 0)
|
||||
{
|
||||
logMessage (String (
|
||||
"HTTPClient error: '" + result.error.message() + "'"));
|
||||
}
|
||||
else if (! result.response.empty ())
|
||||
{
|
||||
logMessage (String ("Status: ") +
|
||||
String::fromNumber (result.response->status()));
|
||||
|
||||
log (*result.response);
|
||||
}
|
||||
else
|
||||
{
|
||||
logMessage ("HTTPClient: no response");
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void onHTTPRequestComplete (
|
||||
HTTPClientBase const&, HTTPClientBase::Result const& result)
|
||||
{
|
||||
log (result);
|
||||
}
|
||||
|
||||
void testSync (String const& s, double timeoutSeconds)
|
||||
{
|
||||
ScopedPointer <HTTPClientBase> client (
|
||||
HTTPClientBase::New (timeoutSeconds));
|
||||
|
||||
log (client->get (ParsedURL (s).url ()));
|
||||
}
|
||||
|
||||
void testAsync (String const& s, double timeoutSeconds)
|
||||
{
|
||||
IoServiceThread t;
|
||||
ScopedPointer <HTTPClientBase> client (
|
||||
HTTPClientBase::New (timeoutSeconds));
|
||||
|
||||
client->async_get (t.get_io_service (), this,
|
||||
ParsedURL (s).url ());
|
||||
|
||||
t.start ();
|
||||
t.join ();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void runTest ()
|
||||
{
|
||||
beginTestCase ("HTTPClient::get");
|
||||
|
||||
testSync (
|
||||
"http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference.html",
|
||||
5);
|
||||
|
||||
testAsync (
|
||||
"http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference.html",
|
||||
5);
|
||||
|
||||
testAsync (
|
||||
"https://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference.html",
|
||||
5);
|
||||
|
||||
pass ();
|
||||
}
|
||||
|
||||
HTTPClientTests () : UnitTest ("HttpClient", "beast", runManual)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static HTTPClientTests httpClientTests;
|
||||
|
||||
|
||||
65
Subtrees/beast/modules/beast_asio/http/HTTPClientType.h
Normal file
65
Subtrees/beast/modules/beast_asio/http/HTTPClientType.h
Normal file
@@ -0,0 +1,65 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_HTTPCLIENTTYPE_H_INCLUDED
|
||||
#define BEAST_ASIO_HTTPCLIENTTYPE_H_INCLUDED
|
||||
|
||||
class HTTPClientBase
|
||||
{
|
||||
public:
|
||||
struct Result
|
||||
{
|
||||
boost::system::error_code error;
|
||||
SharedPtr <HTTPResponse> response;
|
||||
};
|
||||
|
||||
class Listener
|
||||
{
|
||||
public:
|
||||
virtual void onHTTPRequestComplete (
|
||||
HTTPClientBase const& client,
|
||||
Result const& result) = 0;
|
||||
};
|
||||
|
||||
static HTTPClientBase* New (
|
||||
double timeoutSeconds = 30,
|
||||
std::size_t messageLimitBytes = 256 * 1024,
|
||||
std::size_t bufferSize = 16 * 1024);
|
||||
|
||||
virtual ~HTTPClientBase () { }
|
||||
|
||||
virtual Result const& result () const = 0;
|
||||
|
||||
virtual Result const& get (
|
||||
UniformResourceLocator const& url) = 0;
|
||||
|
||||
virtual void async_get (boost::asio::io_service& io_service,
|
||||
Listener* listener,
|
||||
UniformResourceLocator const& url) = 0;
|
||||
|
||||
/** Cancel any pending asynchronous operations.
|
||||
This must be called before destroying the container if there are
|
||||
any pending asynchronous operations. This routine does nothing if
|
||||
there are no pending operations. The call will block until all
|
||||
pending i/o is canceled.
|
||||
*/
|
||||
virtual void cancel () = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
51
Subtrees/beast/modules/beast_asio/http/HTTPField.cpp
Normal file
51
Subtrees/beast/modules/beast_asio/http/HTTPField.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
HTTPField::HTTPField ()
|
||||
{
|
||||
}
|
||||
|
||||
HTTPField::HTTPField (String name_, String value_)
|
||||
: m_name (name_)
|
||||
, m_value (value_)
|
||||
{
|
||||
}
|
||||
|
||||
HTTPField::HTTPField (HTTPField const& other)
|
||||
: m_name (other.m_name)
|
||||
, m_value (other.m_value)
|
||||
{
|
||||
}
|
||||
|
||||
HTTPField& HTTPField::operator= (HTTPField const& other)
|
||||
{
|
||||
m_name = other.m_name;
|
||||
m_value = other.m_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
String HTTPField::name () const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
String HTTPField::value () const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
42
Subtrees/beast/modules/beast_asio/http/HTTPField.h
Normal file
42
Subtrees/beast/modules/beast_asio/http/HTTPField.h
Normal file
@@ -0,0 +1,42 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_HTTPFIELD_H_INCLUDED
|
||||
#define BEAST_ASIO_HTTPFIELD_H_INCLUDED
|
||||
|
||||
/** A single header.
|
||||
The header is a field/value pair.
|
||||
Time complexity of copies is constant.
|
||||
*/
|
||||
class HTTPField
|
||||
{
|
||||
public:
|
||||
HTTPField ();
|
||||
HTTPField (String name_, String value_);
|
||||
HTTPField (HTTPField const& other);
|
||||
HTTPField& operator= (HTTPField const& other);
|
||||
String name () const;
|
||||
String value () const;
|
||||
|
||||
private:
|
||||
String m_name;
|
||||
String m_value;
|
||||
};
|
||||
|
||||
#endif
|
||||
74
Subtrees/beast/modules/beast_asio/http/HTTPHeaders.cpp
Normal file
74
Subtrees/beast/modules/beast_asio/http/HTTPHeaders.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
HTTPHeaders::HTTPHeaders ()
|
||||
{
|
||||
}
|
||||
|
||||
HTTPHeaders::HTTPHeaders (StringPairArray& fields)
|
||||
{
|
||||
m_fields.swapWith (fields);
|
||||
}
|
||||
|
||||
HTTPHeaders::HTTPHeaders (StringPairArray const& fields)
|
||||
: m_fields (fields)
|
||||
{
|
||||
}
|
||||
|
||||
HTTPHeaders::HTTPHeaders (HTTPHeaders const& other)
|
||||
: m_fields (other.m_fields)
|
||||
{
|
||||
}
|
||||
|
||||
HTTPHeaders& HTTPHeaders::operator= (HTTPHeaders const& other)
|
||||
{
|
||||
m_fields = other.m_fields;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool HTTPHeaders::empty () const
|
||||
{
|
||||
return m_fields.size () == 0;
|
||||
}
|
||||
|
||||
std::size_t HTTPHeaders::size () const
|
||||
{
|
||||
return m_fields.size ();
|
||||
}
|
||||
|
||||
HTTPField HTTPHeaders::at (std::size_t index) const
|
||||
{
|
||||
return HTTPField (m_fields.getAllKeys () [index],
|
||||
m_fields.getAllValues () [index]);
|
||||
}
|
||||
|
||||
HTTPField HTTPHeaders::operator[] (std::size_t index) const
|
||||
{
|
||||
return at (index);
|
||||
}
|
||||
|
||||
String HTTPHeaders::get (String const& field) const
|
||||
{
|
||||
return m_fields [field];
|
||||
}
|
||||
|
||||
String HTTPHeaders::operator[] (String const& field) const
|
||||
{
|
||||
return get (field);
|
||||
}
|
||||
68
Subtrees/beast/modules/beast_asio/http/HTTPHeaders.h
Normal file
68
Subtrees/beast/modules/beast_asio/http/HTTPHeaders.h
Normal file
@@ -0,0 +1,68 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_HTTPHEADERS_H_INCLUDED
|
||||
#define BEAST_ASIO_HTTPHEADERS_H_INCLUDED
|
||||
|
||||
/** A set of HTTP headers. */
|
||||
class HTTPHeaders
|
||||
{
|
||||
public:
|
||||
/** Construct an empty set of headers. */
|
||||
HTTPHeaders ();
|
||||
|
||||
/** Construct headers taking ownership of a field array.
|
||||
The callers value is overwritten.
|
||||
*/
|
||||
HTTPHeaders (StringPairArray& fields);
|
||||
|
||||
/** Construct a copy of headers from an array.*/
|
||||
HTTPHeaders (StringPairArray const& fields);
|
||||
|
||||
/** Construct a copy of headers. */
|
||||
HTTPHeaders (HTTPHeaders const& other);
|
||||
|
||||
/** Assign a copy of headers. */
|
||||
HTTPHeaders& operator= (HTTPHeaders const& other);
|
||||
|
||||
/** Returns `true` if the container is empty. */
|
||||
bool empty () const;
|
||||
|
||||
/** Returns the number of fields in the container. */
|
||||
std::size_t size () const;
|
||||
|
||||
/** Random access to fields by index. */
|
||||
/** @{ */
|
||||
HTTPField at (std::size_t index) const;
|
||||
HTTPField operator[] (std::size_t index) const;
|
||||
/** @} */
|
||||
|
||||
/** Associative access to fields by name.
|
||||
If the field is not present, an empty string is returned.
|
||||
*/
|
||||
/** @{ */
|
||||
String get (String const& field) const;
|
||||
String operator[] (String const& field) const;
|
||||
/** @} */
|
||||
|
||||
private:
|
||||
StringPairArray m_fields;
|
||||
};
|
||||
|
||||
#endif
|
||||
42
Subtrees/beast/modules/beast_asio/http/HTTPMessage.cpp
Normal file
42
Subtrees/beast/modules/beast_asio/http/HTTPMessage.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
HTTPMessage::HTTPMessage (HTTPVersion const& version_,
|
||||
StringPairArray& fields,
|
||||
ContentBodyBuffer& body)
|
||||
: m_version (version_)
|
||||
, m_headers (fields)
|
||||
{
|
||||
m_body.swapWith (body);
|
||||
}
|
||||
|
||||
HTTPVersion const& HTTPMessage::version () const
|
||||
{
|
||||
return m_version;
|
||||
}
|
||||
|
||||
HTTPHeaders const& HTTPMessage::headers () const
|
||||
{
|
||||
return m_headers;
|
||||
}
|
||||
|
||||
ContentBodyBuffer const& HTTPMessage::body () const
|
||||
{
|
||||
return m_body;
|
||||
}
|
||||
60
Subtrees/beast/modules/beast_asio/http/HTTPMessage.h
Normal file
60
Subtrees/beast/modules/beast_asio/http/HTTPMessage.h
Normal file
@@ -0,0 +1,60 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_HTTPMESSAGE_H_INCLUDED
|
||||
#define BEAST_ASIO_HTTPMESSAGE_H_INCLUDED
|
||||
|
||||
/** A complete HTTP message.
|
||||
|
||||
This provides the information common to all HTTP messages, including
|
||||
the version, content body, and headers.
|
||||
Derived classes provide the request or response specific data.
|
||||
|
||||
Because a single HTTP message can be a fairly expensive object to
|
||||
make copies of, this is a SharedObject.
|
||||
|
||||
@see HTTPRequest, HTTPResponse
|
||||
*/
|
||||
class HTTPMessage : public SharedObject
|
||||
{
|
||||
public:
|
||||
/** Construct the common HTTP message parts from values.
|
||||
Ownership of the fields and body parameters are
|
||||
transferred from the caller.
|
||||
*/
|
||||
HTTPMessage (HTTPVersion const& version_,
|
||||
StringPairArray& fields,
|
||||
ContentBodyBuffer& body);
|
||||
|
||||
/** Returns the HTTP version of this message. */
|
||||
HTTPVersion const& version () const;
|
||||
|
||||
/** Returns the set of HTTP headers associated with this message. */
|
||||
HTTPHeaders const& headers () const;
|
||||
|
||||
/** Returns the content-body. */
|
||||
ContentBodyBuffer const& body () const;
|
||||
|
||||
private:
|
||||
HTTPVersion m_version;
|
||||
HTTPHeaders m_headers;
|
||||
ContentBodyBuffer m_body;
|
||||
};
|
||||
|
||||
#endif
|
||||
79
Subtrees/beast/modules/beast_asio/http/HTTPParser.cpp
Normal file
79
Subtrees/beast/modules/beast_asio/http/HTTPParser.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
HTTPParser::HTTPParser (Type type)
|
||||
: m_type (type)
|
||||
, m_impl (new HTTPParserImpl (
|
||||
(type == typeResponse) ? HTTP_RESPONSE : HTTP_REQUEST))
|
||||
{
|
||||
}
|
||||
|
||||
HTTPParser::~HTTPParser ()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned char HTTPParser::error () const
|
||||
{
|
||||
return m_impl->http_errno ();
|
||||
}
|
||||
|
||||
String HTTPParser::message () const
|
||||
{
|
||||
return m_impl->http_errno_message ();
|
||||
}
|
||||
|
||||
std::size_t HTTPParser::process (void const* buf, std::size_t bytes)
|
||||
{
|
||||
std::size_t const bytes_used (m_impl->process (buf, bytes));
|
||||
|
||||
if (m_impl->finished ())
|
||||
{
|
||||
if (m_type == typeResponse)
|
||||
{
|
||||
m_response = new HTTPResponse (
|
||||
m_impl->version (),
|
||||
m_impl->fields (),
|
||||
m_impl->body (),
|
||||
m_impl->status_code ());
|
||||
}
|
||||
else
|
||||
{
|
||||
// m_request = new HTTPRequest (
|
||||
}
|
||||
}
|
||||
|
||||
return bytes_used;
|
||||
}
|
||||
|
||||
void HTTPParser::process_eof ()
|
||||
{
|
||||
m_impl->process_eof ();
|
||||
}
|
||||
|
||||
bool HTTPParser::finished () const
|
||||
{
|
||||
return m_impl->finished();
|
||||
}
|
||||
|
||||
SharedPtr <HTTPResponse> const& HTTPParser::response ()
|
||||
{
|
||||
bassert (m_type == typeResponse);
|
||||
|
||||
return m_response;
|
||||
}
|
||||
74
Subtrees/beast/modules/beast_asio/http/HTTPParser.h
Normal file
74
Subtrees/beast/modules/beast_asio/http/HTTPParser.h
Normal file
@@ -0,0 +1,74 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_HTTPPARSER_H_INCLUDED
|
||||
#define BEAST_ASIO_HTTPPARSER_H_INCLUDED
|
||||
|
||||
class HTTPParserImpl;
|
||||
|
||||
/** A parser for HTTPRequest and HTTPResponse objects. */
|
||||
class HTTPParser
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
typeRequest,
|
||||
typeResponse
|
||||
};
|
||||
|
||||
/** Construct a new parser for the specified HTTPMessage type. */
|
||||
explicit HTTPParser (Type type);
|
||||
|
||||
/** Destroy the parser. */
|
||||
~HTTPParser ();
|
||||
|
||||
/** Returns a non zero error code if parsing fails. */
|
||||
unsigned char error () const;
|
||||
|
||||
/** Returns the error message text when error is non zero. */
|
||||
String message () const;
|
||||
|
||||
/** Parse the buffer and return the amount used.
|
||||
Typically it is an error when this returns less than
|
||||
the amount passed in.
|
||||
*/
|
||||
std::size_t process (void const* buf, std::size_t bytes);
|
||||
|
||||
/** Notify the parser that eof was received.
|
||||
*/
|
||||
void process_eof ();
|
||||
|
||||
/** Returns `true` when parsing is successful and complete. */
|
||||
bool finished () const;
|
||||
|
||||
/** Return the HTTPResponse object produce from the parsing.
|
||||
Only valid after finished returns `true`.
|
||||
*/
|
||||
SharedPtr <HTTPResponse> const& response ();
|
||||
|
||||
//SharedPtr <HTTPRequest> const& request ();
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
ScopedPointer <HTTPParserImpl> m_impl;
|
||||
SharedPtr <HTTPResponse> m_response;
|
||||
//SharedPtr <HTTPRequest> m_request;
|
||||
};
|
||||
|
||||
#endif
|
||||
256
Subtrees/beast/modules/beast_asio/http/HTTPParserImpl.h
Normal file
256
Subtrees/beast/modules/beast_asio/http/HTTPParserImpl.h
Normal file
@@ -0,0 +1,256 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HTTPPARSERIMPL_H_INCLUDED
|
||||
#define BEAST_HTTPPARSERIMPL_H_INCLUDED
|
||||
|
||||
class HTTPParserImpl
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
stringReservation = 256
|
||||
};
|
||||
|
||||
explicit HTTPParserImpl (enum http_parser_type type)
|
||||
: m_finished (false)
|
||||
, m_was_value (false)
|
||||
{
|
||||
m_settings.on_message_begin = &HTTPParserImpl::on_message_begin;
|
||||
m_settings.on_url = &HTTPParserImpl::on_url;
|
||||
m_settings.on_status_complete = &HTTPParserImpl::on_status_complete;
|
||||
m_settings.on_header_field = &HTTPParserImpl::on_header_field;
|
||||
m_settings.on_header_value = &HTTPParserImpl::on_header_value;
|
||||
m_settings.on_headers_complete = &HTTPParserImpl::on_headers_complete;
|
||||
m_settings.on_body = &HTTPParserImpl::on_body;
|
||||
m_settings.on_message_complete = &HTTPParserImpl::on_message_complete;
|
||||
|
||||
m_field.reserve (stringReservation);
|
||||
m_value.reserve (stringReservation);
|
||||
|
||||
http_parser_init (&m_parser, type);
|
||||
m_parser.data = this;
|
||||
}
|
||||
|
||||
~HTTPParserImpl ()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned char error () const
|
||||
{
|
||||
return m_parser.http_errno;
|
||||
}
|
||||
|
||||
String message () const
|
||||
{
|
||||
return String (http_errno_name (static_cast <
|
||||
enum http_errno> (m_parser.http_errno)));
|
||||
}
|
||||
|
||||
std::size_t process (void const* buf, std::size_t bytes)
|
||||
{
|
||||
return http_parser_execute (&m_parser,
|
||||
&m_settings, static_cast <char const*> (buf), bytes);
|
||||
}
|
||||
|
||||
void process_eof ()
|
||||
{
|
||||
http_parser_execute (&m_parser, &m_settings, nullptr, 0);
|
||||
}
|
||||
|
||||
bool finished () const
|
||||
{
|
||||
return m_finished;
|
||||
}
|
||||
|
||||
HTTPVersion version () const
|
||||
{
|
||||
return HTTPVersion (
|
||||
m_parser.http_major, m_parser.http_minor);
|
||||
}
|
||||
|
||||
// Only for HTTPResponse!
|
||||
unsigned short status_code () const
|
||||
{
|
||||
return m_parser.status_code;
|
||||
}
|
||||
|
||||
// Only for HTTPRequest!
|
||||
unsigned char method () const
|
||||
{
|
||||
return m_parser.method;
|
||||
}
|
||||
|
||||
unsigned char http_errno () const
|
||||
{
|
||||
return m_parser.http_errno;
|
||||
}
|
||||
|
||||
String http_errno_message () const
|
||||
{
|
||||
return String (http_errno_name (
|
||||
static_cast <enum http_errno> (
|
||||
m_parser.http_errno)));
|
||||
}
|
||||
|
||||
bool upgrade () const
|
||||
{
|
||||
return m_parser.upgrade != 0;
|
||||
}
|
||||
|
||||
StringPairArray& fields ()
|
||||
{
|
||||
return m_fields;
|
||||
}
|
||||
|
||||
ContentBodyBuffer& body ()
|
||||
{
|
||||
return m_body;
|
||||
}
|
||||
|
||||
private:
|
||||
void addFieldValue ()
|
||||
{
|
||||
if (m_field.size () > 0 && m_value.size () > 0)
|
||||
m_fields.set (m_field, m_value);
|
||||
m_field.resize (0);
|
||||
m_value.resize (0);
|
||||
}
|
||||
|
||||
int onMessageBegin ()
|
||||
{
|
||||
int ec (0);
|
||||
return ec;
|
||||
}
|
||||
|
||||
int onUrl (char const*, std::size_t)
|
||||
{
|
||||
int ec (0);
|
||||
// This is for HTTP Request
|
||||
return ec;
|
||||
}
|
||||
|
||||
int onStatusComplete ()
|
||||
{
|
||||
int ec (0);
|
||||
return ec;
|
||||
}
|
||||
|
||||
int onHeaderField (char const* at, std::size_t length)
|
||||
{
|
||||
int ec (0);
|
||||
if (m_was_value)
|
||||
{
|
||||
addFieldValue ();
|
||||
m_was_value = false;
|
||||
}
|
||||
m_field.append (at, length);
|
||||
return ec;
|
||||
}
|
||||
|
||||
int onHeaderValue (char const* at, std::size_t length)
|
||||
{
|
||||
int ec (0);
|
||||
m_value.append (at, length);
|
||||
m_was_value = true;
|
||||
return ec;
|
||||
}
|
||||
|
||||
int onHeadersComplete ()
|
||||
{
|
||||
int ec (0);
|
||||
addFieldValue ();
|
||||
return ec;
|
||||
}
|
||||
|
||||
int onBody (char const* at, std::size_t length)
|
||||
{
|
||||
m_body.commit (boost::asio::buffer_copy (m_body.prepare (length),
|
||||
boost::asio::buffer (at, length)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int onMessageComplete ()
|
||||
{
|
||||
int ec (0);
|
||||
m_finished = true;
|
||||
return ec;
|
||||
}
|
||||
|
||||
private:
|
||||
static int on_message_begin (http_parser* parser)
|
||||
{
|
||||
return static_cast <HTTPParserImpl*> (parser->data)->
|
||||
onMessageBegin ();
|
||||
}
|
||||
|
||||
static int on_url (http_parser* parser, const char *at, size_t length)
|
||||
{
|
||||
return static_cast <HTTPParserImpl*> (parser->data)->
|
||||
onUrl (at, length);
|
||||
}
|
||||
|
||||
static int on_status_complete (http_parser* parser)
|
||||
{
|
||||
return static_cast <HTTPParserImpl*> (parser->data)->
|
||||
onStatusComplete ();
|
||||
}
|
||||
|
||||
static int on_header_field (http_parser* parser, const char *at, size_t length)
|
||||
{
|
||||
return static_cast <HTTPParserImpl*> (parser->data)->
|
||||
onHeaderField (at, length);
|
||||
}
|
||||
|
||||
static int on_header_value (http_parser* parser, const char *at, size_t length)
|
||||
{
|
||||
return static_cast <HTTPParserImpl*> (parser->data)->
|
||||
onHeaderValue (at, length);
|
||||
}
|
||||
|
||||
static int on_headers_complete (http_parser* parser)
|
||||
{
|
||||
return static_cast <HTTPParserImpl*> (parser->data)->
|
||||
onHeadersComplete ();
|
||||
}
|
||||
|
||||
static int on_body (http_parser* parser, const char *at, size_t length)
|
||||
{
|
||||
return static_cast <HTTPParserImpl*> (parser->data)->
|
||||
onBody (at, length);
|
||||
}
|
||||
|
||||
static int on_message_complete (http_parser* parser)
|
||||
{
|
||||
return static_cast <HTTPParserImpl*> (parser->data)->
|
||||
onMessageComplete ();
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_finished;
|
||||
http_parser_settings m_settings;
|
||||
http_parser m_parser;
|
||||
StringPairArray m_fields;
|
||||
bool m_was_value;
|
||||
std::string m_field;
|
||||
std::string m_value;
|
||||
ContentBodyBuffer m_body;
|
||||
};
|
||||
|
||||
#endif
|
||||
33
Subtrees/beast/modules/beast_asio/http/HTTPResponse.cpp
Normal file
33
Subtrees/beast/modules/beast_asio/http/HTTPResponse.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
HTTPResponse::HTTPResponse (
|
||||
HTTPVersion const& version_,
|
||||
StringPairArray& fields,
|
||||
ContentBodyBuffer& body,
|
||||
unsigned short status_)
|
||||
: HTTPMessage (version_, fields, body)
|
||||
, m_status (status_)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned short HTTPResponse::status () const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
42
Subtrees/beast/modules/beast_asio/http/HTTPResponse.h
Normal file
42
Subtrees/beast/modules/beast_asio/http/HTTPResponse.h
Normal file
@@ -0,0 +1,42 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_HTTPRESPONSE_H_INCLUDED
|
||||
#define BEAST_ASIO_HTTPRESPONSE_H_INCLUDED
|
||||
|
||||
class HTTPResponse : public HTTPMessage
|
||||
{
|
||||
public:
|
||||
/** Construct a complete response from values.
|
||||
Ownership of the fields and body parameters are
|
||||
transferred from the caller.
|
||||
*/
|
||||
HTTPResponse (
|
||||
HTTPVersion const& version_,
|
||||
StringPairArray& fields,
|
||||
ContentBodyBuffer& body,
|
||||
unsigned short status_);
|
||||
|
||||
unsigned short status () const;
|
||||
|
||||
private:
|
||||
unsigned short m_status;
|
||||
};
|
||||
|
||||
#endif
|
||||
93
Subtrees/beast/modules/beast_asio/http/HTTPVersion.cpp
Normal file
93
Subtrees/beast/modules/beast_asio/http/HTTPVersion.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
HTTPVersion::HTTPVersion ()
|
||||
: m_major (0)
|
||||
, m_minor (0)
|
||||
{
|
||||
}
|
||||
|
||||
HTTPVersion::HTTPVersion (unsigned short major_, unsigned short minor_)
|
||||
: m_major (major_)
|
||||
, m_minor (minor_)
|
||||
{
|
||||
}
|
||||
|
||||
HTTPVersion::HTTPVersion (HTTPVersion const& other)
|
||||
: m_major (other.m_major)
|
||||
, m_minor (other.m_minor)
|
||||
{
|
||||
}
|
||||
|
||||
HTTPVersion& HTTPVersion::operator= (HTTPVersion const& other)
|
||||
{
|
||||
m_major = other.m_major;
|
||||
m_minor = other.m_minor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
String HTTPVersion::toString () const
|
||||
{
|
||||
return String::fromNumber (major ()) + "." +
|
||||
String::fromNumber (minor ());
|
||||
}
|
||||
|
||||
unsigned short HTTPVersion::major () const
|
||||
{
|
||||
return m_major;
|
||||
}
|
||||
|
||||
unsigned short HTTPVersion::minor () const
|
||||
{
|
||||
return m_minor;
|
||||
}
|
||||
|
||||
bool HTTPVersion::operator== (HTTPVersion const& rhs) const
|
||||
{
|
||||
return (m_major == rhs.m_major) && (m_minor == rhs.m_minor);
|
||||
}
|
||||
|
||||
bool HTTPVersion::operator!= (HTTPVersion const& rhs) const
|
||||
{
|
||||
return (m_major != rhs.m_major) || (m_minor != rhs.m_minor);
|
||||
}
|
||||
|
||||
bool HTTPVersion::operator> (HTTPVersion const& rhs) const
|
||||
{
|
||||
return (m_major > rhs.m_major) ||
|
||||
((m_major == rhs.m_major) && (m_minor > rhs.m_minor));
|
||||
}
|
||||
|
||||
bool HTTPVersion::operator>= (HTTPVersion const& rhs) const
|
||||
{
|
||||
return (m_major > rhs.m_major) ||
|
||||
((m_major == rhs.m_major) && (m_minor >= rhs.m_minor));
|
||||
}
|
||||
|
||||
bool HTTPVersion::operator< (HTTPVersion const& rhs) const
|
||||
{
|
||||
return (m_major < rhs.m_major) ||
|
||||
((m_major == rhs.m_major) && (m_minor < rhs.m_minor));
|
||||
}
|
||||
|
||||
bool HTTPVersion::operator<= (HTTPVersion const& rhs) const
|
||||
{
|
||||
return (m_major < rhs.m_major) ||
|
||||
((m_major == rhs.m_major) && (m_minor <= rhs.m_minor));
|
||||
}
|
||||
46
Subtrees/beast/modules/beast_asio/http/HTTPVersion.h
Normal file
46
Subtrees/beast/modules/beast_asio/http/HTTPVersion.h
Normal file
@@ -0,0 +1,46 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_HTTPVERSION_H_INCLUDED
|
||||
#define BEAST_ASIO_HTTPVERSION_H_INCLUDED
|
||||
|
||||
/** The HTTP version. This is the major.minor version number. */
|
||||
class HTTPVersion
|
||||
{
|
||||
public:
|
||||
HTTPVersion ();
|
||||
HTTPVersion (unsigned short major_, unsigned short minor_);
|
||||
HTTPVersion (HTTPVersion const& other);
|
||||
HTTPVersion& operator= (HTTPVersion const& other);
|
||||
String toString () const;
|
||||
unsigned short major () const;
|
||||
unsigned short minor () const;
|
||||
bool operator== (HTTPVersion const& rhs) const;
|
||||
bool operator!= (HTTPVersion const& rhs) const;
|
||||
bool operator> (HTTPVersion const& rhs) const;
|
||||
bool operator>= (HTTPVersion const& rhs) const;
|
||||
bool operator< (HTTPVersion const& rhs) const;
|
||||
bool operator<= (HTTPVersion const& rhs) const;
|
||||
|
||||
private:
|
||||
unsigned short m_major;
|
||||
unsigned short m_minor;;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user