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(); | 
