diff options
-rw-r--r-- | icespider/core/Jamfile.jam | 2 | ||||
-rw-r--r-- | icespider/core/hextable.c (renamed from icespider/fcgi/hextable.c) | 0 | ||||
-rw-r--r-- | icespider/core/ihttpRequest.cpp | 29 | ||||
-rw-r--r-- | icespider/core/ihttpRequest.h | 5 | ||||
-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.jam | 2 | ||||
-rw-r--r-- | icespider/unittests/Jamfile.jam | 2 | ||||
-rw-r--r-- | icespider/unittests/testFcgi.cpp | 7 |
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(); |