ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

240 lines
6.2 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
  4. //
  5. // See accompanying file COPYING.TXT file for licensing details.
  6. //
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #define CPPCMS_SOURCE
  9. #include <cppcms/http_cookie.h>
  10. #include "http_protocol.h"
  11. #include <cppcms/cppcms_error.h>
  12. #include <booster/posix_time.h>
  13. #include <sstream>
  14. #include <locale>
  15. namespace cppcms { namespace http {
  16. struct cookie::_data { time_t expires; };
  17. bool cookie::empty() const
  18. {
  19. return name_.empty() && value_.empty();
  20. }
  21. std::string cookie::name() const { return name_; }
  22. void cookie::name(std::string v) { name_=v; }
  23. std::string cookie::value() const { return value_; }
  24. void cookie::value(std::string v) { value_=v; }
  25. std::string cookie::path() const { return path_; }
  26. void cookie::path(std::string v) { path_=v; }
  27. std::string cookie::domain() const { return domain_; }
  28. void cookie::domain(std::string v) { domain_=v; }
  29. std::string cookie::comment() const { return comment_; }
  30. void cookie::comment(std::string v) { comment_=v; }
  31. void cookie::expires(time_t when)
  32. {
  33. if(!d.get()) {
  34. d.reset(new _data());
  35. }
  36. has_expiration_=1;
  37. d->expires = when;
  38. }
  39. time_t cookie::expires() const
  40. {
  41. if(has_expiration_)
  42. return d->expires;
  43. return 0;
  44. }
  45. bool cookie::expires_defined() const
  46. {
  47. return has_expiration_ == 1;
  48. }
  49. void cookie::max_age(unsigned age)
  50. {
  51. has_age_=1;
  52. max_age_=age;
  53. }
  54. bool cookie::max_age_defined() const
  55. {
  56. return has_age_ == 1;
  57. }
  58. unsigned cookie::max_age() const
  59. {
  60. if(has_age_)
  61. return max_age_;
  62. return 0;
  63. }
  64. void cookie::browser_age()
  65. {
  66. has_age_=0;
  67. has_expiration_=0;
  68. }
  69. bool cookie::secure() const { return secure_; }
  70. void cookie::secure(bool secure) { secure_ = secure ? 1: 0; }
  71. bool cookie::httponly() const { return httponly_; }
  72. void cookie::httponly(bool httponly) { httponly_ = httponly ? 1 : 0; }
  73. bool cookie::samesite_none() const { return samesite_none_; }
  74. bool cookie::samesite_lax() const { return samesite_lax_; }
  75. bool cookie::samesite_strict() const { return samesite_strict_; }
  76. void cookie::samesite_none(bool v)
  77. {
  78. if (v) {
  79. samesite_none_ = 1;
  80. samesite_lax_ = 0;
  81. samesite_strict_ = 0;
  82. } else {
  83. samesite_none_ = 0;
  84. }
  85. }
  86. void cookie::samesite_lax(bool v)
  87. {
  88. if (v) {
  89. samesite_none_ = 0;
  90. samesite_lax_ = 1;
  91. samesite_strict_ = 0;
  92. } else {
  93. samesite_lax_ = 0;
  94. }
  95. }
  96. void cookie::samesite_strict(bool v)
  97. {
  98. if (v) {
  99. samesite_none_ = 0;
  100. samesite_lax_ = 0;
  101. samesite_strict_ = 1;
  102. } else {
  103. samesite_strict_ = 0;
  104. }
  105. }
  106. void cookie::write(std::ostream &out) const
  107. {
  108. if(name_.empty())
  109. throw cppcms_error("Cookie's name is not defined");
  110. out<<"Set-Cookie:"<<name_<<'=';
  111. if(value_.empty()) {
  112. // Nothing to do write
  113. }
  114. if(protocol::tocken(value_.begin(),value_.end())==value_.end())
  115. out<<value_;
  116. else
  117. out<<protocol::quote(value_);
  118. if(!comment_.empty())
  119. out<<"; Comment="<<protocol::quote(comment_);
  120. if(!domain_.empty())
  121. out<<"; Domain="<<domain_;
  122. if(has_age_ || has_expiration_) {
  123. std::locale l=std::locale::classic();
  124. std::stringstream ss;
  125. ss.imbue(l);
  126. if(has_age_)
  127. ss<<"; Max-Age="<<max_age_;
  128. if(has_expiration_ && d.get()) {
  129. ss<<"; Expires=";
  130. std::tm splitted = booster::ptime::universal_time(booster::ptime(d->expires));
  131. static char const format[]="%a, %d %b %Y %H:%M:%S GMT";
  132. char const *b=format;
  133. char const *e=b+sizeof(format)-1;
  134. std::use_facet<std::time_put<char> >(l).put(ss,ss,' ',&splitted,b,e);
  135. }
  136. out << ss.rdbuf();
  137. }
  138. if(!path_.empty())
  139. out<<"; Path="<<path_;
  140. if(secure_)
  141. out<<"; Secure";
  142. if(httponly_)
  143. out<<"; HttpOnly";
  144. // The samesite_*_ setters guarantee that only one of the following is set.
  145. if(samesite_none_)
  146. out<<"; SameSite=None";
  147. if(samesite_lax_)
  148. out<<"; SameSite=Lax";
  149. if(samesite_strict_)
  150. out<<"; SameSite=Strict";
  151. out<<"; Version=1";
  152. }
  153. std::ostream &operator<<(std::ostream &out,cookie const &c)
  154. {
  155. c.write(out);
  156. return out;
  157. }
  158. cookie::cookie(std::string name,std::string value) :
  159. name_(name), value_(value), secure_(0), has_age_(0), has_expiration_(0), httponly_(0), samesite_none_(0), samesite_lax_(0), samesite_strict_(0)
  160. {
  161. }
  162. cookie::cookie(std::string name,std::string value,unsigned age) :
  163. name_(name), value_(value), max_age_(age), secure_(0), has_age_(1), has_expiration_(0), httponly_(0), samesite_none_(0), samesite_lax_(0), samesite_strict_(0)
  164. {
  165. }
  166. cookie::cookie(std::string name,std::string value,unsigned age,std::string path,std::string domain,std::string comment) :
  167. name_(name), value_(value), path_(path),domain_(domain),comment_(comment),max_age_(age), secure_(0), has_age_(1), has_expiration_(0), httponly_(0), samesite_none_(0), samesite_lax_(0), samesite_strict_(0)
  168. {
  169. }
  170. cookie::cookie(std::string name,std::string value,std::string path,std::string domain,std::string comment) :
  171. name_(name), value_(value), path_(path),domain_(domain),comment_(comment), secure_(0), has_age_(0), has_expiration_(0), httponly_(0), samesite_none_(0), samesite_lax_(0), samesite_strict_(0)
  172. {
  173. }
  174. cookie::cookie(cookie const &other) :
  175. d(other.d),
  176. name_(other.name_),
  177. value_(other.value_),
  178. path_(other.path_),
  179. domain_(other.domain_),
  180. comment_(other.comment_),
  181. max_age_(other.max_age_),
  182. secure_(other.secure_),
  183. has_age_(other.has_age_),
  184. has_expiration_(other.has_expiration_),
  185. httponly_(other.httponly_),
  186. samesite_none_(other.samesite_none_),
  187. samesite_lax_(other.samesite_lax_),
  188. samesite_strict_(other.samesite_strict_)
  189. {
  190. }
  191. cookie const &cookie::operator=(cookie const &other)
  192. {
  193. d=other.d;
  194. name_=other.name_;
  195. value_=other.value_;
  196. path_=other.path_;
  197. domain_=other.domain_;
  198. comment_=other.comment_;
  199. max_age_=other.max_age_;
  200. secure_=other.secure_;
  201. has_age_=other.has_age_;
  202. has_expiration_ = other.has_expiration_;
  203. httponly_ = other.httponly_;
  204. samesite_none_ = other.samesite_none_;
  205. samesite_lax_ = other.samesite_lax_;
  206. samesite_strict_ = other.samesite_strict_;
  207. return *this;
  208. }
  209. cookie::cookie() : secure_(0), has_age_(0), has_expiration_(0), httponly_(0), samesite_none_(0), samesite_lax_(0), samesite_strict_(0) {}
  210. cookie::~cookie() {}
  211. } } // cppcms::http