From e189ba42b0cd68e8806250aa33322f58e867dd41 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 9 Feb 2014 21:42:52 -0800 Subject: [PATCH 1/2] Add a simple alternative to UrlEncoder for mulipart. That is, when you want files in your postdata. --- net/url.cpp | 2 ++ net/url.h | 85 +++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 72 insertions(+), 15 deletions(-) diff --git a/net/url.cpp b/net/url.cpp index 4b1c068f57..990bf6ce17 100644 --- a/net/url.cpp +++ b/net/url.cpp @@ -4,6 +4,8 @@ const char *UrlEncoder::unreservedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~"; const char *UrlEncoder::hexChars = "0123456789ABCDEF"; +int MultipartFormDataEncoder::seq = 0; + void Url::Split() { size_t colonSlashSlash = url_.find("://"); if (colonSlashSlash == std::string::npos) { diff --git a/net/url.h b/net/url.h index 734ef0ccd2..52f6cd95e4 100644 --- a/net/url.h +++ b/net/url.h @@ -19,7 +19,7 @@ struct UrlEncoder data.reserve(256); } - void Add(const std::string &key, const std::string &value) + virtual void Add(const std::string &key, const std::string &value) { if (++paramCount > 1) data += '&'; @@ -33,15 +33,6 @@ struct UrlEncoder Add(key, std::string(value)); } - template - void AddT(const std::string &key, const char *fmt, const T value) - { - char temp[64]; - snprintf(temp, sizeof(temp), fmt, value); - temp[sizeof(temp) - 1] = '\0'; - Add(key, temp); - } - void Add(const std::string &key, const int value) { AddT(key, "%d", value); @@ -67,6 +58,21 @@ struct UrlEncoder Add(key, value ? "true" : "false"); } + const std::string &ToString() const + { + return data; + } + +protected: + template + void AddT(const std::string &key, const char *fmt, const T value) + { + char temp[64]; + snprintf(temp, sizeof(temp), fmt, value); + temp[sizeof(temp) - 1] = '\0'; + Add(key, temp); + } + // Percent encoding, aka application/x-www-form-urlencoded. void AppendEscaped(const std::string &value) { @@ -92,11 +98,6 @@ struct UrlEncoder } } - std::string &ToString() - { - return data; - } - std::string data; int paramCount; static const char *unreservedChars; @@ -104,6 +105,60 @@ struct UrlEncoder }; +// Stores everything in memory, not super efficient. +// Easy to swap out for a UrlEncoder. +struct MultipartFormDataEncoder : UrlEncoder +{ + MultipartFormDataEncoder() : UrlEncoder() + { + data.reserve(8192); + int r1 = rand(); + int r2 = rand(); + char temp[256]; + snprintf(temp, sizeof(temp), "NATIVE-DATA-BOUNDARY-%08x%08x-%d", r1, r2, seq++); + boundary = temp; + } + + virtual void Add(const std::string &key, const std::string &value) + { + Add(key, value, "", ""); + } + + void Add(const std::string &key, const std::string &value, const std::string &filename, const std::string &mimeType) + { + data += "--" + boundary + "\r\n"; + data += "Content-Disposition: form-data; name=\"" + key + "\""; + if (!filename.empty()) + data += "; filename=\"" + filename + "\""; + data += "\r\n"; + if (!mimeType.empty()) + data += "Content-Type: " + mimeType + "\r\n"; + char temp[64]; + snprintf(temp, sizeof(temp), "Content-Length: %d\r\n", (int)value.size()); + data += temp; + data += "\r\n"; + + data += value; + data += "\r\n"; + } + + void Finish() + { + data += "--" + boundary + "--"; + } + + std::string GetMimeType() const + { + return "multipart/form-data; boundary=\"" + boundary + "\""; + } + +protected: + std::string boundary; + + static int seq; +}; + + class Url { public: Url(const std::string url) : valid_(false), url_(url) { From e569903f9c68c5c4c11d707f1853c59629300379 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 9 Feb 2014 21:56:34 -0800 Subject: [PATCH 2/2] Make it just a bit more drop-in compatible. --- net/url.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/net/url.h b/net/url.h index 52f6cd95e4..c796ae46b3 100644 --- a/net/url.h +++ b/net/url.h @@ -58,11 +58,20 @@ struct UrlEncoder Add(key, value ? "true" : "false"); } + virtual void Finish() + { + } + const std::string &ToString() const { return data; } + virtual std::string GetMimeType() const + { + return "application/x-www-form-urlencoded"; + } + protected: template void AddT(const std::string &key, const char *fmt, const T value) @@ -142,12 +151,12 @@ struct MultipartFormDataEncoder : UrlEncoder data += "\r\n"; } - void Finish() + virtual void Finish() { data += "--" + boundary + "--"; } - std::string GetMimeType() const + virtual std::string GetMimeType() const { return "multipart/form-data; boundary=\"" + boundary + "\""; }