1
1
/* **
2
2
* ==++==
3
3
*
4
- * Copyright (c) Microsoft Corporation. All rights reserved.
4
+ * Copyright (c) Microsoft Corporation. All rights reserved.
5
5
* Licensed under the Apache License, Version 2.0 (the "License");
6
6
* you may not use this file except in compliance with the License.
7
7
* You may obtain a copy of the License at
19
19
* http_linux.cpp
20
20
*
21
21
* HTTP Library: Client-side APIs.
22
- *
22
+ *
23
23
* This file contains the implementation for Linux
24
24
*
25
25
* For the latest on this and related APIs, please see http://casablanca.codeplex.com.
@@ -95,7 +95,7 @@ namespace web { namespace http
95
95
bool is_reused () const { return m_is_reused; }
96
96
97
97
void set_keep_alive (bool keep_alive) { m_keep_alive = keep_alive; }
98
- bool keep_alive () const { return m_keep_alive; }
98
+ bool keep_alive () const { return m_keep_alive; }
99
99
tcp::socket& socket () { return m_socket; }
100
100
101
101
private:
@@ -258,29 +258,29 @@ namespace web { namespace http
258
258
}
259
259
request_context::report_error (errorcodeValue, message);
260
260
}
261
-
261
+
262
262
void set_timer (const int secs)
263
263
{
264
264
m_timeout_timer.expires_from_now (boost::posix_time::milliseconds (secs * 1000 ));
265
265
m_timeout_timer.async_wait (boost::bind (&linux_client_request_context::handle_timeout_timer, this , boost::asio::placeholders::error));
266
266
}
267
-
267
+
268
268
void reset_timer (const int secs)
269
269
{
270
270
if (m_timeout_timer.expires_from_now (boost::posix_time::milliseconds (secs * 1000 )) > 0 )
271
271
{
272
272
m_timeout_timer.async_wait (boost::bind (&linux_client_request_context::handle_timeout_timer, this , boost::asio::placeholders::error));
273
273
}
274
274
}
275
-
275
+
276
276
std::unique_ptr<boost::asio::ssl::stream<tcp::socket &> > m_ssl_stream;
277
277
uint64_t m_known_size;
278
278
bool m_needChunked;
279
279
bool m_timedout;
280
280
boost::asio::streambuf m_body_buf;
281
281
boost::asio::deadline_timer m_timeout_timer;
282
282
std::shared_ptr<linux_connection> m_connection;
283
-
283
+
284
284
#if defined(__APPLE__) || defined(ANDROID)
285
285
bool m_openssl_failed;
286
286
#endif
@@ -301,8 +301,8 @@ namespace web { namespace http
301
301
}
302
302
303
303
linux_client_request_context (
304
- const std::shared_ptr<_http_client_communicator> &client,
305
- http_request request,
304
+ const std::shared_ptr<_http_client_communicator> &client,
305
+ http_request request,
306
306
const std::shared_ptr<linux_connection> &connection);
307
307
308
308
protected:
@@ -332,7 +332,7 @@ namespace web { namespace http
332
332
{
333
333
if (request_ctx->m_request ._cancellation_token ().is_canceled ())
334
334
{
335
- request_ctx->report_error (make_error_code (std::errc::operation_canceled).value (), " Request cancelled by user." );
335
+ request_ctx->report_error (make_error_code (std::errc::operation_canceled).value (), " Request canceled by user." );
336
336
return ;
337
337
}
338
338
@@ -380,7 +380,7 @@ namespace web { namespace http
380
380
if (ctx->m_request .headers ().match (header_names::transfer_encoding, transferencoding) && transferencoding == " chunked" )
381
381
{
382
382
ctx->m_needChunked = true ;
383
- }
383
+ }
384
384
else if (!ctx->m_request .headers ().match (header_names::content_length, ctx->m_known_size ))
385
385
{
386
386
// Stream without content length is the signal of requiring transfer encoding chunked.
@@ -460,7 +460,7 @@ namespace web { namespace http
460
460
}
461
461
}
462
462
463
- void handle_resolve (const boost::system::error_code& ec, tcp::resolver::iterator endpoints, std::shared_ptr<linux_client_request_context> ctx)
463
+ void handle_resolve (const boost::system::error_code& ec, tcp::resolver::iterator endpoints, const std::shared_ptr<linux_client_request_context> & ctx)
464
464
{
465
465
if (ec)
466
466
{
@@ -500,8 +500,8 @@ namespace web { namespace http
500
500
ctx->m_timeout_timer .cancel ();
501
501
502
502
// Replace the connection. This causes old connection object to go out of scope.
503
- ctx->m_connection = m_pool.obtain ();
504
-
503
+ ctx->m_connection = m_pool.obtain ();
504
+
505
505
if (ctx->m_ssl_stream )
506
506
{
507
507
reset_ssl_stream (ctx);
@@ -521,66 +521,27 @@ namespace web { namespace http
521
521
// certificate, i.e. actual server certificate is at the '0' position in the
522
522
// certificate chain, the rest are optional intermediate certificates, followed
523
523
// finally by the root CA self signed certificate.
524
-
524
+
525
525
#if defined(__APPLE__) || defined(ANDROID)
526
+ // On OS X, iOS, and Android, OpenSSL doesn't have access to where the OS
527
+ // stores keychains. If OpenSSL fails we will doing verification at the
528
+ // end using the whole certificate chain so wait until the 'leaf' cert.
529
+ // For now return true so OpenSSL continues down the certificate chain.
526
530
if (!preverified)
527
531
{
528
532
requestCtx->m_openssl_failed = true ;
529
533
}
530
534
if (requestCtx->m_openssl_failed )
531
535
{
532
- // On OS X, iOS, and Android, OpenSSL doesn't have access to where the OS
533
- // stores keychains. If OpenSSL fails we will doing verification at the
534
- // end using the whole certificate chain so wait until the 'leaf' cert.
535
- // For now return true so OpenSSL continues down the certificate chain.
536
- X509_STORE_CTX *storeContext = verifyCtx.native_handle ();
537
- int currentDepth = X509_STORE_CTX_get_error_depth (storeContext);
538
- if (currentDepth != 0 )
539
- {
540
- return true ;
541
- }
542
-
543
- STACK_OF (X509) *certStack = X509_STORE_CTX_get_chain (storeContext);
544
- const int numCerts = sk_X509_num (certStack);
545
- if (numCerts < 0 )
546
- {
547
- return false ;
548
- }
549
-
550
- std::vector<std::string> certChain;
551
- certChain.reserve (numCerts);
552
- for (int i = 0 ; i < numCerts; ++i)
553
- {
554
- X509 *cert = sk_X509_value (certStack, i);
555
-
556
- // Encode into DER format into raw memory.
557
- int len = i2d_X509 (cert, nullptr );
558
- if (len < 0 )
559
- {
560
- return false ;
561
- }
562
-
563
- std::string certData;
564
- certData.resize (len);
565
- unsigned char * buffer = reinterpret_cast <unsigned char *>(&certData[0 ]);
566
- len = i2d_X509 (cert, &buffer);
567
- if (len < 0 )
568
- {
569
- return false ;
570
- }
571
-
572
- certChain.push_back (std::move (certData));
573
- }
574
-
575
- return verify_X509_cert_chain (certChain, m_uri.host ());
536
+ return verify_cert_chain_platform_specific (verifyCtx, m_uri.host ());
576
537
}
577
538
#endif
578
-
539
+
579
540
boost::asio::ssl::rfc2818_verification rfc2818 (m_uri.host ());
580
541
return rfc2818 (preverified, verifyCtx);
581
542
}
582
543
583
- void handle_handshake (const boost::system::error_code& ec, std::shared_ptr<linux_client_request_context> ctx)
544
+ void handle_handshake (const boost::system::error_code& ec, const std::shared_ptr<linux_client_request_context> & ctx)
584
545
{
585
546
if (!ec)
586
547
{
@@ -592,7 +553,7 @@ namespace web { namespace http
592
553
}
593
554
}
594
555
595
- void handle_write_chunked_body (const boost::system::error_code& ec, std::shared_ptr<linux_client_request_context> ctx)
556
+ void handle_write_chunked_body (const boost::system::error_code& ec, const std::shared_ptr<linux_client_request_context> & ctx)
596
557
{
597
558
if (ec)
598
559
{
@@ -664,7 +625,7 @@ namespace web { namespace http
664
625
});
665
626
}
666
627
667
- void handle_write_large_body (const boost::system::error_code& ec, std::shared_ptr<linux_client_request_context> ctx)
628
+ void handle_write_large_body (const boost::system::error_code& ec, const std::shared_ptr<linux_client_request_context> & ctx)
668
629
{
669
630
if (ec || ctx->m_uploaded >= ctx->m_known_size )
670
631
{
@@ -721,7 +682,7 @@ namespace web { namespace http
721
682
});
722
683
}
723
684
724
- void handle_write_headers (const boost::system::error_code& ec, std::shared_ptr<linux_client_request_context> ctx)
685
+ void handle_write_headers (const boost::system::error_code& ec, const std::shared_ptr<linux_client_request_context> & ctx)
725
686
{
726
687
if (ec)
727
688
{
@@ -740,7 +701,7 @@ namespace web { namespace http
740
701
}
741
702
}
742
703
743
- void handle_write_body (const boost::system::error_code& ec, std::shared_ptr<linux_client_request_context> ctx)
704
+ void handle_write_body (const boost::system::error_code& ec, const std::shared_ptr<linux_client_request_context> & ctx)
744
705
{
745
706
if (!ec)
746
707
{
@@ -776,7 +737,7 @@ namespace web { namespace http
776
737
}
777
738
}
778
739
779
- void handle_status_line (const boost::system::error_code& ec, std::shared_ptr<linux_client_request_context> ctx)
740
+ void handle_status_line (const boost::system::error_code& ec, std::shared_ptr<linux_client_request_context> & ctx)
780
741
{
781
742
if (!ec)
782
743
{
@@ -799,7 +760,7 @@ namespace web { namespace http
799
760
ctx->report_error (" Invalid HTTP status line" , ec, httpclient_errorcode_context::readheader);
800
761
return ;
801
762
}
802
-
763
+
803
764
read_headers (ctx);
804
765
}
805
766
else
@@ -916,7 +877,7 @@ namespace web { namespace http
916
877
}
917
878
918
879
template <typename ReadHandler>
919
- void async_read_until_buffersize (size_t size, ReadHandler handler, std::shared_ptr<linux_client_request_context> ctx)
880
+ void async_read_until_buffersize (size_t size, ReadHandler handler, const std::shared_ptr<linux_client_request_context> & ctx)
920
881
{
921
882
size_t size_to_read = 0 ;
922
883
if (ctx->m_body_buf .size () < size)
@@ -934,7 +895,7 @@ namespace web { namespace http
934
895
}
935
896
}
936
897
937
- void handle_chunk_header (const boost::system::error_code& ec, std::shared_ptr<linux_client_request_context> ctx)
898
+ void handle_chunk_header (const boost::system::error_code& ec, const std::shared_ptr<linux_client_request_context> & ctx)
938
899
{
939
900
if (!ec)
940
901
{
@@ -962,7 +923,7 @@ namespace web { namespace http
962
923
}
963
924
}
964
925
965
- void handle_chunk (const boost::system::error_code& ec, int to_read, std::shared_ptr<linux_client_request_context> ctx)
926
+ void handle_chunk (const boost::system::error_code& ec, int to_read, const std::shared_ptr<linux_client_request_context> & ctx)
966
927
{
967
928
if (!ec)
968
929
{
@@ -1036,7 +997,7 @@ namespace web { namespace http
1036
997
}
1037
998
}
1038
999
1039
- void handle_read_content (const boost::system::error_code& ec, std::shared_ptr<linux_client_request_context> ctx)
1000
+ void handle_read_content (const boost::system::error_code& ec, const std::shared_ptr<linux_client_request_context> & ctx)
1040
1001
{
1041
1002
auto writeBuffer = ctx->_get_writebuffer ();
1042
1003
0 commit comments