This file is indexed.

/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&nbsp;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&nbsp;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 &lt;boost/algorithm/string.hpp&gt;</span>
<a name="l00011"></a>00011 <span class="preprocessor">#include &lt;pion/algorithm.hpp&gt;</span>
<a name="l00012"></a>00012 <span class="preprocessor">#include &lt;pion/http/cookie_auth.hpp&gt;</span>
<a name="l00013"></a>00013 <span class="preprocessor">#include &lt;pion/http/response_writer.hpp&gt;</span>
<a name="l00014"></a>00014 <span class="preprocessor">#include &lt;pion/http/server.hpp&gt;</span>
<a name="l00015"></a>00015 <span class="preprocessor">#include &lt;ctime&gt;</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">&quot;pion_session_id&quot;</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&amp; login,
<a name="l00033"></a>00033                                <span class="keyword">const</span> std::string&amp; logout,
<a name="l00034"></a>00034                                <span class="keyword">const</span> std::string&amp; 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">&quot;pion.http.cookie_auth&quot;</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&lt;boost::mt19937::result_type&gt;(::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 &lt; 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&amp; http_request_ptr, tcp::connection_ptr&amp; 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() &amp;&amp; m_redirect==http_request_ptr-&gt;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-&gt;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-&gt;set_user(user_cache_itr-&gt;second.second);
<a name="l00082"></a>00082             <span class="comment">// and update cache timeout</span>
<a name="l00083"></a>00083             user_cache_itr-&gt;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&amp; name, <span class="keyword">const</span> std::string&amp; value) 
<a name="l00094"></a>00094 {
<a name="l00095"></a>00095     <span class="keywordflow">if</span> (name==<span class="stringliteral">&quot;login&quot;</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">&quot;logout&quot;</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">&quot;redirect&quot;</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>() &lt;&lt; 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&amp; http_request_ptr, tcp::connection_ptr&amp; 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-&gt;get_resource()));
<a name="l00109"></a>00109 
<a name="l00110"></a>00110     <span class="keywordflow">if</span> (resource != m_login &amp;&amp; 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-&gt;get_query(<span class="stringliteral">&quot;url&quot;</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-&gt;get_query(<span class="stringliteral">&quot;user&quot;</span>);
<a name="l00122"></a>00122         std::string password = http_request_ptr-&gt;get_query(<span class="stringliteral">&quot;pass&quot;</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>-&gt;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&lt;RANDOM_COOKIE_BYTES ; i++) {
<a name="l00136"></a>00136             rand_binary += <span class="keyword">static_cast&lt;</span><span class="keywordtype">unsigned</span> <span class="keywordtype">char</span><span class="keyword">&gt;</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-&gt;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&amp; http_request_ptr,
<a name="l00172"></a>00172     tcp::connection_ptr&amp; 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">&quot;&quot;</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">&quot; &lt;!DOCTYPE HTML PUBLIC \&quot;-//W3C//DTD HTML 4.01 Transitional//EN\&quot;&quot;</span>
<a name="l00183"></a>00183         <span class="stringliteral">&quot;\&quot;http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\&quot;&gt;&quot;</span>
<a name="l00184"></a>00184         <span class="stringliteral">&quot;&lt;HTML&gt;&quot;</span>
<a name="l00185"></a>00185         <span class="stringliteral">&quot;&lt;HEAD&gt;&quot;</span>
<a name="l00186"></a>00186         <span class="stringliteral">&quot;&lt;TITLE&gt;Error&lt;/TITLE&gt;&quot;</span>
<a name="l00187"></a>00187         <span class="stringliteral">&quot;&lt;META HTTP-EQUIV=\&quot;Content-Type\&quot; CONTENT=\&quot;text/html; charset=ISO-8859-1\&quot;&gt;&quot;</span>
<a name="l00188"></a>00188         <span class="stringliteral">&quot;&lt;/HEAD&gt;&quot;</span>
<a name="l00189"></a>00189         <span class="stringliteral">&quot;&lt;BODY&gt;&lt;H1&gt;401 Unauthorized.&lt;/H1&gt;&lt;/BODY&gt;&quot;</span>
<a name="l00190"></a>00190         <span class="stringliteral">&quot;&lt;/HTML&gt; &quot;</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(&amp;<a class="code" href="classpion_1_1tcp_1_1connection.html#aa7ff7a6d8325c9cbfb026c1a441523fe">tcp::connection::finish</a>, tcp_conn)));
<a name="l00193"></a>00193     writer-&gt;get_response().set_status_code(http::types::RESPONSE_CODE_UNAUTHORIZED);
<a name="l00194"></a>00194     writer-&gt;get_response().set_status_message(http::types::RESPONSE_MESSAGE_UNAUTHORIZED);
<a name="l00195"></a>00195     writer-&gt;write_no_copy(CONTENT);
<a name="l00196"></a>00196     writer-&gt;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&amp; http_request_ptr,
<a name="l00200"></a>00200                                         tcp::connection_ptr&amp; tcp_conn,
<a name="l00201"></a>00201                                         <span class="keyword">const</span> std::string &amp;redirection_url,
<a name="l00202"></a>00202                                         <span class="keyword">const</span> std::string &amp;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">&quot; &lt;!DOCTYPE HTML PUBLIC \&quot;-//W3C//DTD HTML 4.01 Transitional//EN\&quot;&quot;</span>
<a name="l00209"></a>00209         <span class="stringliteral">&quot;\&quot;http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\&quot;&gt;&quot;</span>
<a name="l00210"></a>00210         <span class="stringliteral">&quot;&lt;HTML&gt;&quot;</span>
<a name="l00211"></a>00211         <span class="stringliteral">&quot;&lt;HEAD&gt;&quot;</span>
<a name="l00212"></a>00212         <span class="stringliteral">&quot;&lt;TITLE&gt;Redirect&lt;/TITLE&gt;&quot;</span>
<a name="l00213"></a>00213         <span class="stringliteral">&quot;&lt;META HTTP-EQUIV=\&quot;Content-Type\&quot; CONTENT=\&quot;text/html; charset=ISO-8859-1\&quot;&gt;&quot;</span>
<a name="l00214"></a>00214         <span class="stringliteral">&quot;&lt;/HEAD&gt;&quot;</span>
<a name="l00215"></a>00215         <span class="stringliteral">&quot;&lt;BODY&gt;&lt;H1&gt;302 Found.&lt;/H1&gt;&lt;/BODY&gt;&quot;</span>
<a name="l00216"></a>00216         <span class="stringliteral">&quot;&lt;/HTML&gt; &quot;</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(&amp;<a class="code" href="classpion_1_1tcp_1_1connection.html#aa7ff7a6d8325c9cbfb026c1a441523fe">tcp::connection::finish</a>, tcp_conn)));
<a name="l00219"></a>00219     writer-&gt;get_response().set_status_code(http::types::RESPONSE_CODE_FOUND);
<a name="l00220"></a>00220     writer-&gt;get_response().set_status_message(http::types::RESPONSE_MESSAGE_FOUND);
<a name="l00221"></a>00221     writer-&gt;get_response().add_header(http::types::HEADER_LOCATION, redirection_url);
<a name="l00222"></a>00222     <span class="comment">// Note: use empty pass &quot;&quot; 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-&gt;get_response().delete_cookie(AUTH_COOKIE_NAME,<span class="stringliteral">&quot;&quot;</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-&gt;get_response().set_cookie(AUTH_COOKIE_NAME, new_cookie,<span class="stringliteral">&quot;&quot;</span>);
<a name="l00231"></a>00231     }
<a name="l00232"></a>00232 
<a name="l00233"></a>00233     writer-&gt;write_no_copy(CONTENT);
<a name="l00234"></a>00234     writer-&gt;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&amp; http_request_ptr,
<a name="l00238"></a>00238                               tcp::connection_ptr&amp; tcp_conn,
<a name="l00239"></a>00239                               <span class="keyword">const</span> std::string &amp;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(&amp;<a class="code" href="classpion_1_1tcp_1_1connection.html#aa7ff7a6d8325c9cbfb026c1a441523fe">tcp::connection::finish</a>, tcp_conn)));
<a name="l00246"></a>00246     writer-&gt;get_response().set_status_code(http::types::RESPONSE_CODE_NO_CONTENT);
<a name="l00247"></a>00247     writer-&gt;get_response().set_status_message(http::types::RESPONSE_MESSAGE_NO_CONTENT);
<a name="l00248"></a>00248     <span class="comment">// Note: use empty pass &quot;&quot; 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-&gt;get_response().delete_cookie(AUTH_COOKIE_NAME,<span class="stringliteral">&quot;&quot;</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-&gt;get_response().set_cookie(AUTH_COOKIE_NAME, new_cookie,<span class="stringliteral">&quot;&quot;</span>);
<a name="l00257"></a>00257     }
<a name="l00258"></a>00258     writer-&gt;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 &amp;time_now)
<a name="l00262"></a>00262 {
<a name="l00263"></a>00263     <span class="keywordflow">if</span> (time_now &gt; 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 &gt; i-&gt;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&nbsp;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.6.1 </small></address>
</body>
</html>