/usr/share/doc/libpion-doc/html/http__cookie__auth_8cpp_source.html is in libpion-doc 5.0.6+dfsg-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>pion: src/http_cookie_auth.cpp Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<!-- Generated by Doxygen 1.6.1 -->
<div class="navigation" id="top">
<div class="tabs">
<ul>
<li><a href="index.html"><span>Main Page</span></a></li>
<li><a href="annotated.html"><span>Classes</span></a></li>
<li class="current"><a href="files.html"><span>Files</span></a></li>
</ul>
</div>
<div class="tabs">
<ul>
<li><a href="files.html"><span>File List</span></a></li>
</ul>
</div>
<h1>src/http_cookie_auth.cpp</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">// ---------------------------------------------------------------------</span>
<a name="l00002"></a>00002 <span class="comment">// pion: a Boost C++ framework for building lightweight HTTP interfaces</span>
<a name="l00003"></a>00003 <span class="comment">// ---------------------------------------------------------------------</span>
<a name="l00004"></a>00004 <span class="comment">// Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion)</span>
<a name="l00005"></a>00005 <span class="comment">//</span>
<a name="l00006"></a>00006 <span class="comment">// Distributed under the Boost Software License, Version 1.0.</span>
<a name="l00007"></a>00007 <span class="comment">// See http://www.boost.org/LICENSE_1_0.txt</span>
<a name="l00008"></a>00008 <span class="comment">//</span>
<a name="l00009"></a>00009
<a name="l00010"></a>00010 <span class="preprocessor">#include <boost/algorithm/string.hpp></span>
<a name="l00011"></a>00011 <span class="preprocessor">#include <pion/algorithm.hpp></span>
<a name="l00012"></a>00012 <span class="preprocessor">#include <pion/http/cookie_auth.hpp></span>
<a name="l00013"></a>00013 <span class="preprocessor">#include <pion/http/response_writer.hpp></span>
<a name="l00014"></a>00014 <span class="preprocessor">#include <pion/http/server.hpp></span>
<a name="l00015"></a>00015 <span class="preprocessor">#include <ctime></span>
<a name="l00016"></a>00016
<a name="l00017"></a>00017
<a name="l00018"></a>00018 <span class="keyword">namespace </span>pion { <span class="comment">// begin namespace pion</span>
<a name="l00019"></a>00019 <span class="keyword">namespace </span>http { <span class="comment">// begin namespace http</span>
<a name="l00020"></a>00020
<a name="l00021"></a>00021
<a name="l00022"></a>00022 <span class="comment">// static members of cookie_auth</span>
<a name="l00023"></a>00023
<a name="l00024"></a>00024 <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> cookie_auth::CACHE_EXPIRATION = 3600; <span class="comment">// 1 hour</span>
<a name="l00025"></a>00025 <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> cookie_auth::RANDOM_COOKIE_BYTES = 20;
<a name="l00026"></a>00026 <span class="keyword">const</span> std::string cookie_auth::AUTH_COOKIE_NAME = <span class="stringliteral">"pion_session_id"</span>;
<a name="l00027"></a>00027
<a name="l00028"></a>00028
<a name="l00029"></a>00029 <span class="comment">// cookie_auth member functions</span>
<a name="l00030"></a>00030
<a name="l00031"></a><a class="code" href="classpion_1_1http_1_1cookie__auth.html#a769336238f9a20b74eb29be7db6e8bd3">00031</a> <a class="code" href="classpion_1_1http_1_1cookie__auth.html#a769336238f9a20b74eb29be7db6e8bd3">cookie_auth::cookie_auth</a>(user_manager_ptr userManager,
<a name="l00032"></a>00032 <span class="keyword">const</span> std::string& login,
<a name="l00033"></a>00033 <span class="keyword">const</span> std::string& logout,
<a name="l00034"></a>00034 <span class="keyword">const</span> std::string& redirect)
<a name="l00035"></a>00035 : http::<a class="code" href="classpion_1_1http_1_1auth.html">auth</a>(userManager), m_login(login), m_logout(logout), m_redirect(redirect),
<a name="l00036"></a>00036 m_random_gen(), m_random_range(0, 255), m_random_die(m_random_gen, m_random_range),
<a name="l00037"></a>00037 m_cache_cleanup_time(boost::posix_time::second_clock::universal_time())
<a name="l00038"></a>00038 {
<a name="l00039"></a>00039 <span class="comment">// set logger for this class</span>
<a name="l00040"></a>00040 <a class="code" href="classpion_1_1http_1_1auth.html#af25a5d74ab812554d6c04379c856d019" title="sets the logger to be used">set_logger</a>(PION_GET_LOGGER(<span class="stringliteral">"pion.http.cookie_auth"</span>));
<a name="l00041"></a>00041
<a name="l00042"></a>00042 <span class="comment">// Seed random number generator with current time as time_t int value, cast to the required type.</span>
<a name="l00043"></a>00043 <span class="comment">// (Note that boost::mt19937::result_type is boost::uint32_t, and casting to an unsigned n-bit integer is</span>
<a name="l00044"></a>00044 <span class="comment">// defined by the standard to keep the lower n bits. Since ::time() returns seconds since Jan 1, 1970, </span>
<a name="l00045"></a>00045 <span class="comment">// it will be a long time before we lose any entropy here, even if time_t is a 64-bit int.)</span>
<a name="l00046"></a>00046 m_random_gen.seed(static_cast<boost::mt19937::result_type>(::time(NULL)));
<a name="l00047"></a>00047
<a name="l00048"></a>00048 <span class="comment">// generate some random numbers to increase entropy of the rng</span>
<a name="l00049"></a>00049 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> n = 0; n < 100; ++n)
<a name="l00050"></a>00050 m_random_die();
<a name="l00051"></a>00051 }
<a name="l00052"></a>00052
<a name="l00053"></a><a class="code" href="classpion_1_1http_1_1cookie__auth.html#a83a9f7e27e1c8f714f6ba79101dea498">00053</a> <span class="keywordtype">bool</span> <a class="code" href="classpion_1_1http_1_1cookie__auth.html#a83a9f7e27e1c8f714f6ba79101dea498">cookie_auth::handle_request</a>(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn)
<a name="l00054"></a>00054 {
<a name="l00055"></a>00055 <span class="keywordflow">if</span> (<a class="code" href="classpion_1_1http_1_1cookie__auth.html#a5263531417c673055b050ca76d3844a3">process_login</a>(http_request_ptr,tcp_conn)) {
<a name="l00056"></a>00056 <span class="keywordflow">return</span> <span class="keyword">false</span>; <span class="comment">// we processed login/logout request, no future processing for this request permitted</span>
<a name="l00057"></a>00057 }
<a name="l00058"></a>00058
<a name="l00059"></a>00059 <span class="keywordflow">if</span> (!<a class="code" href="classpion_1_1http_1_1auth.html#a62f9ddca03be608b7884542b0d6904f6">need_authentication</a>(http_request_ptr)) {
<a name="l00060"></a>00060 <span class="keywordflow">return</span> <span class="keyword">true</span>; <span class="comment">// this request does not require authentication</span>
<a name="l00061"></a>00061 }
<a name="l00062"></a>00062
<a name="l00063"></a>00063 <span class="comment">// check if it is redirection page.. If yes, then do not test its credentials ( as used for login)</span>
<a name="l00064"></a>00064 <span class="keywordflow">if</span> (!m_redirect.empty() && m_redirect==http_request_ptr->get_resource()) {
<a name="l00065"></a>00065 <span class="keywordflow">return</span> <span class="keyword">true</span>; <span class="comment">// this request does not require authentication</span>
<a name="l00066"></a>00066 }
<a name="l00067"></a>00067
<a name="l00068"></a>00068 <span class="comment">// check cache for expiration</span>
<a name="l00069"></a>00069 boost::posix_time::ptime time_now(boost::posix_time::second_clock::universal_time());
<a name="l00070"></a>00070 <a class="code" href="classpion_1_1http_1_1cookie__auth.html#a2ed6fd5500e68795955aedd6570328f4">expire_cache</a>(time_now);
<a name="l00071"></a>00071
<a name="l00072"></a>00072 <span class="comment">// if we are here, we need to check if access authorized...</span>
<a name="l00073"></a>00073 <span class="keyword">const</span> std::string auth_cookie(http_request_ptr->get_cookie(AUTH_COOKIE_NAME));
<a name="l00074"></a>00074 <span class="keywordflow">if</span> (! auth_cookie.empty()) {
<a name="l00075"></a>00075 <span class="comment">// check if this cookie is in user cache</span>
<a name="l00076"></a>00076 boost::mutex::scoped_lock cache_lock(m_cache_mutex);
<a name="l00077"></a>00077 user_cache_type::iterator user_cache_itr=m_user_cache.find(auth_cookie);
<a name="l00078"></a>00078 <span class="keywordflow">if</span> (user_cache_itr != m_user_cache.end()) {
<a name="l00079"></a>00079 <span class="comment">// we find those credential in our cache...</span>
<a name="l00080"></a>00080 <span class="comment">// we can approve authorization now!</span>
<a name="l00081"></a>00081 http_request_ptr->set_user(user_cache_itr->second.second);
<a name="l00082"></a>00082 <span class="comment">// and update cache timeout</span>
<a name="l00083"></a>00083 user_cache_itr->second.first = time_now;
<a name="l00084"></a>00084 <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00085"></a>00085 }
<a name="l00086"></a>00086 }
<a name="l00087"></a>00087
<a name="l00088"></a>00088 <span class="comment">// user not found</span>
<a name="l00089"></a>00089 <a class="code" href="classpion_1_1http_1_1cookie__auth.html#a290a0bfd6f886600fd7eb006a2b28e99">handle_unauthorized</a>(http_request_ptr,tcp_conn);
<a name="l00090"></a>00090 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00091"></a>00091 }
<a name="l00092"></a>00092
<a name="l00093"></a><a class="code" href="classpion_1_1http_1_1cookie__auth.html#a87eb9ebf16f524aaf672465c37299772">00093</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1cookie__auth.html#a87eb9ebf16f524aaf672465c37299772">cookie_auth::set_option</a>(<span class="keyword">const</span> std::string& name, <span class="keyword">const</span> std::string& value)
<a name="l00094"></a>00094 {
<a name="l00095"></a>00095 <span class="keywordflow">if</span> (name==<span class="stringliteral">"login"</span>)
<a name="l00096"></a>00096 m_login = value;
<a name="l00097"></a>00097 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (name==<span class="stringliteral">"logout"</span>)
<a name="l00098"></a>00098 m_logout = value;
<a name="l00099"></a>00099 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (name==<span class="stringliteral">"redirect"</span>)
<a name="l00100"></a>00100 m_redirect = value;
<a name="l00101"></a>00101 <span class="keywordflow">else</span>
<a name="l00102"></a>00102 BOOST_THROW_EXCEPTION( <a class="code" href="classpion_1_1error_1_1bad__arg.html" title="exception thrown for an invalid configuration argument or option">error::bad_arg</a>() << error::errinfo_arg_name(name) );
<a name="l00103"></a>00103 }
<a name="l00104"></a>00104
<a name="l00105"></a><a class="code" href="classpion_1_1http_1_1cookie__auth.html#a5263531417c673055b050ca76d3844a3">00105</a> <span class="keywordtype">bool</span> <a class="code" href="classpion_1_1http_1_1cookie__auth.html#a5263531417c673055b050ca76d3844a3">cookie_auth::process_login</a>(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn)
<a name="l00106"></a>00106 {
<a name="l00107"></a>00107 <span class="comment">// strip off trailing slash if the request has one</span>
<a name="l00108"></a>00108 std::string resource(<a class="code" href="classpion_1_1http_1_1server.html#a375e54d0970e5d3dfc0eb50f902cf4c9">http::server::strip_trailing_slash</a>(http_request_ptr->get_resource()));
<a name="l00109"></a>00109
<a name="l00110"></a>00110 <span class="keywordflow">if</span> (resource != m_login && resource != m_logout) {
<a name="l00111"></a>00111 <span class="keywordflow">return</span> <span class="keyword">false</span>; <span class="comment">// no login processing done</span>
<a name="l00112"></a>00112 }
<a name="l00113"></a>00113
<a name="l00114"></a>00114 std::string redirect_url = http_request_ptr->get_query(<span class="stringliteral">"url"</span>);
<a name="l00115"></a>00115 std::string new_cookie;
<a name="l00116"></a>00116 <span class="keywordtype">bool</span> delete_cookie = <span class="keyword">false</span>;
<a name="l00117"></a>00117
<a name="l00118"></a>00118 <span class="keywordflow">if</span> (resource == m_login) {
<a name="l00119"></a>00119 <span class="comment">// process login</span>
<a name="l00120"></a>00120 <span class="comment">// check username</span>
<a name="l00121"></a>00121 std::string username = http_request_ptr->get_query(<span class="stringliteral">"user"</span>);
<a name="l00122"></a>00122 std::string password = http_request_ptr->get_query(<span class="stringliteral">"pass"</span>);
<a name="l00123"></a>00123
<a name="l00124"></a>00124 <span class="comment">// match username/password</span>
<a name="l00125"></a>00125 user_ptr <a class="code" href="classpion_1_1user.html">user</a>=<a class="code" href="classpion_1_1http_1_1auth.html#a5f85a718dc74306a6f62c931d2b4bc53" title="container used to manager user objects">m_user_manager</a>->get_user(username,password);
<a name="l00126"></a>00126 <span class="keywordflow">if</span> (!user) { <span class="comment">// authentication failed, process as in case of failed authentication...</span>
<a name="l00127"></a>00127 <a class="code" href="classpion_1_1http_1_1cookie__auth.html#a290a0bfd6f886600fd7eb006a2b28e99">handle_unauthorized</a>(http_request_ptr,tcp_conn);
<a name="l00128"></a>00128 <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00129"></a>00129 }
<a name="l00130"></a>00130 <span class="comment">// ok we have a new user session, create a new cookie, add to cache</span>
<a name="l00131"></a>00131
<a name="l00132"></a>00132 <span class="comment">// create random cookie</span>
<a name="l00133"></a>00133 std::string rand_binary;
<a name="l00134"></a>00134 rand_binary.reserve(RANDOM_COOKIE_BYTES);
<a name="l00135"></a>00135 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i<RANDOM_COOKIE_BYTES ; i++) {
<a name="l00136"></a>00136 rand_binary += <span class="keyword">static_cast<</span><span class="keywordtype">unsigned</span> <span class="keywordtype">char</span><span class="keyword">></span>(m_random_die());
<a name="l00137"></a>00137 }
<a name="l00138"></a>00138 <a class="code" href="structpion_1_1algorithm.html#ae5f52e52ac349ecf20410f2ad3e257dd">algorithm::base64_encode</a>(rand_binary, new_cookie);
<a name="l00139"></a>00139
<a name="l00140"></a>00140 <span class="comment">// add new session to cache</span>
<a name="l00141"></a>00141 boost::posix_time::ptime time_now(boost::posix_time::second_clock::universal_time());
<a name="l00142"></a>00142 boost::mutex::scoped_lock cache_lock(m_cache_mutex);
<a name="l00143"></a>00143 m_user_cache.insert(std::make_pair(new_cookie,std::make_pair(time_now,user)));
<a name="l00144"></a>00144 } <span class="keywordflow">else</span> {
<a name="l00145"></a>00145 <span class="comment">// process logout sequence</span>
<a name="l00146"></a>00146 <span class="comment">// if auth cookie presented - clean cache out</span>
<a name="l00147"></a>00147 <span class="keyword">const</span> std::string auth_cookie(http_request_ptr->get_cookie(AUTH_COOKIE_NAME));
<a name="l00148"></a>00148 <span class="keywordflow">if</span> (! auth_cookie.empty()) {
<a name="l00149"></a>00149 boost::mutex::scoped_lock cache_lock(m_cache_mutex);
<a name="l00150"></a>00150 user_cache_type::iterator user_cache_itr=m_user_cache.find(auth_cookie);
<a name="l00151"></a>00151 <span class="keywordflow">if</span> (user_cache_itr!=m_user_cache.end()) {
<a name="l00152"></a>00152 m_user_cache.erase(user_cache_itr);
<a name="l00153"></a>00153 }
<a name="l00154"></a>00154 }
<a name="l00155"></a>00155 <span class="comment">// and remove cookie from browser</span>
<a name="l00156"></a>00156 delete_cookie = <span class="keyword">true</span>;
<a name="l00157"></a>00157 }
<a name="l00158"></a>00158
<a name="l00159"></a>00159 <span class="comment">// if redirect defined - send redirect</span>
<a name="l00160"></a>00160 <span class="keywordflow">if</span> (! redirect_url.empty()) {
<a name="l00161"></a>00161 <a class="code" href="classpion_1_1http_1_1cookie__auth.html#a80517399e8467252c8fb8417e794f5dd">handle_redirection</a>(http_request_ptr,tcp_conn,redirect_url,new_cookie,delete_cookie);
<a name="l00162"></a>00162 } <span class="keywordflow">else</span> {
<a name="l00163"></a>00163 <span class="comment">// otherwise - OK</span>
<a name="l00164"></a>00164 <a class="code" href="classpion_1_1http_1_1cookie__auth.html#a0c38b182c3374382f6000abb8e8d4319">handle_ok</a>(http_request_ptr,tcp_conn,new_cookie,delete_cookie);
<a name="l00165"></a>00165 }
<a name="l00166"></a>00166
<a name="l00167"></a>00167 <span class="comment">// yes, we processed login/logout somehow</span>
<a name="l00168"></a>00168 <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00169"></a>00169 }
<a name="l00170"></a>00170
<a name="l00171"></a><a class="code" href="classpion_1_1http_1_1cookie__auth.html#a290a0bfd6f886600fd7eb006a2b28e99">00171</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1cookie__auth.html#a290a0bfd6f886600fd7eb006a2b28e99">cookie_auth::handle_unauthorized</a>(http::request_ptr& http_request_ptr,
<a name="l00172"></a>00172 tcp::connection_ptr& tcp_conn)
<a name="l00173"></a>00173 {
<a name="l00174"></a>00174 <span class="comment">// if redirection option is used, send redirect</span>
<a name="l00175"></a>00175 <span class="keywordflow">if</span> (!m_redirect.empty()) {
<a name="l00176"></a>00176 <a class="code" href="classpion_1_1http_1_1cookie__auth.html#a80517399e8467252c8fb8417e794f5dd">handle_redirection</a>(http_request_ptr,tcp_conn,m_redirect,<span class="stringliteral">""</span>,<span class="keyword">false</span>);
<a name="l00177"></a>00177 <span class="keywordflow">return</span>;
<a name="l00178"></a>00178 }
<a name="l00179"></a>00179
<a name="l00180"></a>00180 <span class="comment">// authentication failed, send 401.....</span>
<a name="l00181"></a>00181 <span class="keyword">static</span> <span class="keyword">const</span> std::string CONTENT =
<a name="l00182"></a>00182 <span class="stringliteral">" <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\""</span>
<a name="l00183"></a>00183 <span class="stringliteral">"\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">"</span>
<a name="l00184"></a>00184 <span class="stringliteral">"<HTML>"</span>
<a name="l00185"></a>00185 <span class="stringliteral">"<HEAD>"</span>
<a name="l00186"></a>00186 <span class="stringliteral">"<TITLE>Error</TITLE>"</span>
<a name="l00187"></a>00187 <span class="stringliteral">"<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=ISO-8859-1\">"</span>
<a name="l00188"></a>00188 <span class="stringliteral">"</HEAD>"</span>
<a name="l00189"></a>00189 <span class="stringliteral">"<BODY><H1>401 Unauthorized.</H1></BODY>"</span>
<a name="l00190"></a>00190 <span class="stringliteral">"</HTML> "</span>;
<a name="l00191"></a>00191 http::response_writer_ptr <a class="code" href="classpion_1_1http_1_1writer.html">writer</a>(<a class="code" href="classpion_1_1http_1_1response__writer.html#a75084960d3162f724342ae947e7d07e3">http::response_writer::create</a>(tcp_conn, *http_request_ptr,
<a name="l00192"></a>00192 boost::bind(&<a class="code" href="classpion_1_1tcp_1_1connection.html#aa7ff7a6d8325c9cbfb026c1a441523fe">tcp::connection::finish</a>, tcp_conn)));
<a name="l00193"></a>00193 writer->get_response().set_status_code(http::types::RESPONSE_CODE_UNAUTHORIZED);
<a name="l00194"></a>00194 writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_UNAUTHORIZED);
<a name="l00195"></a>00195 writer->write_no_copy(CONTENT);
<a name="l00196"></a>00196 writer->send();
<a name="l00197"></a>00197 }
<a name="l00198"></a>00198
<a name="l00199"></a><a class="code" href="classpion_1_1http_1_1cookie__auth.html#a80517399e8467252c8fb8417e794f5dd">00199</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1cookie__auth.html#a80517399e8467252c8fb8417e794f5dd">cookie_auth::handle_redirection</a>(http::request_ptr& http_request_ptr,
<a name="l00200"></a>00200 tcp::connection_ptr& tcp_conn,
<a name="l00201"></a>00201 <span class="keyword">const</span> std::string &redirection_url,
<a name="l00202"></a>00202 <span class="keyword">const</span> std::string &new_cookie,
<a name="l00203"></a>00203 <span class="keywordtype">bool</span> delete_cookie
<a name="l00204"></a>00204 )
<a name="l00205"></a>00205 {
<a name="l00206"></a>00206 <span class="comment">// authentication failed, send 302.....</span>
<a name="l00207"></a>00207 <span class="keyword">static</span> <span class="keyword">const</span> std::string CONTENT =
<a name="l00208"></a>00208 <span class="stringliteral">" <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\""</span>
<a name="l00209"></a>00209 <span class="stringliteral">"\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">"</span>
<a name="l00210"></a>00210 <span class="stringliteral">"<HTML>"</span>
<a name="l00211"></a>00211 <span class="stringliteral">"<HEAD>"</span>
<a name="l00212"></a>00212 <span class="stringliteral">"<TITLE>Redirect</TITLE>"</span>
<a name="l00213"></a>00213 <span class="stringliteral">"<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=ISO-8859-1\">"</span>
<a name="l00214"></a>00214 <span class="stringliteral">"</HEAD>"</span>
<a name="l00215"></a>00215 <span class="stringliteral">"<BODY><H1>302 Found.</H1></BODY>"</span>
<a name="l00216"></a>00216 <span class="stringliteral">"</HTML> "</span>;
<a name="l00217"></a>00217 http::response_writer_ptr <a class="code" href="classpion_1_1http_1_1writer.html">writer</a>(<a class="code" href="classpion_1_1http_1_1response__writer.html#a75084960d3162f724342ae947e7d07e3">http::response_writer::create</a>(tcp_conn, *http_request_ptr,
<a name="l00218"></a>00218 boost::bind(&<a class="code" href="classpion_1_1tcp_1_1connection.html#aa7ff7a6d8325c9cbfb026c1a441523fe">tcp::connection::finish</a>, tcp_conn)));
<a name="l00219"></a>00219 writer->get_response().set_status_code(http::types::RESPONSE_CODE_FOUND);
<a name="l00220"></a>00220 writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_FOUND);
<a name="l00221"></a>00221 writer->get_response().add_header(http::types::HEADER_LOCATION, redirection_url);
<a name="l00222"></a>00222 <span class="comment">// Note: use empty pass "" while setting cookies to workaround IE/FF difference</span>
<a name="l00223"></a>00223 <span class="comment">// It is assumed that request url points to the root</span>
<a name="l00224"></a>00224 <span class="comment">// ToDo: find a better workaround</span>
<a name="l00225"></a>00225 <span class="keywordflow">if</span> (delete_cookie) {
<a name="l00226"></a>00226 <span class="comment">// remove cookie</span>
<a name="l00227"></a>00227 writer->get_response().delete_cookie(AUTH_COOKIE_NAME,<span class="stringliteral">""</span>);
<a name="l00228"></a>00228 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (!new_cookie.empty()) {
<a name="l00229"></a>00229 <span class="comment">// set up a new cookie</span>
<a name="l00230"></a>00230 writer->get_response().set_cookie(AUTH_COOKIE_NAME, new_cookie,<span class="stringliteral">""</span>);
<a name="l00231"></a>00231 }
<a name="l00232"></a>00232
<a name="l00233"></a>00233 writer->write_no_copy(CONTENT);
<a name="l00234"></a>00234 writer->send();
<a name="l00235"></a>00235 }
<a name="l00236"></a>00236
<a name="l00237"></a><a class="code" href="classpion_1_1http_1_1cookie__auth.html#a0c38b182c3374382f6000abb8e8d4319">00237</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1cookie__auth.html#a0c38b182c3374382f6000abb8e8d4319">cookie_auth::handle_ok</a>(http::request_ptr& http_request_ptr,
<a name="l00238"></a>00238 tcp::connection_ptr& tcp_conn,
<a name="l00239"></a>00239 <span class="keyword">const</span> std::string &new_cookie,
<a name="l00240"></a>00240 <span class="keywordtype">bool</span> delete_cookie
<a name="l00241"></a>00241 )
<a name="l00242"></a>00242 {
<a name="l00243"></a>00243 <span class="comment">// send 204 (No Content) response</span>
<a name="l00244"></a>00244 http::response_writer_ptr <a class="code" href="classpion_1_1http_1_1writer.html">writer</a>(<a class="code" href="classpion_1_1http_1_1response__writer.html#a75084960d3162f724342ae947e7d07e3">http::response_writer::create</a>(tcp_conn, *http_request_ptr,
<a name="l00245"></a>00245 boost::bind(&<a class="code" href="classpion_1_1tcp_1_1connection.html#aa7ff7a6d8325c9cbfb026c1a441523fe">tcp::connection::finish</a>, tcp_conn)));
<a name="l00246"></a>00246 writer->get_response().set_status_code(http::types::RESPONSE_CODE_NO_CONTENT);
<a name="l00247"></a>00247 writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_NO_CONTENT);
<a name="l00248"></a>00248 <span class="comment">// Note: use empty pass "" while setting cookies to workaround IE/FF difference</span>
<a name="l00249"></a>00249 <span class="comment">// It is assumed that request url points to the root</span>
<a name="l00250"></a>00250 <span class="comment">// ToDo: find a better workaround</span>
<a name="l00251"></a>00251 <span class="keywordflow">if</span> (delete_cookie) {
<a name="l00252"></a>00252 <span class="comment">// remove cookie</span>
<a name="l00253"></a>00253 writer->get_response().delete_cookie(AUTH_COOKIE_NAME,<span class="stringliteral">""</span>);
<a name="l00254"></a>00254 } <span class="keywordflow">else</span> <span class="keywordflow">if</span>(!new_cookie.empty()) {
<a name="l00255"></a>00255 <span class="comment">// set up a new cookie</span>
<a name="l00256"></a>00256 writer->get_response().set_cookie(AUTH_COOKIE_NAME, new_cookie,<span class="stringliteral">""</span>);
<a name="l00257"></a>00257 }
<a name="l00258"></a>00258 writer->send();
<a name="l00259"></a>00259 }
<a name="l00260"></a>00260
<a name="l00261"></a><a class="code" href="classpion_1_1http_1_1cookie__auth.html#a2ed6fd5500e68795955aedd6570328f4">00261</a> <span class="keywordtype">void</span> <a class="code" href="classpion_1_1http_1_1cookie__auth.html#a2ed6fd5500e68795955aedd6570328f4">cookie_auth::expire_cache</a>(<span class="keyword">const</span> boost::posix_time::ptime &time_now)
<a name="l00262"></a>00262 {
<a name="l00263"></a>00263 <span class="keywordflow">if</span> (time_now > m_cache_cleanup_time + boost::posix_time::seconds(CACHE_EXPIRATION)) {
<a name="l00264"></a>00264 <span class="comment">// expire cache</span>
<a name="l00265"></a>00265 boost::mutex::scoped_lock cache_lock(m_cache_mutex);
<a name="l00266"></a>00266 user_cache_type::iterator i;
<a name="l00267"></a>00267 user_cache_type::iterator next=m_user_cache.begin();
<a name="l00268"></a>00268 <span class="keywordflow">while</span> (next!=m_user_cache.end()) {
<a name="l00269"></a>00269 i=next;
<a name="l00270"></a>00270 ++next;
<a name="l00271"></a>00271 <span class="keywordflow">if</span> (time_now > i->second.first + boost::posix_time::seconds(CACHE_EXPIRATION)) {
<a name="l00272"></a>00272 <span class="comment">// ok - this is an old record.. expire it now</span>
<a name="l00273"></a>00273 m_user_cache.erase(i);
<a name="l00274"></a>00274 }
<a name="l00275"></a>00275 }
<a name="l00276"></a>00276 m_cache_cleanup_time = time_now;
<a name="l00277"></a>00277 }
<a name="l00278"></a>00278 }
<a name="l00279"></a>00279
<a name="l00280"></a>00280 } <span class="comment">// end namespace http</span>
<a name="l00281"></a>00281 } <span class="comment">// end namespace pion</span>
</pre></div></div>
<hr size="1"/><address style="text-align: right;"><small>Generated on 24 Mar 2014 for pion by
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.6.1 </small></address>
</body>
</html>
|