xp-framework / http

HTTP protocol support for the XP Framework
2 stars 2 forks source link

Fix for proxy handling in SSLSocketHttpTransport and CurlHttpTransport #25

Closed patzerr closed 4 years ago

patzerr commented 4 years ago

Hi, we needed the proxy functionality and realized there were some bugs:

Other things i missed:

hth

thekid commented 4 years ago

Environment setup

Step 1: Installed local Squid proxy ✅ Step 2: Verified it via curl ✅ :

$ https_proxy=localhost:3128 curl -iI https://thekid.de/
HTTP/1.1 200 Connection established

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 6113
Connection: keep-alive
Keep-Alive: timeout=15
Date: Tue, 24 Dec 2019 11:42:54 GMT
Server: Apache
Last-Modified: Wed, 10 Jan 2018 17:16:51 GMT
ETag: "17e1-5626f327566c0"
Accept-Ranges: bytes

Test script

head.script.php:

<?php

use peer\http\HttpConnection;
use util\cmd\Console;
use util\log\Logging;

$c= new HttpConnection($argv[1]);
$c->setTrace(Logging::all()->toConsole());
$c->head();

Run with ext/openssl:

$ https_proxy=localhost:3128 xp -m ../logging/ head.script.php https://thekid.de/
[12:47:34 13200  info] >>> CONNECT thekid.de:443 HTTP/1.1
[12:47:34 13200  info] <<< HTTP/1.1 200 Connection established

[12:47:34 13200 debug] @@@ Enabling tls:// cryptography
[12:47:34 13200  info] >>> HEAD / HTTP/1.1
Connection: close
Host: thekid.de

[12:47:34 13200  info] <<< HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 6113
Connection: close
Date: Tue, 24 Dec 2019 11:47:31 GMT
Server: Apache
Last-Modified: Wed, 10 Jan 2018 17:16:51 GMT
ETag: "17e1-5626f327566c0"
Accept-Ranges: bytes

Run with ext/curl:

$ https_proxy=localhost:3128 xp -m ../logging/ head.script.php https://thekid.de/
[12:49:17 13284  info] >>> HEAD / HTTP/1.1
Connection: close
Host: thekid.de

Uncaught exception: Exception lang.FormatException ("" is not a valid HTTP response [-1])
  at peer.http.CurlHttpTransport::send() [line 122 of CurlHttpTransport.class.php] 
  Undefined property: peer\http\CurlHttpTransport::$handle
# ...

Okay, I see why you used curl_init() above.

thekid commented 4 years ago

Okay, I see why you used curl_init() above.

Fixed in xp-framework/http@91e84d95bd64bb4f91d85ebfbd8a115ee6d15650

thekid commented 4 years ago

✅ Released the CURL fixes in https://github.com/xp-framework/http/releases/tag/v9.1.3

thekid commented 4 years ago

@patzerr - could you please explain with an example script how to reproduce this:

SSLSocketHttpTransport encryption algorithm check needed a new connection for each try (foreach in "enable" didn't work) that's why SSLSocketHttpTransport::proxy may return a new peer.Socket

thekid commented 4 years ago

Okay, the "flags" parameter to stream_socket_enable_crypto() is meant to be used as a bitfield, see https://github.com/php/php-src/blob/PHP-7.4.0/main/streams/php_stream_transport.h#L166. Rewrote code base to adapt to this in xp-framework/http@387d48f4fce0c07d14e2ef2cc2c1927d346819da

thekid commented 4 years ago

curl.script.php:

<?php

use peer\http\HttpConnection;
use util\cmd\Console;
use util\log\Logging;

$c= new HttpConnection($argv[2]);
$c->setTrace(Logging::all()->toConsole());
$c->request($argv[1]);

Run with ext/openssl:

$ https_proxy=localhost:3128 xp -m ../logging/ curl.script.php head https://thekid.de/
[16:54:56 11028  info] >>> CONNECT thekid.de:443 HTTP/1.1
[16:54:56 11028  info] <<< HTTP/1.1 200 Connection established

[16:54:56 11028 debug] @@@ Enabled cryptography: [
  protocol => "TLSv1.2"
  cipher_name => "ECDHE-RSA-AES256-GCM-SHA384"
  cipher_bits => 256
  cipher_version => "TLSv1.2"
]
[16:54:56 11028  info] >>> HEAD / HTTP/1.1
Connection: close
Host: thekid.de

[16:54:56 11028  info] <<< HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 6113
Connection: close
Date: Tue, 24 Dec 2019 15:54:53 GMT
Server: Apache
Last-Modified: Wed, 10 Jan 2018 17:16:51 GMT
ETag: "17e1-5626f327566c0"
Accept-Ranges: bytes

Run with ext/openssl and a specific crypto method which the server does not support:

$ https_proxy=localhost:3128 xp -m ../logging/ curl.script.php head https+sslv3://thekid.de/
[16:56:46  1148  info] >>> CONNECT thekid.de:443 HTTP/1.1
[16:56:46  1148  info] <<< HTTP/1.1 200 Connection established

Uncaught exception: Exception io.IOException (Cannot establish secure connection, tried sslv3)
  at <main>::stream_socket_enable_crypto() [line 86 of SSLSocketHttpTransport.class.php]
  stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages:
  error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
  # ...
thekid commented 4 years ago

✅ Fix released in https://github.com/xp-framework/http/releases/tag/v9.1.4

patzerr commented 4 years ago

Hi, first of all, sorry for the late reply. Second, thanks for the hint about the global gitignore.

My testing was done manually in an environment where the use of a proxy is enforced. That is where the need to use this feature originated from.