summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2016-10-12 01:22:23 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2016-10-12 01:22:23 +0100
commit2f778d2b858361d4e2c9aeff88a184878eebdaa6 (patch)
tree053ea1b50e165cec009f71e4923a045bff17ebb0
parentTidy creation of strings from ranges (diff)
downloadicespider-2f778d2b858361d4e2c9aeff88a184878eebdaa6.tar.bz2
icespider-2f778d2b858361d4e2c9aeff88a184878eebdaa6.tar.xz
icespider-2f778d2b858361d4e2c9aeff88a184878eebdaa6.zip
Move XwwwFormUrlEncoded code into core from fcgi.
Add functions for encoding strings as well as just decoding them. Add wrapper functions for setting cookies.
-rw-r--r--icespider/core/Jamfile.jam2
-rw-r--r--icespider/core/hextable.c (renamed from icespider/fcgi/hextable.c)0
-rw-r--r--icespider/core/ihttpRequest.cpp29
-rw-r--r--icespider/core/ihttpRequest.h5
-rw-r--r--icespider/core/xwwwFormUrlEncoded.cpp (renamed from icespider/fcgi/xwwwFormUrlEncoded.cpp)34
-rw-r--r--icespider/core/xwwwFormUrlEncoded.h (renamed from icespider/fcgi/xwwwFormUrlEncoded.h)9
-rw-r--r--icespider/fcgi/Jamfile.jam2
-rw-r--r--icespider/unittests/Jamfile.jam2
-rw-r--r--icespider/unittests/testFcgi.cpp7
9 files changed, 79 insertions, 11 deletions
diff --git a/icespider/core/Jamfile.jam b/icespider/core/Jamfile.jam
index a0df519..b5712ad 100644
--- a/icespider/core/Jamfile.jam
+++ b/icespider/core/Jamfile.jam
@@ -4,7 +4,7 @@ lib boost_system ;
lib boost_filesystem ;
lib icespider-core :
- [ glob-tree *.cpp : bin ]
+ [ glob-tree *.c *.cpp : bin ]
:
<library>../common//icespider-common
<library>adhocutil
diff --git a/icespider/fcgi/hextable.c b/icespider/core/hextable.c
index 3086d49..3086d49 100644
--- a/icespider/fcgi/hextable.c
+++ b/icespider/core/hextable.c
diff --git a/icespider/core/ihttpRequest.cpp b/icespider/core/ihttpRequest.cpp
index 6f68f5f..9142b1b 100644
--- a/icespider/core/ihttpRequest.cpp
+++ b/icespider/core/ihttpRequest.cpp
@@ -2,7 +2,9 @@
#include "irouteHandler.h"
#include "util.h"
#include "exceptions.h"
+#include "xwwwFormUrlEncoded.h"
#include <boost/lexical_cast.hpp>
+#include <time.h>
namespace IceSpider {
IHttpRequest::IHttpRequest(const Core * c) :
@@ -93,6 +95,29 @@ namespace IceSpider {
}
}
+ // Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]
+ // Sat, 02 May 2009 23:38:25 GMT
+ void IHttpRequest::setCookie(const std::string & name, const std::string & value,
+ const IceUtil::Optional<std::string> & d, const IceUtil::Optional<std::string> & p, bool s,
+ IceUtil::Optional<time_t> e)
+ {
+ auto & o = getOutputStream();
+ o << "Set-Cookie: " << XWwwFormUrlEncoded::urlencode(name) <<
+ '=' << XWwwFormUrlEncoded::urlencode(value);
+ if (e) {
+ char buf[45];
+ struct tm tm;
+ memset(&tm, 0, sizeof(tm));
+ gmtime_r(&*e, &tm);
+ auto l = strftime(buf, sizeof(buf), "; expires=%a, %d %b %Y %T %Z", &tm);
+ o.write(buf, l);
+ }
+ if (d) o << "; domain=" << *d;
+ if (p) o << "; path=" << *p;
+ if (s) o << "; secure";
+ o << "\r\n";
+ }
+
template <typename T>
inline IceUtil::Optional<T> optionalLexicalCast(const IceUtil::Optional<std::string> & p)
{
@@ -109,6 +134,10 @@ namespace IceSpider {
#define getParams(T) \
+ template<> void IHttpRequest::setCookie<T>(const std::string & n, const T & v, \
+ const IceUtil::Optional<std::string> & d, const IceUtil::Optional<std::string> & p, \
+ bool s, IceUtil::Optional<time_t> e) { \
+ setCookie(n, boost::lexical_cast<std::string>(v), d, p, s, e); } \
template<> T IHttpRequest::getURLParam<T>(unsigned int idx) const { \
return wrapLexicalCast<T>(getURLParam(idx)); } \
template<> IceUtil::Optional<T> IHttpRequest::getQueryStringParam<T>(const std::string & key) const { \
diff --git a/icespider/core/ihttpRequest.h b/icespider/core/ihttpRequest.h
index 92435f4..6ead437 100644
--- a/icespider/core/ihttpRequest.h
+++ b/icespider/core/ihttpRequest.h
@@ -57,6 +57,11 @@ namespace IceSpider {
return boost::lexical_cast<T>(i->second);
}
}
+ void setCookie(const std::string &, const std::string &,
+ const IceUtil::Optional<std::string> &, const IceUtil::Optional<std::string> &, bool,
+ IceUtil::Optional<time_t>);
+ template<typename T>
+ void setCookie(const std::string &, const T &, const IceUtil::Optional<std::string> &, const IceUtil::Optional<std::string> &, bool, IceUtil::Optional<time_t>);
template<typename T>
IceUtil::Optional<T> getQueryStringParam(const std::string & key) const;
template<typename T>
diff --git a/icespider/fcgi/xwwwFormUrlEncoded.cpp b/icespider/core/xwwwFormUrlEncoded.cpp
index 345a597..8d48107 100644
--- a/icespider/fcgi/xwwwFormUrlEncoded.cpp
+++ b/icespider/core/xwwwFormUrlEncoded.cpp
@@ -1,5 +1,5 @@
#include "xwwwFormUrlEncoded.h"
-#include <exceptions.h>
+#include "exceptions.h"
#include <boost/lexical_cast.hpp>
#include <Ice/BuiltinSequences.h>
@@ -71,10 +71,40 @@ namespace IceSpider {
};
std::string
+ XWwwFormUrlEncoded::urlencode(const std::string & s)
+ {
+ return urlencode(s.begin(), s.end());
+ }
+
+ inline char hexchar(char c) { return c < 10 ? '0' + c : 'a' - 10 + c; }
+
+ std::string
+ XWwwFormUrlEncoded::urlencode(std::string::const_iterator i, std::string::const_iterator e)
+ {
+ std::string t;
+ t.reserve(std::distance(i, e));
+ while (i != e) {
+ if (*i == ' ') {
+ t += '+';
+ }
+ else if (!isalnum(*i)) {
+ t += '%';
+ t += hexchar(*i >> 4);
+ t += hexchar(*i & 0xf);
+ }
+ else {
+ t += *i;
+ }
+ ++i;
+ }
+ return t;
+ }
+
+ std::string
XWwwFormUrlEncoded::urldecode(std::string::const_iterator i, std::string::const_iterator e)
{
std::string t;
- t.reserve(&*e - &*i);
+ t.reserve(std::distance(i, e));
while (i != e) {
if (*i == '+') t += ' ';
else if (*i == '%') {
diff --git a/icespider/fcgi/xwwwFormUrlEncoded.h b/icespider/core/xwwwFormUrlEncoded.h
index 54205e3..4f6cdae 100644
--- a/icespider/fcgi/xwwwFormUrlEncoded.h
+++ b/icespider/core/xwwwFormUrlEncoded.h
@@ -1,6 +1,7 @@
#ifndef ICESPIDER_CGI_XWWWFORMURLENCODED_H
#define ICESPIDER_CGI_XWWWFORMURLENCODED_H
+#include <visibility.h>
#include <slicer/serializer.h>
#include <boost/algorithm/string/split.hpp>
@@ -12,12 +13,14 @@ namespace IceSpider {
XWwwFormUrlEncoded(std::istream & in);
void Deserialize(Slicer::ModelPartForRootPtr mp) override;
- static void iterateVars(const std::string & input, const KVh & h, const std::string & split);
+ DLL_PUBLIC static void iterateVars(const std::string & input, const KVh & h, const std::string & split);
- private:
+ DLL_PUBLIC static std::string urldecode(std::string::const_iterator s, std::string::const_iterator);
+ DLL_PUBLIC static std::string urlencode(std::string::const_iterator s, std::string::const_iterator);
+ DLL_PUBLIC static std::string urlencode(const std::string & s);
+ private:
static inline void iterateVars(const KVh & h, boost::algorithm::split_iterator<std::string::const_iterator> pi);
- static std::string urldecode(std::string::const_iterator s, std::string::const_iterator);
void iterateVars(const KVh & h);
diff --git a/icespider/fcgi/Jamfile.jam b/icespider/fcgi/Jamfile.jam
index c6c4ca0..c607ed1 100644
--- a/icespider/fcgi/Jamfile.jam
+++ b/icespider/fcgi/Jamfile.jam
@@ -2,7 +2,7 @@ lib fcgi : : <name>fcgi ;
lib fcgi++ : : <name>fcgi++ ;
lib icespider-fcgi :
- [ glob-tree *.c *.cpp : bin ]
+ [ glob-tree *.cpp : bin ]
:
<library>fcgi
<library>fcgi++
diff --git a/icespider/unittests/Jamfile.jam b/icespider/unittests/Jamfile.jam
index ba7e9c2..513f41f 100644
--- a/icespider/unittests/Jamfile.jam
+++ b/icespider/unittests/Jamfile.jam
@@ -84,8 +84,6 @@ run
testFcgi.cpp
test-fcgi.ice
../fcgi/cgiRequestBase.cpp
- ../fcgi/xwwwFormUrlEncoded.cpp
- ../fcgi/hextable.c
: : :
<slicer>yes
<define>BOOST_TEST_DYN_LINK
diff --git a/icespider/unittests/testFcgi.cpp b/icespider/unittests/testFcgi.cpp
index 2c93c32..bf8e442 100644
--- a/icespider/unittests/testFcgi.cpp
+++ b/icespider/unittests/testFcgi.cpp
@@ -13,17 +13,18 @@ class TestRequest : public IceSpider::CgiRequestBase {
initialize();
}
- // LCOV_EXCL_START we never actually read or write anything here
std::ostream & getOutputStream() const override
{
- return std::cout;
+ return out;
}
+ // LCOV_EXCL_START we never actually read or write anything here
std::istream & getInputStream() const override
{
return std::cin;
}
// LCOV_EXCL_STOP
+ mutable std::stringstream out;
};
class TestPayloadRequest : public TestRequest {
@@ -271,6 +272,8 @@ BOOST_AUTO_TEST_CASE( cookies )
BOOST_REQUIRE_EQUAL(1234, *r.IceSpider::IHttpRequest::getCookieParam<Ice::Int>("valueA"));
BOOST_REQUIRE_EQUAL("Something with spaces.", *r.IceSpider::IHttpRequest::getCookieParam<std::string>("value B"));
BOOST_REQUIRE(!r.IceSpider::IHttpRequest::getCookieParam<Ice::Int>("notAThing"));
+ r.setCookie("some int.", 1234, "www.com", "/dir", true, 1476142378);
+ BOOST_REQUIRE_EQUAL("Set-Cookie: some+int%2e=1234; expires=Mon, 10 Oct 2016 23:32:58 GMT; domain=www.com; path=/dir; secure\r\n", r.out.str());
}
BOOST_AUTO_TEST_SUITE_END();