Moved http encode/decode from header to .cpp file. Review: https://reviews.apache.org/r/32338
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/f9961e35 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/f9961e35 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/f9961e35 Branch: refs/heads/master Commit: f9961e353a3ceac964ed099ba5507469d250f2dd Parents: dab7bdb Author: Benjamin Mahler <[email protected]> Authored: Tue Mar 17 12:43:10 2015 -0700 Committer: Benjamin Mahler <[email protected]> Committed: Tue Mar 24 16:47:18 2015 -0700 ---------------------------------------------------------------------- 3rdparty/libprocess/include/process/http.hpp | 109 +++------------------- 3rdparty/libprocess/src/http.cpp | 94 +++++++++++++++++++ 2 files changed, 105 insertions(+), 98 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/f9961e35/3rdparty/libprocess/include/process/http.hpp ---------------------------------------------------------------------- diff --git a/3rdparty/libprocess/include/process/http.hpp b/3rdparty/libprocess/include/process/http.hpp index a96bc28..ca1bedc 100644 --- a/3rdparty/libprocess/include/process/http.hpp +++ b/3rdparty/libprocess/include/process/http.hpp @@ -1,13 +1,8 @@ #ifndef __PROCESS_HTTP_HPP__ #define __PROCESS_HTTP_HPP__ -#include <limits.h> #include <stdint.h> -#include <unistd.h> -#include <cctype> -#include <cstdlib> -#include <iomanip> #include <queue> #include <sstream> #include <string> @@ -18,7 +13,6 @@ #include <process/pid.hpp> #include <stout/error.hpp> -#include <stout/foreach.hpp> #include <stout/hashmap.hpp> #include <stout/ip.hpp> #include <stout/json.hpp> @@ -477,6 +471,17 @@ inline Try<hashmap<std::string, std::string> > parse( } // namespace path { +// Returns a percent-encoded string according to RFC 3986. +// The input string must not already be percent encoded. +std::string encode(const std::string& s); + + +// Decodes a percent-encoded string according to RFC 3986. +// The input string must not already be decoded. +// Returns error on the occurrence of a malformed % escape in s. +Try<std::string> decode(const std::string& s); + + namespace query { // Decodes an HTTP query string into a map. For example: @@ -500,98 +505,6 @@ std::string encode(const hashmap<std::string, std::string>& query); } // namespace query { -// Returns a percent-encoded string according to RFC 3986. -// The input string must not already be percent encoded. -inline std::string encode(const std::string& s) -{ - std::ostringstream out; - - foreach (unsigned char c, s) { - switch (c) { - // Reserved characters. - case '$': - case '&': - case '+': - case ',': - case '/': - case ':': - case ';': - case '=': - case '?': - case '@': - // Unsafe characters. - case ' ': - case '"': - case '<': - case '>': - case '#': - case '%': - case '{': - case '}': - case '|': - case '\\': - case '^': - case '~': - case '[': - case ']': - case '`': - // NOTE: The cast to unsigned int is needed. - out << '%' << std::setfill('0') << std::setw(2) << std::hex - << std::uppercase << (unsigned int) c; - break; - default: - // ASCII control characters and non-ASCII characters. - // NOTE: The cast to unsigned int is needed. - if (c < 0x20 || c > 0x7F) { - out << '%' << std::setfill('0') << std::setw(2) << std::hex - << std::uppercase << (unsigned int) c; - } else { - out << c; - } - break; - } - } - - return out.str(); -} - - -// Decodes a percent-encoded string according to RFC 3986. -// The input string must not already be decoded. -// Returns error on the occurrence of a malformed % escape in s. -inline Try<std::string> decode(const std::string& s) -{ - std::ostringstream out; - - for (size_t i = 0; i < s.length(); ++i) { - if (s[i] != '%') { - out << (s[i] == '+' ? ' ' : s[i]); - continue; - } - - // We now expect two more characters: "% HEXDIG HEXDIG" - if (i + 2 >= s.length() || !isxdigit(s[i+1]) || !isxdigit(s[i+2])) { - return Error( - "Malformed % escape in '" + s + "': '" + s.substr(i, 3) + "'"); - } - - // Convert from HEXDIG HEXDIG to char value. - std::istringstream in(s.substr(i + 1, 2)); - unsigned long l; - in >> std::hex >> l; - if (l > UCHAR_MAX) { - ABORT("Unexpected conversion from hex string: " + s.substr(i + 1, 2) + - " to unsigned long: " + stringify(l)); - } - out << static_cast<unsigned char>(l); - - i += 2; - } - - return out.str(); -} - - // Represents a Uniform Resource Locator: // scheme://domain|ip:port/path?query#fragment struct URL http://git-wip-us.apache.org/repos/asf/mesos/blob/f9961e35/3rdparty/libprocess/src/http.cpp ---------------------------------------------------------------------- diff --git a/3rdparty/libprocess/src/http.cpp b/3rdparty/libprocess/src/http.cpp index 3d2b541..f56c88e 100644 --- a/3rdparty/libprocess/src/http.cpp +++ b/3rdparty/libprocess/src/http.cpp @@ -1,14 +1,18 @@ #include <arpa/inet.h> #include <stdint.h> +#include <stdlib.h> #include <algorithm> +#include <cctype> #include <cstring> #include <deque> +#include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> +#include <sstream> #include <vector> #include <process/future.hpp> @@ -30,7 +34,9 @@ #include "decoder.hpp" using std::deque; +using std::istringstream; using std::map; +using std::ostringstream; using std::queue; using std::string; using std::vector; @@ -301,6 +307,93 @@ Future<Nothing> Pipe::Writer::readerClosed() } +string encode(const string& s) +{ + ostringstream out; + + foreach (unsigned char c, s) { + switch (c) { + // Reserved characters. + case '$': + case '&': + case '+': + case ',': + case '/': + case ':': + case ';': + case '=': + case '?': + case '@': + // Unsafe characters. + case ' ': + case '"': + case '<': + case '>': + case '#': + case '%': + case '{': + case '}': + case '|': + case '\\': + case '^': + case '~': + case '[': + case ']': + case '`': + // NOTE: The cast to unsigned int is needed. + out << '%' << std::setfill('0') << std::setw(2) << std::hex + << std::uppercase << (unsigned int) c; + break; + default: + // ASCII control characters and non-ASCII characters. + // NOTE: The cast to unsigned int is needed. + if (c < 0x20 || c > 0x7F) { + out << '%' << std::setfill('0') << std::setw(2) << std::hex + << std::uppercase << (unsigned int) c; + } else { + out << c; + } + break; + } + } + + return out.str(); +} + + +Try<string> decode(const string& s) +{ + ostringstream out; + + for (size_t i = 0; i < s.length(); ++i) { + if (s[i] != '%') { + out << (s[i] == '+' ? ' ' : s[i]); + continue; + } + + // We now expect two more characters: "% HEXDIG HEXDIG" + if (i + 2 >= s.length() || !isxdigit(s[i+1]) || !isxdigit(s[i+2])) { + return Error( + "Malformed % escape in '" + s + "': '" + s.substr(i, 3) + "'"); + } + + // Convert from HEXDIG HEXDIG to char value. + istringstream in(s.substr(i + 1, 2)); + unsigned long l; + in >> std::hex >> l; + if (l > UCHAR_MAX) { + ABORT("Unexpected conversion from hex string: " + s.substr(i + 1, 2) + + " to unsigned long: " + stringify(l)); + } + out << static_cast<unsigned char>(l); + + i += 2; + } + + return out.str(); +} + + namespace query { Try<hashmap<std::string, std::string>> decode(const std::string& query) @@ -351,6 +444,7 @@ std::string encode(const hashmap<std::string, std::string>& query) } // namespace query { + namespace internal { Future<Response> decode(const string& buffer)
