Skip to content

Commit

Permalink
Add a URLEncode function to HTTPQueryDecoder.
Browse files Browse the repository at this point in the history
Useful for encoding request parameters, especially for Amazon SimpleDB.
  • Loading branch information
qris committed Nov 28, 2015
1 parent 41b93dc commit 6c5796b
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 3 deletions.
42 changes: 41 additions & 1 deletion lib/httpserver/HTTPQueryDecoder.cpp
Expand Up @@ -9,7 +9,8 @@

#include "Box.h"

#include <stdlib.h>
#include <cstdlib>
#include <ostream>

#include "HTTPQueryDecoder.h"

Expand Down Expand Up @@ -157,3 +158,42 @@ void HTTPQueryDecoder::Finish()
}


// --------------------------------------------------------------------------
//
// Function
// Name: HTTPQueryDecoder::URLEncode()
// Purpose: URL-encode a value according to Amazon's rules,
// which are similar to RFC 3986.
// Created: 2015-11-15
//
// --------------------------------------------------------------------------

std::string HTTPQueryDecoder::URLEncode(const std::string& value)
{
std::ostringstream out;
for(std::string::const_iterator i = value.begin(); i != value.end(); i++)
{
// Do not URL encode any of the unreserved characters that RFC 3986
// defines: A-Z, a-z, 0-9, hyphen ( - ), underscore ( _ ), period ( . ),
// and tilde ( ~ ).
if(std::isalnum(*i) || *i == '-' || *i == '_' || *i == '.' || *i == '~')
{
out << *i;
}
else
{
// Percent encode all other characters with %XY, where X and Y are
// hex characters 0-9 and uppercase A-F.
out << "%" <<
std::hex <<
std::uppercase <<
std::internal <<
std::setw(2) <<
std::setfill('0') <<
(int)(unsigned char)(*i) <<
std::dec;
}
}
return out.str();
}

6 changes: 4 additions & 2 deletions lib/httpserver/HTTPQueryDecoder.h
Expand Up @@ -25,14 +25,16 @@ class HTTPQueryDecoder
public:
HTTPQueryDecoder(HTTPRequest::Query_t &rDecodeInto);
~HTTPQueryDecoder();

private:
// no copying
HTTPQueryDecoder(const HTTPQueryDecoder &);
HTTPQueryDecoder &operator=(const HTTPQueryDecoder &);
public:
HTTPQueryDecoder& operator=(const HTTPQueryDecoder &);

public:
void DecodeChunk(const char *pQueryString, int QueryStringSize);
void Finish();
static std::string URLEncode(const std::string& value);

private:
HTTPRequest::Query_t &mrDecodeInto;
Expand Down
6 changes: 6 additions & 0 deletions test/httpserver/testhttpserver.cpp
Expand Up @@ -21,6 +21,7 @@
#include <openssl/hmac.h>

#include "autogen_HTTPException.h"
#include "HTTPQueryDecoder.h"
#include "HTTPRequest.h"
#include "HTTPResponse.h"
#include "HTTPServer.h"
Expand Down Expand Up @@ -619,6 +620,11 @@ int test(int argc, const char *argv[])
TEST_THAT(exercise_s3client(client));
}

// Test the HTTPQueryDecoder::URLEncode method.
TEST_EQUAL("AZaz09-_.~", HTTPQueryDecoder::URLEncode("AZaz09-_.~"));
TEST_EQUAL("%00%01%FF",
HTTPQueryDecoder::URLEncode(std::string("\0\x01\xff", 3)));

// Kill it
TEST_THAT(StopDaemon(pid, "testfiles/s3simulator.pid",
"s3simulator.memleaks", true));
Expand Down

0 comments on commit 6c5796b

Please sign in to comment.