From a66639ae0e30b43650ff37648730aef4d684133e Mon Sep 17 00:00:00 2001 From: binary1248 Date: Sun, 27 Sep 2015 08:12:45 +0200 Subject: [PATCH] Add support for getting and setting multiple HTTP fields. (#134) --- include/SFML/Network/Http.hpp | 34 ++++++++++++++++++++++++++++++++-- src/SFML/Network/Http.cpp | 31 ++++++++++++++++++++++++++----- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/include/SFML/Network/Http.hpp b/include/SFML/Network/Http.hpp index 057b86ba..c6fc3b8a 100644 --- a/include/SFML/Network/Http.hpp +++ b/include/SFML/Network/Http.hpp @@ -35,6 +35,7 @@ #include #include #include +#include namespace sf @@ -96,6 +97,21 @@ public: //////////////////////////////////////////////////////////// void setField(const std::string& field, const std::string& value); + //////////////////////////////////////////////////////////// + /// \brief Set the values of a field + /// + /// The field entries are created if they doesn't exist. + /// The name of the field is case-insensitive. + /// By default, a request doesn't contain any fields (but the + /// mandatory fields are added later by the HTTP client when + /// sending the request). + /// + /// \param field Name of the field whose values to set + /// \param values Values of the field + /// + //////////////////////////////////////////////////////////// + void setFieldValues(const std::string& field, const std::vector& values); + //////////////////////////////////////////////////////////// /// \brief Set the request method /// @@ -173,7 +189,7 @@ public: //////////////////////////////////////////////////////////// // Types //////////////////////////////////////////////////////////// - typedef std::map FieldTable; + typedef std::map > FieldTable; //////////////////////////////////////////////////////////// // Member data @@ -256,6 +272,20 @@ public: //////////////////////////////////////////////////////////// const std::string& getField(const std::string& field) const; + //////////////////////////////////////////////////////////// + /// \brief Get the values of a field + /// + /// If the field \a field is not found in the response header, + /// an empty container is returned. This function uses + /// case-insensitive comparisons. + /// + /// \param field Name of the field whose values to get + /// + /// \return Values of the field, or empty container if not found + /// + //////////////////////////////////////////////////////////// + const std::vector& getFieldValues(const std::string& field) const; + //////////////////////////////////////////////////////////// /// \brief Get the response status code /// @@ -333,7 +363,7 @@ public: //////////////////////////////////////////////////////////// // Types //////////////////////////////////////////////////////////// - typedef std::map FieldTable; + typedef std::map > FieldTable; //////////////////////////////////////////////////////////// // Member data diff --git a/src/SFML/Network/Http.cpp b/src/SFML/Network/Http.cpp index 68737f48..89a264bd 100644 --- a/src/SFML/Network/Http.cpp +++ b/src/SFML/Network/Http.cpp @@ -61,7 +61,16 @@ Http::Request::Request(const std::string& uri, Method method, const std::string& //////////////////////////////////////////////////////////// void Http::Request::setField(const std::string& field, const std::string& value) { - m_fields[toLower(field)] = value; + std::vector values; + values.push_back(value); + setFieldValues(field, values); +} + + +//////////////////////////////////////////////////////////// +void Http::Request::setFieldValues(const std::string& field, const std::vector& values) +{ + m_fields[toLower(field)] = values; } @@ -121,7 +130,10 @@ std::string Http::Request::prepare() const // Write fields for (FieldTable::const_iterator i = m_fields.begin(); i != m_fields.end(); ++i) { - out << i->first << ": " << i->second << "\r\n"; + for (std::vector::const_iterator j = i->second.begin(); j != i->second.end(); ++j) + { + out << i->first << ": " << *j << "\r\n"; + } } // Use an extra \r\n to separate the header from the body @@ -155,9 +167,9 @@ m_minorVersion(0) const std::string& Http::Response::getField(const std::string& field) const { FieldTable::const_iterator it = m_fields.find(toLower(field)); - if (it != m_fields.end()) + if ((it != m_fields.end()) && !it->second.empty()) { - return it->second; + return it->second.front(); } else { @@ -167,6 +179,15 @@ const std::string& Http::Response::getField(const std::string& field) const } +//////////////////////////////////////////////////////////// +const std::vector& Http::Response::getFieldValues(const std::string& field) const +{ + static const std::vector empty; + FieldTable::const_iterator it = m_fields.find(toLower(field)); + return (it != m_fields.end()) ? it->second : empty; +} + + //////////////////////////////////////////////////////////// Http::Response::Status Http::Response::getStatus() const { @@ -290,7 +311,7 @@ void Http::Response::parseFields(std::istream &in) value.erase(value.size() - 1); // Add the field - m_fields[toLower(field)] = value; + m_fields[toLower(field)].push_back(value); } } }