<p dir="auto">When sending form data, values which are booleans are encoded as "True" and "False" as opposed to "true" and "false". This is because of the urllib.parse.urlencode function.<br>
Perhaps it is non standard to pass a boolean as form data, but I think this is non obvious to regular users. Maybe it should raise an exception or perform a conversion to lowercase.</p>
<h2 dir="auto">Expected Result</h2>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; data = {&quot;key&quot;: True, &quot;key2&quot;: &quot;true&quot;}
&gt;&gt;&gt; req = requests.post(&quot;http://www.google.com&quot;, data=data)
&gt;&gt;&gt; req.request.body
'key=true&amp;key2=true'"><pre class="notranslate"><code class="notranslate">&gt;&gt;&gt; data = {"key": True, "key2": "true"}
&gt;&gt;&gt; req = requests.post("http://www.google.com", data=data)
&gt;&gt;&gt; req.request.body
'key=true&amp;key2=true'
</code></pre></div>
<h2 dir="auto">Actual Result</h2>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; data = {&quot;key&quot;: True, &quot;key2&quot;: &quot;true&quot;}
&gt;&gt;&gt; req = requests.post(&quot;http://www.google.com&quot;, data=data)
&gt;&gt;&gt; req.request.body
'key=True&amp;key2=true'"><pre class="notranslate"><code class="notranslate">&gt;&gt;&gt; data = {"key": True, "key2": "true"}
&gt;&gt;&gt; req = requests.post("http://www.google.com", data=data)
&gt;&gt;&gt; req.request.body
'key=True&amp;key2=true'
</code></pre></div>
<h2 dir="auto">Reproduction Steps</h2>
<p dir="auto">Pass a dictionary with a key/value pair with a boolean value to the data param of a post.</p>
<p dir="auto">For a Squid configuration of:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="http_port 3128
https_port 3129 cert=/usr/local/opt/squid/etc/ssl/squid.crt key=/usr/local/opt/squid/etc/ssl/squid.key"><pre class="notranslate"><code class="notranslate">http_port 3128
https_port 3129 cert=/usr/local/opt/squid/etc/ssl/squid.crt key=/usr/local/opt/squid/etc/ssl/squid.key
</code></pre></div>
<p dir="auto">And test names where:</p>
<p dir="auto">The 'http_port' annotation indicates whether Squid HTTP port was used.</p>
<p dir="auto">The 'https_port' annotation indicates whether Squid HTTPS port was used.</p>
<p dir="auto">The 'scheme' annotation in test names refers to whether the scheme was part of proxy definition in proxies dictionary passed to requests</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="no_scheme --&gt; { 'https': 'localhost:3129' }
http_scheme --&gt; { 'https': 'http://localhost:3129' }
https_scheme --&gt; { 'https': 'https://localhost:3129' }"><pre class="notranslate"><code class="notranslate">no_scheme --&gt; { 'https': 'localhost:3129' }
http_scheme --&gt; { 'https': 'http://localhost:3129' }
https_scheme --&gt; { 'https': 'https://localhost:3129' }
</code></pre></div>
<p dir="auto">Results for different requests versions are:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="                    requests        0.9.3   1.2.3   2.0.0

                    no_proxy        PASS    PASS    PASS
         http_port_no_scheme        PASS    FAIL    FAIL
  http_port_with_http_scheme        PASS    PASS    PASS
 http_port_with_https_scheme        FAIL    FAIL    PASS
        https_port_no_scheme        FAIL    PASS    FAIL
 https_port_with_http_scheme        FAIL    FAIL    FAIL
https_port_with_https_scheme        PASS    PASS    FAIL"><pre class="notranslate"><code class="notranslate">                    requests        0.9.3   1.2.3   2.0.0

                    no_proxy        PASS    PASS    PASS
         http_port_no_scheme        PASS    FAIL    FAIL
  http_port_with_http_scheme        PASS    PASS    PASS
 http_port_with_https_scheme        FAIL    FAIL    PASS
        https_port_no_scheme        FAIL    PASS    FAIL
 https_port_with_http_scheme        FAIL    FAIL    FAIL
https_port_with_https_scheme        PASS    PASS    FAIL
</code></pre></div>
<p dir="auto">The problem one I am concerned about is https_port_with_https_scheme as this no longer works any more.</p>
<p dir="auto">I fully realise that http_port_with_https_scheme now works and that this presumably would use CONNECT as is the safest option, but we would have to notify all customers relying on https_port_with_https_scheme that what they used before no longer works and they will need to change their configuration they have. If they don't heed that instruction, then we will start see failed connections and complaints.</p>
<p dir="auto">BTW, it would be really good if the documentation explained the differences between all the combinations, what mechanisms they use and what represents best practice for being the safest/best to use.</p>
<p dir="auto">Test used for https_port_with_https_scheme is:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="import unittest
import requests

PROXY_HOST = 'localhost'
PROXY_HTTP_PORT = 3128
PROXY_HTTPS_PORT = 3129

REMOTE_URL = 'https://pypi.python.org/pypi'

class TestProxyingOfSSLRequests(unittest.TestCase):

    def test_proxy_via_squid_https_port_with_https_scheme(self):
        proxies = { 'https': 'https://%s:%s' % (PROXY_HOST, PROXY_HTTPS_PORT) }

        response = requests.get(REMOTE_URL, proxies=proxies)

        self.assertTrue(len(response.content) != 0)

if __name__ == '__main__':
    unittest.main()"><pre class="notranslate"><code class="notranslate">import unittest
import requests

PROXY_HOST = 'localhost'
PROXY_HTTP_PORT = 3128
PROXY_HTTPS_PORT = 3129

REMOTE_URL = 'https://pypi.python.org/pypi'

class TestProxyingOfSSLRequests(unittest.TestCase):

    def test_proxy_via_squid_https_port_with_https_scheme(self):
        proxies = { 'https': 'https://%s:%s' % (PROXY_HOST, PROXY_HTTPS_PORT) }

        response = requests.get(REMOTE_URL, proxies=proxies)

        self.assertTrue(len(response.content) != 0)

if __name__ == '__main__':
    unittest.main()
</code></pre></div>
<p dir="auto">For full set of tests and results see:</p>
<ul dir="auto">
<li><a href="https://dl.dropboxusercontent.com/u/22571016/requests-ssl-proxy.tar" rel="nofollow">https://dl.dropboxusercontent.com/u/22571016/requests-ssl-proxy.tar</a></li>
</ul>
<p dir="auto">Cheat sheet for setting up Squid on MacOS X with SSL support from our own cheat sheet is:</p>
<p dir="auto">To test proxying via SSL, the easiest thing to do is install 'squid' via 'brew' under MacOSX, but avoid the standard recipe and instead use:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="brew install https://raw.github.com/mxcl/homebrew/a7bf4c381f4e38c24fb23493a92851ea8339493e/Library/Formula/squid.rb"><pre class="notranslate"><code class="notranslate">brew install https://raw.github.com/mxcl/homebrew/a7bf4c381f4e38c24fb23493a92851ea8339493e/Library/Formula/squid.rb
</code></pre></div>
<p dir="auto">This will install 'squid' with SSL support.</p>
<p dir="auto">You can then generate a self signed certificate to use:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="cd /usr/local/opt/squid/etc
mkdir ssl
cd ssl

openssl genrsa -des3 -out squid.key 1024
openssl req -new -key squid.key -out squid.csr
cp squid.key squid.key.org
openssl rsa -in squid.key.org -out squid.key
openssl x509 -req -days 365 -in squid.csr -signkey squid.key -out squid.crt"><pre class="notranslate"><code class="notranslate">cd /usr/local/opt/squid/etc
mkdir ssl
cd ssl

openssl genrsa -des3 -out squid.key 1024
openssl req -new -key squid.key -out squid.csr
cp squid.key squid.key.org
openssl rsa -in squid.key.org -out squid.key
openssl x509 -req -days 365 -in squid.csr -signkey squid.key -out squid.crt
</code></pre></div>
<p dir="auto">Then edit the the squid configuration file at '/usr/local/opt/squid/etc/squid.conf', adding:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="https_port 3129 cert=/usr/local/opt/squid/etc/ssl/squid.crt key=/usr/local/opt/squid/etc/ssl/squid.key"><pre class="notranslate"><code class="notranslate">https_port 3129 cert=/usr/local/opt/squid/etc/ssl/squid.crt key=/usr/local/opt/squid/etc/ssl/squid.key
</code></pre></div>
<p dir="auto">Then use configuration of:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="proxy_host = localhost
proxy_port = 3129"><pre class="notranslate"><code class="notranslate">proxy_host = localhost
proxy_port = 3129
</code></pre></div>