From 373ca9cef0195ee014899160c6213752953c1d19 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Fri, 20 Sep 2013 12:58:41 -0700 Subject: [PATCH] Add HTTPRequest and improvements to HTTPMessage parsing --- Builds/VisualStudio2012/beast.vcxproj | 7 +++ Builds/VisualStudio2012/beast.vcxproj.filters | 6 +++ modules/beast_asio/beast_asio.cpp | 1 + modules/beast_asio/beast_asio.h | 1 + modules/beast_asio/http/HTTPParser.cpp | 29 +++++++++++- modules/beast_asio/http/HTTPParser.h | 19 ++++++-- modules/beast_asio/http/HTTPParserImpl.h | 8 ++++ modules/beast_asio/http/HTTPRequest.cpp | 42 +++++++++++++++++ modules/beast_asio/http/HTTPRequest.h | 45 +++++++++++++++++++ 9 files changed, 152 insertions(+), 6 deletions(-) create mode 100644 modules/beast_asio/http/HTTPRequest.cpp create mode 100644 modules/beast_asio/http/HTTPRequest.h diff --git a/Builds/VisualStudio2012/beast.vcxproj b/Builds/VisualStudio2012/beast.vcxproj index 4a9f54f58..b6bb09653 100644 --- a/Builds/VisualStudio2012/beast.vcxproj +++ b/Builds/VisualStudio2012/beast.vcxproj @@ -117,6 +117,7 @@ + @@ -434,6 +435,12 @@ true true + + true + true + true + true + true true diff --git a/Builds/VisualStudio2012/beast.vcxproj.filters b/Builds/VisualStudio2012/beast.vcxproj.filters index c1e7053db..d6e3aa81e 100644 --- a/Builds/VisualStudio2012/beast.vcxproj.filters +++ b/Builds/VisualStudio2012/beast.vcxproj.filters @@ -1095,6 +1095,9 @@ beast + + beast_asio\http + @@ -1622,6 +1625,9 @@ beast\utility\impl + + beast_asio\http + diff --git a/modules/beast_asio/beast_asio.cpp b/modules/beast_asio/beast_asio.cpp index 6301c1c2e..094698253 100644 --- a/modules/beast_asio/beast_asio.cpp +++ b/modules/beast_asio/beast_asio.cpp @@ -45,6 +45,7 @@ namespace beast #include "http/HTTPField.cpp" #include "http/HTTPHeaders.cpp" #include "http/HTTPMessage.cpp" +#include "http/HTTPRequest.cpp" #include "http/HTTPResponse.cpp" #include "http/HTTPVersion.cpp" diff --git a/modules/beast_asio/beast_asio.h b/modules/beast_asio/beast_asio.h index 32b41fe8a..5d60c758d 100644 --- a/modules/beast_asio/beast_asio.h +++ b/modules/beast_asio/beast_asio.h @@ -82,6 +82,7 @@ namespace beast # include "http/HTTPField.h" # include "http/HTTPHeaders.h" # include "http/HTTPMessage.h" +# include "http/HTTPRequest.h" # include "http/HTTPResponse.h" # include "http/HTTPParser.h" # include "http/UniformResourceLocator.h" diff --git a/modules/beast_asio/http/HTTPParser.cpp b/modules/beast_asio/http/HTTPParser.cpp index 5ca1c9ed8..6c5a5e41d 100644 --- a/modules/beast_asio/http/HTTPParser.cpp +++ b/modules/beast_asio/http/HTTPParser.cpp @@ -44,7 +44,15 @@ std::size_t HTTPParser::process (void const* buf, std::size_t bytes) if (m_impl->finished ()) { - if (m_type == typeResponse) + if (m_type == typeRequest) + { + m_request = new HTTPRequest ( + m_impl->version (), + m_impl->fields (), + m_impl->body (), + m_impl->method ()); + } + else if (m_type == typeResponse) { m_response = new HTTPResponse ( m_impl->version (), @@ -54,7 +62,7 @@ std::size_t HTTPParser::process (void const* buf, std::size_t bytes) } else { - // m_request = new HTTPRequest ( + bassertfalse; } } @@ -71,6 +79,23 @@ bool HTTPParser::finished () const return m_impl->finished(); } +StringPairArray const& HTTPParser::fields () const +{ + return m_impl->fields(); +} + +bool HTTPParser::headersComplete () const +{ + return m_impl->headers_complete(); +} + +SharedPtr const& HTTPParser::request () +{ + bassert (m_type == typeRequest); + + return m_request; +} + SharedPtr const& HTTPParser::response () { bassert (m_type == typeResponse); diff --git a/modules/beast_asio/http/HTTPParser.h b/modules/beast_asio/http/HTTPParser.h index d6e3a287e..675e4a43b 100644 --- a/modules/beast_asio/http/HTTPParser.h +++ b/modules/beast_asio/http/HTTPParser.h @@ -57,18 +57,29 @@ public: /** Returns `true` when parsing is successful and complete. */ bool finished () const; - /** Return the HTTPResponse object produce from the parsing. + /** Peek at the header fields as they are being built. + Only complete pairs will show up, never partial strings. + */ + StringPairArray const& fields () const; + + /** Returns `true` if all the HTTP headers have been received. */ + bool headersComplete () const; + + /** Return the HTTPRequest object produced from the parsiing. + Only valid after finished returns `true`. + */ + SharedPtr const& request (); + + /** Return the HTTPResponse object produced from the parsing. Only valid after finished returns `true`. */ SharedPtr const& response (); - //SharedPtr const& request (); - private: Type m_type; ScopedPointer m_impl; + SharedPtr m_request; SharedPtr m_response; - //SharedPtr m_request; }; #endif diff --git a/modules/beast_asio/http/HTTPParserImpl.h b/modules/beast_asio/http/HTTPParserImpl.h index c01fd5811..344785907 100644 --- a/modules/beast_asio/http/HTTPParserImpl.h +++ b/modules/beast_asio/http/HTTPParserImpl.h @@ -31,6 +31,7 @@ public: explicit HTTPParserImpl (enum http_parser_type type) : m_finished (false) , m_was_value (false) + , m_headersComplete (false) { m_settings.on_message_begin = &HTTPParserImpl::on_message_begin; m_settings.on_url = &HTTPParserImpl::on_url; @@ -119,6 +120,11 @@ public: return m_fields; } + bool headers_complete () const + { + return m_headersComplete; + } + ContentBodyBuffer& body () { return m_body; @@ -174,6 +180,7 @@ private: int onHeadersComplete () { + m_headersComplete = true; int ec (0); addFieldValue (); return ec; @@ -250,6 +257,7 @@ private: bool m_was_value; std::string m_field; std::string m_value; + bool m_headersComplete; ContentBodyBuffer m_body; }; diff --git a/modules/beast_asio/http/HTTPRequest.cpp b/modules/beast_asio/http/HTTPRequest.cpp new file mode 100644 index 000000000..1d3efee96 --- /dev/null +++ b/modules/beast_asio/http/HTTPRequest.cpp @@ -0,0 +1,42 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + 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. +*/ +//============================================================================== + +HTTPRequest::HTTPRequest ( + HTTPVersion const& version_, + StringPairArray& fields, + ContentBodyBuffer& body, + unsigned short method_) + : HTTPMessage (version_, fields, body) + , m_method (method_) +{ +} + +unsigned short HTTPRequest::method () const +{ + return m_method; +} + +String HTTPRequest::toString () const +{ + String s; + s << "Method: " << String::fromNumber (method ()) << newLine; + s << this->HTTPMessage::toString (); + return s; +} + diff --git a/modules/beast_asio/http/HTTPRequest.h b/modules/beast_asio/http/HTTPRequest.h new file mode 100644 index 000000000..0ae1a2594 --- /dev/null +++ b/modules/beast_asio/http/HTTPRequest.h @@ -0,0 +1,45 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + 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_HTTPREQUEST_H_INCLUDED +#define BEAST_ASIO_HTTPREQUEST_H_INCLUDED + +class HTTPRequest : public HTTPMessage +{ +public: + /** Construct a complete response from values. + Ownership of the fields and body parameters are + transferred from the caller. + */ + HTTPRequest ( + HTTPVersion const& version_, + StringPairArray& fields, + ContentBodyBuffer& body, + unsigned short method_); + + unsigned short method () const; + + /** Convert the request into a string, excluding the body. */ + String toString () const; + +private: + unsigned short m_method; +}; + +#endif