Merge pull request #195 from unknownbrackets/multipart

Add a simple alternative to UrlEncoder for mulipart
This commit is contained in:
Henrik Rydgård 2014-02-10 09:51:12 +01:00
commit cbd28980da
2 changed files with 81 additions and 15 deletions

View File

@ -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) {

View File

@ -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 <typename T>
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,30 @@ 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 <typename T>
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 +107,6 @@ struct UrlEncoder
}
}
std::string &ToString()
{
return data;
}
std::string data;
int paramCount;
static const char *unreservedChars;
@ -104,6 +114,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";
}
virtual void Finish()
{
data += "--" + boundary + "--";
}
virtual 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) {