@@ -57,18 +57,25 @@ namespace web { namespace http
57
57
}
58
58
59
59
std::unique_ptr<tcp::socket> m_socket;
60
- std::unique_ptr<boost::asio::ssl::stream<tcp::socket>> p_ssl_stream ;
60
+ std::unique_ptr<boost::asio::ssl::stream<tcp::socket>> m_ssl_stream ;
61
61
62
62
uri m_what;
63
63
size_t m_known_size;
64
64
size_t m_current_size;
65
65
bool m_needChunked;
66
66
bool m_timedout;
67
- bool m_ssl;
68
67
boost::asio::streambuf m_request_buf;
69
68
boost::asio::streambuf m_response_buf;
70
69
std::unique_ptr<boost::asio::deadline_timer> m_timer;
71
70
71
+ template <typename socket_type>
72
+ void shutdown_socket (socket_type &socket)
73
+ {
74
+ boost::system::error_code ignore;
75
+ socket.shutdown (tcp::socket::shutdown_both, ignore);
76
+ socket.close ();
77
+ }
78
+
72
79
~linux_request_context ()
73
80
{
74
81
if (m_timer)
@@ -77,17 +84,16 @@ namespace web { namespace http
77
84
m_timer.reset ();
78
85
}
79
86
80
- if (!m_ssl && m_socket)
87
+ if (m_socket)
81
88
{
82
- boost::system::error_code ignore;
83
- m_socket->shutdown (tcp::socket::shutdown_both, ignore);
84
- m_socket->close ();
89
+ shutdown_socket (*m_socket);
85
90
m_socket.reset ();
86
91
}
87
92
88
- if (m_ssl && p_ssl_stream )
93
+ if (m_ssl_stream )
89
94
{
90
- p_ssl_stream->shutdown ();
95
+ shutdown_socket (m_ssl_stream->lowest_layer ());
96
+ m_ssl_stream.reset ();
91
97
}
92
98
}
93
99
@@ -133,25 +139,27 @@ namespace web { namespace http
133
139
auto what = ctx->m_what ;
134
140
auto resource = what.resource ().to_string ();
135
141
136
- ctx->m_ssl = what.scheme () == " https" ;
137
-
138
- if (ctx->m_ssl )
142
+ if (what.scheme () == " https" )
139
143
{
140
144
boost::asio::ssl::context context (boost::asio::ssl::context::sslv23);
141
145
context.set_verify_mode (boost::asio::ssl::context::verify_none);
142
- ctx->p_ssl_stream .reset (new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(m_io_service, context));
146
+ ctx->m_ssl_stream .reset (new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(m_io_service, context));
143
147
}
144
148
else
145
149
ctx->m_socket .reset (new tcp::socket (m_io_service));
146
150
147
151
if (resource == " " ) resource = " /" ;
148
152
149
153
auto method = ctx->m_request .method ();
154
+
150
155
// stop injection of headers via method
151
156
// resource should be ok, since it's been encoded
152
157
// and host won't resolve
153
158
if (std::find (method.begin (), method.end (), ' \r ' ) != method.end ())
154
- throw std::runtime_error (" invalid method string" );
159
+ {
160
+ ctx->report_exception (std::runtime_error (" invalid method string" ));
161
+ return ;
162
+ }
155
163
156
164
auto host = what.host ();
157
165
std::ostream request_stream (&ctx->m_request_buf );
@@ -160,7 +168,7 @@ namespace web { namespace http
160
168
161
169
int port = what.port ();
162
170
if (port == 0 )
163
- port = (ctx->m_ssl ? 443 : 80 );
171
+ port = (ctx->m_ssl_stream ? 443 : 80 );
164
172
request_stream << " :" << port << CRLF;
165
173
166
174
// Check user specified transfer-encoding
@@ -183,8 +191,7 @@ namespace web { namespace http
183
191
else
184
192
{
185
193
has_body = false ;
186
- if (!ctx->m_ssl )
187
- ctx->m_request .headers ()[header_names::content_length] = U (" 0" );
194
+ ctx->m_request .headers ()[header_names::content_length] = U (" 0" );
188
195
}
189
196
}
190
197
@@ -195,9 +202,9 @@ namespace web { namespace http
195
202
196
203
request_stream << flatten_http_headers (ctx->m_request .headers ());
197
204
198
- if (!ctx->m_ssl )
199
- request_stream << " Connection: close" << CRLF; // so we can just read to EOF
200
-
205
+ if (!ctx->m_ssl_stream )
206
+ request_stream << " Connection: close" << CRLF; // so we can just read to EOF
207
+
201
208
request_stream << CRLF;
202
209
203
210
tcp::resolver::query query (host, utility::conversions::print_string (port));
@@ -206,13 +213,7 @@ namespace web { namespace http
206
213
ctx->m_timer ->expires_from_now (boost::posix_time::milliseconds (timeout));
207
214
ctx->m_timer ->async_wait (boost::bind (&linux_request_context::cancel, ctx, boost::asio::placeholders::error));
208
215
209
- if (ctx->m_ssl )
210
- {
211
- boost::asio::ip::tcp::resolver::iterator iter = m_resolver.resolve (query);
212
- boost::asio::async_connect (ctx->p_ssl_stream ->lowest_layer (), iter, boost::bind (&client::handle_connect, this , boost::asio::placeholders::error, boost::asio::placeholders::iterator, ctx));
213
- }
214
- else
215
- m_resolver.async_resolve (query, boost::bind (&client::handle_resolve, this , boost::asio::placeholders::error, boost::asio::placeholders::iterator, ctx));
216
+ m_resolver.async_resolve (query, boost::bind (&client::handle_resolve, this , boost::asio::placeholders::error, boost::asio::placeholders::iterator, ctx));
216
217
}
217
218
218
219
private:
@@ -246,11 +247,8 @@ namespace web { namespace http
246
247
else
247
248
{
248
249
auto endpoint = *endpoints;
249
- if (ctx->m_ssl )
250
- {
251
- boost::asio::ip::tcp::resolver::iterator endpoint_iterator;
252
- boost::asio::async_connect ((*(ctx->p_ssl_stream )).lowest_layer (), endpoint_iterator, boost::bind (&client::handle_connect, this , boost::asio::placeholders::error, ++endpoints, ctx));
253
- }
250
+ if (ctx->m_ssl_stream )
251
+ ctx->m_ssl_stream ->lowest_layer ().async_connect (endpoint, boost::bind (&client::handle_connect, this , boost::asio::placeholders::error, ++endpoints, ctx));
254
252
else
255
253
ctx->m_socket ->async_connect (endpoint, boost::bind (&client::handle_connect, this , boost::asio::placeholders::error, ++endpoints, ctx));
256
254
}
@@ -260,8 +258,8 @@ namespace web { namespace http
260
258
{
261
259
if (!ec)
262
260
{
263
- if (ctx->m_ssl )
264
- ctx->p_ssl_stream ->async_handshake (boost::asio::ssl::stream_base::client, boost::bind (&client::handle_handshake, this , boost::asio::placeholders::error, ctx));
261
+ if (ctx->m_ssl_stream )
262
+ ctx->m_ssl_stream ->async_handshake (boost::asio::ssl::stream_base::client, boost::bind (&client::handle_handshake, this , boost::asio::placeholders::error, ctx));
265
263
else
266
264
boost::asio::async_write (*ctx->m_socket , ctx->m_request_buf , boost::bind (&client::handle_write_request, this , boost::asio::placeholders::error, ctx));
267
265
}
@@ -271,31 +269,21 @@ namespace web { namespace http
271
269
}
272
270
else
273
271
{
274
- if (ctx->m_ssl )
275
- {
276
- ctx->report_error (" SSL Failed to connect to any resolved endpoint" , ec);
277
- return ;
278
- }
279
-
280
272
boost::system::error_code ignore;
281
273
ctx->m_socket ->shutdown (tcp::socket::shutdown_both, ignore);
282
274
ctx->m_socket ->close ();
283
275
ctx->m_socket .reset (new tcp::socket (m_io_service));
284
276
auto endpoint = *endpoints;
285
277
ctx->m_socket ->async_connect (endpoint, boost::bind (&client::handle_connect, this , boost::asio::placeholders::error, ++endpoints, ctx));
286
- }
278
+ }
287
279
}
288
280
289
281
void handle_handshake (const boost::system::error_code& ec, linux_request_context* ctx)
290
282
{
291
283
if (!ec)
292
- {
293
- boost::asio::async_write (*ctx->p_ssl_stream , ctx->m_request_buf , boost::bind (&client::handle_write_request, this , boost::asio::placeholders::error, ctx));
294
- }
284
+ boost::asio::async_write (*ctx->m_ssl_stream , ctx->m_request_buf , boost::bind (&client::handle_write_request, this , boost::asio::placeholders::error, ctx));
295
285
else
296
- {
297
- std::cout << " Error code in handle_handshake is " << ec << std::endl;
298
- }
286
+ ctx->report_error (" Error code in handle_handshake is " , ec);
299
287
}
300
288
301
289
void handle_write_chunked_body (const boost::system::error_code& ec, linux_request_context* ctx)
@@ -325,8 +313,8 @@ namespace web { namespace http
325
313
ctx->m_request_buf .consume (offset);
326
314
ctx->m_current_size += readSize;
327
315
ctx->m_uploaded += (size64_t )readSize;
328
- if (ctx->m_ssl )
329
- boost::asio::async_write (*ctx->p_ssl_stream , ctx->m_request_buf ,
316
+ if (ctx->m_ssl_stream )
317
+ boost::asio::async_write (*ctx->m_ssl_stream , ctx->m_request_buf ,
330
318
boost::bind (readSize != 0 ? &client::handle_write_chunked_body : &client::handle_write_body, this , boost::asio::placeholders::error, ctx));
331
319
else
332
320
boost::asio::async_write (*ctx->m_socket , ctx->m_request_buf ,
@@ -362,8 +350,8 @@ namespace web { namespace http
362
350
ctx->m_uploaded += (size64_t )actualSize;
363
351
ctx->m_current_size += actualSize;
364
352
ctx->m_request_buf .commit (actualSize);
365
- if (ctx->m_ssl )
366
- boost::asio::async_write (*ctx->p_ssl_stream , ctx->m_request_buf ,
353
+ if (ctx->m_ssl_stream )
354
+ boost::asio::async_write (*ctx->m_ssl_stream , ctx->m_request_buf ,
367
355
boost::bind (&client::handle_write_large_body, this , boost::asio::placeholders::error, ctx));
368
356
else
369
357
boost::asio::async_write (*ctx->m_socket , ctx->m_request_buf ,
@@ -399,8 +387,8 @@ namespace web { namespace http
399
387
}
400
388
401
389
// Read until the end of entire headers
402
- if (ctx->m_ssl )
403
- boost::asio::async_read_until (*ctx->p_ssl_stream , ctx->m_response_buf , CRLF+CRLF,
390
+ if (ctx->m_ssl_stream )
391
+ boost::asio::async_read_until (*ctx->m_ssl_stream , ctx->m_response_buf , CRLF+CRLF,
404
392
boost::bind (&client::handle_status_line, this , boost::asio::placeholders::error, ctx));
405
393
else
406
394
boost::asio::async_read_until (*ctx->m_socket , ctx->m_response_buf , CRLF+CRLF,
@@ -494,8 +482,8 @@ namespace web { namespace http
494
482
boost::bind (&client::handle_read_content, this , boost::asio::placeholders::error, ctx), ctx);
495
483
else
496
484
{
497
- if (ctx->m_ssl )
498
- boost::asio::async_read_until (*ctx->p_ssl_stream , ctx->m_response_buf , CRLF,
485
+ if (ctx->m_ssl_stream )
486
+ boost::asio::async_read_until (*ctx->m_ssl_stream , ctx->m_response_buf , CRLF,
499
487
boost::bind (&client::handle_chunk_header, this , boost::asio::placeholders::error, ctx));
500
488
else
501
489
boost::asio::async_read_until (*ctx->m_socket , ctx->m_response_buf , CRLF,
@@ -507,12 +495,12 @@ namespace web { namespace http
507
495
template <typename ReadHandler>
508
496
void async_read_until_buffersize (size_t size, ReadHandler handler, linux_request_context* ctx)
509
497
{
510
- if (ctx->m_ssl )
498
+ if (ctx->m_ssl_stream )
511
499
{
512
500
if (ctx->m_response_buf .size () >= size)
513
- boost::asio::async_read (*ctx->p_ssl_stream , ctx->m_response_buf , boost::asio::transfer_at_least (0 ), handler);
501
+ boost::asio::async_read (*ctx->m_ssl_stream , ctx->m_response_buf , boost::asio::transfer_at_least (0 ), handler);
514
502
else
515
- boost::asio::async_read (*ctx->p_ssl_stream , ctx->m_response_buf , boost::asio::transfer_at_least (size - ctx->m_response_buf .size ()), handler);
503
+ boost::asio::async_read (*ctx->m_ssl_stream , ctx->m_response_buf , boost::asio::transfer_at_least (size - ctx->m_response_buf .size ()), handler);
516
504
}
517
505
else
518
506
{
@@ -589,8 +577,8 @@ namespace web { namespace http
589
577
}
590
578
ctx->m_response_buf .consume (to_read + CRLF.size ()); // consume crlf
591
579
592
- if (ctx->m_ssl )
593
- boost::asio::async_read_until (*ctx->p_ssl_stream , ctx->m_response_buf , CRLF,
580
+ if (ctx->m_ssl_stream )
581
+ boost::asio::async_read_until (*ctx->m_ssl_stream , ctx->m_response_buf , CRLF,
594
582
boost::bind (&client::handle_chunk_header, this , boost::asio::placeholders::error, ctx));
595
583
else
596
584
boost::asio::async_read_until (*ctx->m_socket , ctx->m_response_buf , CRLF,
0 commit comments