From 02e8d7382fb9b5f2c663ab7c0d68cafac7b53a1c Mon Sep 17 00:00:00 2001 From: Frank Celler Date: Wed, 13 Jun 2012 23:29:27 +0200 Subject: [PATCH] trying to get an abstact class for HttpRequest --- arangod/RestHandler/RestDocumentHandler.cpp | 2 +- .../RestHandler/RestVocbaseBaseHandler.cpp | 33 ++- arangod/RestHandler/RestVocbaseBaseHandler.h | 4 +- lib/Admin/RestBaseHandler.cpp | 28 +- lib/Admin/RestBaseHandler.h | 11 + lib/Admin/RestVersionHandler.cpp | 20 +- lib/Basics/StringBuffer.h | 8 + lib/BasicsC/json.h | 6 + lib/Rest/HttpRequest.h | 251 ++++++------------ lib/Rest/HttpRequestPlain.h | 5 +- 10 files changed, 172 insertions(+), 196 deletions(-) diff --git a/arangod/RestHandler/RestDocumentHandler.cpp b/arangod/RestHandler/RestDocumentHandler.cpp index 16e8a8d4d0..34fc3272c9 100644 --- a/arangod/RestHandler/RestDocumentHandler.cpp +++ b/arangod/RestHandler/RestDocumentHandler.cpp @@ -391,7 +391,7 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) { vector const& suffix = request->suffix(); /// check for an etag - TRI_voc_rid_t ifNoneRid = extractRevision("if-none-match"); + TRI_voc_rid_t ifNoneRid = extractRevision("if-none-match", 0); TRI_voc_rid_t ifRid = extractRevision("if-match", "rev"); // split the document reference diff --git a/arangod/RestHandler/RestVocbaseBaseHandler.cpp b/arangod/RestHandler/RestVocbaseBaseHandler.cpp index 0fdf382802..206551bb42 100644 --- a/arangod/RestHandler/RestVocbaseBaseHandler.cpp +++ b/arangod/RestHandler/RestVocbaseBaseHandler.cpp @@ -423,25 +423,38 @@ void RestVocbaseBaseHandler::generateDocument (TRI_doc_mptr_t const* document, /// @brief extracts the revision //////////////////////////////////////////////////////////////////////////////// -TRI_voc_rid_t RestVocbaseBaseHandler::extractRevision (string const& header, string const& parameter) { +TRI_voc_rid_t RestVocbaseBaseHandler::extractRevision (char const* header, char const* parameter) { bool found; - string etag = StringUtils::trim(request->header(header, found)); + char const* etag = request->header(header, found); - if (found && ! etag.empty() && etag[0] == '"' && etag[etag.length()-1] == '"') { - return StringUtils::uint64(etag.c_str() + 1, etag.length() - 2); - } - else if (found) { - return 0; + if (found) { + char const* s = etag; + char const* e = etag + strlen(etag); + + while (s < e && (s[0] == ' ' || s[0] == '\t')) { + ++s; + } + + while (s < e && (e[-1] == ' ' || e[-1] == '\t')) { + --e; + } + + if (s + 1 < e && s[0] == '"' && e[-1] == '"') { + return TRI_UInt64String2(s + 1, e - s - 2); + } + else { + return 0; + } } - if (parameter.empty()) { + if (parameter == 0) { return 0; } else { - char const* cetag = request->value(parameter, found); + etag = request->value(parameter, found); if (found) { - return TRI_UInt64String(cetag); + return TRI_UInt64String(etag); } else { return 0; diff --git a/arangod/RestHandler/RestVocbaseBaseHandler.h b/arangod/RestHandler/RestVocbaseBaseHandler.h index 7000b1207a..42346f41b9 100644 --- a/arangod/RestHandler/RestVocbaseBaseHandler.h +++ b/arangod/RestHandler/RestVocbaseBaseHandler.h @@ -231,9 +231,11 @@ namespace triagens { //////////////////////////////////////////////////////////////////////////////// /// @brief extracts the revision +/// +/// @note @FA{header} must be lowercase. //////////////////////////////////////////////////////////////////////////////// - TRI_voc_rid_t extractRevision (string const& header, string const& parameter = ""); + TRI_voc_rid_t extractRevision (char const* header, char const* parameter); //////////////////////////////////////////////////////////////////////////////// /// @brief extracts the update policy diff --git a/lib/Admin/RestBaseHandler.cpp b/lib/Admin/RestBaseHandler.cpp index f2a3de0325..07f79fa407 100644 --- a/lib/Admin/RestBaseHandler.cpp +++ b/lib/Admin/RestBaseHandler.cpp @@ -29,6 +29,7 @@ #include +#include "BasicsC/strings.h" #include "Basics/StringUtils.h" #include "Logger/Logger.h" #include "Rest/HttpRequest.h" @@ -84,16 +85,9 @@ RestBaseHandler::RestBaseHandler (HttpRequest* request) if (found) { LOGGER_TRACE << "forcing body"; - request->setBody(body); + request->setBody(body, strlen(body)); } } - - char const* format = request->value("__OUTPUT__", found); - - if (found) { - LOGGER_TRACE << "forcing output format '" << format << "'"; - request->setHeader("accept", format); - } } //////////////////////////////////////////////////////////////////////////////// @@ -132,6 +126,24 @@ void RestBaseHandler::handleError (TriagensError const& error) { /// @{ //////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +/// @brief generates a result from JSON +//////////////////////////////////////////////////////////////////////////////// + +void RestBaseHandler::generateResult (TRI_json_t* json) { + response = new HttpResponse(HttpResponse::OK); + response->setContentType("application/json; charset=utf-8"); + + int res = TRI_StringifyJson(response->body().stringBuffer(), json); + + if (res != TRI_ERROR_NO_ERROR) { + delete response; + generateError(HttpResponse::SERVER_ERROR, + TRI_ERROR_INTERNAL, + "cannot generate output"); + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief generates a result //////////////////////////////////////////////////////////////////////////////// diff --git a/lib/Admin/RestBaseHandler.h b/lib/Admin/RestBaseHandler.h index 32347dbbe8..f8dfc82200 100644 --- a/lib/Admin/RestBaseHandler.h +++ b/lib/Admin/RestBaseHandler.h @@ -30,9 +30,14 @@ #include "HttpServer/HttpHandler.h" +#include "BasicsC/json.h" #include "JsonParserX/InputParser.h" #include "Rest/HttpResponse.h" +// ----------------------------------------------------------------------------- +// --SECTION-- forward declaration +// ----------------------------------------------------------------------------- + namespace triagens { namespace basics { class VariantObject; @@ -112,6 +117,12 @@ namespace triagens { public: +//////////////////////////////////////////////////////////////////////////////// +/// @brief generates a result from JSON +//////////////////////////////////////////////////////////////////////////////// + + virtual void generateResult (TRI_json_t* json); + //////////////////////////////////////////////////////////////////////////////// /// @brief generates a result //////////////////////////////////////////////////////////////////////////////// diff --git a/lib/Admin/RestVersionHandler.cpp b/lib/Admin/RestVersionHandler.cpp index 6225403720..06904dc68d 100644 --- a/lib/Admin/RestVersionHandler.cpp +++ b/lib/Admin/RestVersionHandler.cpp @@ -27,7 +27,8 @@ #include "RestVersionHandler.h" -#include "Variant/VariantArray.h" +#include "BasicsC/json.h" +#include "BasicsC/strings.h" using namespace triagens::basics; using namespace triagens::rest; @@ -89,12 +90,21 @@ string const& RestVersionHandler::queue () { //////////////////////////////////////////////////////////////////////////////// HttpHandler::status_e RestVersionHandler::execute () { - VariantArray* result = new VariantArray(); + TRI_json_t result; + TRI_json_t server; + TRI_json_t version; - result->add("server", _name); - result->add("version", _version); + TRI_InitArrayJson(TRI_CORE_MEM_ZONE, &result); + + TRI_InitStringJson(TRI_CORE_MEM_ZONE, &server, TRI_DuplicateString(_name.c_str())); + TRI_Insert2ArrayJson(TRI_CORE_MEM_ZONE, &result, "server", &server); + + TRI_InitStringJson(TRI_CORE_MEM_ZONE, &version, TRI_DuplicateString(_version.c_str())); + TRI_Insert2ArrayJson(TRI_CORE_MEM_ZONE, &result, "version", &version); + + generateResult(&result); + TRI_DestroyJson(TRI_CORE_MEM_ZONE, &result); - generateResult(result); return HANDLER_DONE; } diff --git a/lib/Basics/StringBuffer.h b/lib/Basics/StringBuffer.h index 0ed251c9db..35ed099c20 100644 --- a/lib/Basics/StringBuffer.h +++ b/lib/Basics/StringBuffer.h @@ -124,6 +124,14 @@ namespace triagens { /// @{ //////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns the low level buffer +//////////////////////////////////////////////////////////////////////////////// + + TRI_string_buffer_t* stringBuffer () { + return &_buffer; + } + //////////////////////////////////////////////////////////////////////////////// /// @brief swaps content with another string buffer //////////////////////////////////////////////////////////////////////////////// diff --git a/lib/BasicsC/json.h b/lib/BasicsC/json.h index 3f7f9c4808..c4bfcf0a14 100644 --- a/lib/BasicsC/json.h +++ b/lib/BasicsC/json.h @@ -131,6 +131,12 @@ TRI_json_t* TRI_CreateNumberJson (TRI_memory_zone_t*, double value); TRI_json_t* TRI_CreateStringJson (TRI_memory_zone_t*, char* value); +//////////////////////////////////////////////////////////////////////////////// +/// @brief creates a string object +//////////////////////////////////////////////////////////////////////////////// + +void TRI_InitStringJson (TRI_memory_zone_t*, TRI_json_t* result, char* value); + //////////////////////////////////////////////////////////////////////////////// /// @brief creates a string object, copying the string //////////////////////////////////////////////////////////////////////////////// diff --git a/lib/Rest/HttpRequest.h b/lib/Rest/HttpRequest.h index ab920b7a68..226eb90354 100644 --- a/lib/Rest/HttpRequest.h +++ b/lib/Rest/HttpRequest.h @@ -31,8 +31,6 @@ #include "Basics/Common.h" -#include "Basics/Dictionary.h" -#include "BasicsC/strings.h" #include "Rest/ConnectionInfo.h" // ----------------------------------------------------------------------------- @@ -114,35 +112,8 @@ namespace triagens { //////////////////////////////////////////////////////////////////////////////// /// @brief http request constructor /// -/// Constructs a http request given the header string. A client request -/// consists of two parts: the header and the body. For a GET request the -/// body is always empty and all information about the request is delivered -/// in the header. For a POST or PUT request some information is also -/// delivered in the body. However, it is necessary to parse the header -/// information, before the body can be read. -//////////////////////////////////////////////////////////////////////////////// - - explicit - HttpRequest (string const& header); - -//////////////////////////////////////////////////////////////////////////////// -/// @brief http request constructor -/// -/// Constructs a http request given the header string. A client request -/// consists of two parts: the header and the body. For a GET request the -/// body is always empty and all information about the request is delivered -/// in the header. For a POST or PUT request some information is also -/// delivered in the body. However, it is necessary to parse the header -/// information, before the body can be read. -//////////////////////////////////////////////////////////////////////////////// - - HttpRequest (char const* header, size_t length); - -//////////////////////////////////////////////////////////////////////////////// -/// @brief http request constructor -/// -/// Constructs a http request given nothing. You can add the values, -/// the header information, and the path later. +/// Constructs a http request given nothing. You can add the values, the header +/// information, and path information afterwards. //////////////////////////////////////////////////////////////////////////////// HttpRequest (); @@ -180,26 +151,6 @@ namespace triagens { void setRequestType (HttpRequestType newType); -//////////////////////////////////////////////////////////////////////////////// -/// @brief returns the path of the request -/// -/// The path consists of the URL without the host and without any parameters. -//////////////////////////////////////////////////////////////////////////////// - - char const* requestPath () const; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief sets the path of the request -//////////////////////////////////////////////////////////////////////////////// - - void setRequestPath (char const* path); - -//////////////////////////////////////////////////////////////////////////////// -/// @brief returns the content length -//////////////////////////////////////////////////////////////////////////////// - - size_t contentLength () const; - //////////////////////////////////////////////////////////////////////////////// /// @brief returns the server IP //////////////////////////////////////////////////////////////////////////////// @@ -212,62 +163,19 @@ namespace triagens { void setConnectionInfo (ConnectionInfo const& info); +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns the path of the request +/// +/// The path consists of the URL without the host and without any parameters. +//////////////////////////////////////////////////////////////////////////////// + + virtual char const* requestPath () const = 0; + //////////////////////////////////////////////////////////////////////////////// /// @brief writes representation to string buffer //////////////////////////////////////////////////////////////////////////////// - void write (basics::StringBuffer*) const; - -//////////////////////////////////////////////////////////////////////////////// -/// @} -//////////////////////////////////////////////////////////////////////////////// - -// ----------------------------------------------------------------------------- -// --SECTION-- public header methods -// ----------------------------------------------------------------------------- - -//////////////////////////////////////////////////////////////////////////////// -/// @addtogroup Rest -/// @{ -//////////////////////////////////////////////////////////////////////////////// - - public: - -//////////////////////////////////////////////////////////////////////////////// -/// @brief returns a header field -/// -/// Returns the value of a header field with given name. If no header field -/// with the given name was specified by the client, the empty string is -/// returned. -//////////////////////////////////////////////////////////////////////////////// - - char const* header (char const* field) const; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief returns a header field -/// -/// Returns the value of a header field with given name. If no header field -/// with the given name was specified by the client, the empty string is -/// returned. found is try if the client specified the header field. -//////////////////////////////////////////////////////////////////////////////// - - char const* header (char const* field, bool& found) const; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief returns all header fields -/// -/// Returns all header fields -//////////////////////////////////////////////////////////////////////////////// - - map headers () const; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief set a header field -/// -/// Set the value of a header field with given name. -//////////////////////////////////////////////////////////////////////////////// - - void setHeader (string const& field, string const& value); + virtual void write (basics::StringBuffer*) const = 0; //////////////////////////////////////////////////////////////////////////////// /// @} @@ -294,7 +202,60 @@ namespace triagens { /// @brief adds a suffix part //////////////////////////////////////////////////////////////////////////////// - void addSuffix (string const& part); + void addSuffix (void*, string const& part); + +//////////////////////////////////////////////////////////////////////////////// +/// @} +//////////////////////////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// --SECTION-- public header methods +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @addtogroup Rest +/// @{ +//////////////////////////////////////////////////////////////////////////////// + + public: + +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns the content length +//////////////////////////////////////////////////////////////////////////////// + + virtual size_t contentLength () const = 0; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns a header field +/// +/// Returns the value of a header field with given name. If no header field +/// with the given name was specified by the client, the empty string is +/// returned. +/// +/// @note The @FA{field} must be lowercase. +//////////////////////////////////////////////////////////////////////////////// + + virtual char const* header (char const* field) const = 0; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns a header field +/// +/// Returns the value of a header field with given name. If no header field +/// with the given name was specified by the client, the empty string is +/// returned. found is try if the client specified the header field. +/// +/// @note The @FA{field} must be lowercase. +//////////////////////////////////////////////////////////////////////////////// + + virtual char const* header (char const* field, bool& found) const = 0; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns all header fields +/// +/// Returns a copy of all header fields. +//////////////////////////////////////////////////////////////////////////////// + + map headers () const; //////////////////////////////////////////////////////////////////////////////// /// @} @@ -318,7 +279,7 @@ namespace triagens { /// specified by the client. //////////////////////////////////////////////////////////////////////////////// - char const* value (string const& key) const; + virtual char const* value (char const* key) const = 0; //////////////////////////////////////////////////////////////////////////////// /// @brief returns the value of a key @@ -327,7 +288,7 @@ namespace triagens { /// specified by the client. found is true if the client specified the key. //////////////////////////////////////////////////////////////////////////////// - char const* value (string const& key, bool& found) const; + virtual char const* value (char const* key, bool& found) const = 0; //////////////////////////////////////////////////////////////////////////////// /// @brief returns all values @@ -335,19 +296,7 @@ namespace triagens { /// Returns all key/value pairs of the request. //////////////////////////////////////////////////////////////////////////////// - map values () const; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief sets the key/values from an url encoded string -//////////////////////////////////////////////////////////////////////////////// - - void setValues (string const& params); - -//////////////////////////////////////////////////////////////////////////////// -/// @brief sets a key/value pair -//////////////////////////////////////////////////////////////////////////////// - - void setValue (string const& key, string const& value); + virtual map values () const; //////////////////////////////////////////////////////////////////////////////// /// @} @@ -368,55 +317,19 @@ namespace triagens { /// @brief gets the body //////////////////////////////////////////////////////////////////////////////// - char const* body () const; + virtual char const* body () const = 0; //////////////////////////////////////////////////////////////////////////////// /// @brief gets the body size //////////////////////////////////////////////////////////////////////////////// - size_t bodySize () const; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief sets the body -/// -/// In a POST request the body contains additional key/value pairs. The -/// function parses the body and adds the corresponding pairs. -//////////////////////////////////////////////////////////////////////////////// - - void setBody (char const* newBody); + virtual size_t bodySize () const = 0; //////////////////////////////////////////////////////////////////////////////// /// @brief sets the body //////////////////////////////////////////////////////////////////////////////// - void setBody (char const* newBody, size_t length); - -//////////////////////////////////////////////////////////////////////////////// -/// @} -//////////////////////////////////////////////////////////////////////////////// - -// ----------------------------------------------------------------------------- -// --SECTION-- private methods -// ----------------------------------------------------------------------------- - -//////////////////////////////////////////////////////////////////////////////// -/// @addtogroup Rest -/// @{ -//////////////////////////////////////////////////////////////////////////////// - - private: - -//////////////////////////////////////////////////////////////////////////////// -/// @brief parses the http header -//////////////////////////////////////////////////////////////////////////////// - - void parseHeader (char* ptr, size_t length); - -//////////////////////////////////////////////////////////////////////////////// -/// @brief sets the header values -//////////////////////////////////////////////////////////////////////////////// - - void setValues (char* begin, char* end); + virtual int setBody (char const* newBody, size_t length) = 0; //////////////////////////////////////////////////////////////////////////////// /// @} @@ -432,20 +345,24 @@ namespace triagens { //////////////////////////////////////////////////////////////////////////////// private: + +//////////////////////////////////////////////////////////////////////////////// +/// @brief the request type +//////////////////////////////////////////////////////////////////////////////// + HttpRequestType _type; - string _requestPath; - - vector _suffix; - basics::Dictionary _headers; - basics::Dictionary _values; - - char* _body; - size_t _bodySize; +//////////////////////////////////////////////////////////////////////////////// +/// @brief connection info for the server and the peer +//////////////////////////////////////////////////////////////////////////////// ConnectionInfo _connectionInfo; - vector _freeables; +//////////////////////////////////////////////////////////////////////////////// +/// @brief list of suffixes +//////////////////////////////////////////////////////////////////////////////// + + vector _suffix; }; } } diff --git a/lib/Rest/HttpRequestPlain.h b/lib/Rest/HttpRequestPlain.h index 9f4b56d3c1..747ae678b0 100644 --- a/lib/Rest/HttpRequestPlain.h +++ b/lib/Rest/HttpRequestPlain.h @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////// -/// @brief http request +/// @brief plain http request /// /// @file /// @@ -378,9 +378,6 @@ namespace triagens { //////////////////////////////////////////////////////////////////////////////// /// @brief sets the body -/// -/// In a POST request the body contains additional key/value pairs. The -/// function parses the body and adds the corresponding pairs. //////////////////////////////////////////////////////////////////////////////// void setBody (char const* newBody);