Python Requests: IOError: [Errno 22] Invalid argument
Asked Answered
B

2

16

I am new to Python Requests and am encountering an IOError:[Errno 22] Invalid argument when I attempt a requests.get(). In short, I am attempting to connect to an internal web application using SSL and so I pass a cert/key combination per the Requests documentation.

I've spent quite a bit of time researching potential issues and saw some mention of potential SNI issues but am not savvy enough to know how I might go about remedying the issue (again, new to Requests). Appreciate any nudge in the right direction/where to dig in further (I'm guessing the urllib3 piece?)

My Code

import requests

cert_file_path = "/Users/me/Documents/cert.pem"
key_file_path = "/Users/me/Documents/key.pem"

url = "https://mydomain/path/to/something"
cert = (cert_file_path, key_file_path)
r = requests.get(url, cert=cert) 

My Error

IOError                               Traceback (most recent call last)
    <ipython-input-48-1ee4a7f23d00> in <module>()
          4 url = "https://mydomain/path/to/something"
          5 cert = (cert_file_path, key_file_path)
    ----> 6 r = requests.get(url, cert=cert)

    /Users/me/anaconda/lib/python2.7/site-packages/requests/api.pyc in get(url, **kwargs)
         66 
         67     kwargs.setdefault('allow_redirects', True)
    ---> 68     return request('get', url, **kwargs)
         69 
         70 

    /Users/me/anaconda/lib/python2.7/site-packages/requests/api.pyc in request(method, url, **kwargs)
         48 
         49     session = sessions.Session()
    ---> 50     response = session.request(method=method, url=url, **kwargs)
         51     # By explicitly closing the session, we avoid leaving sockets open which
         52     # can trigger a ResourceWarning in some cases, and look like a memory leak

    /Users/me/anaconda/lib/python2.7/site-packages/requests/sessions.pyc in request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
        462         }
        463         send_kwargs.update(settings)
    --> 464         resp = self.send(prep, **send_kwargs)
        465 
        466         return resp

    /Users/me/anaconda/lib/python2.7/site-packages/requests/sessions.pyc in send(self, request, **kwargs)
        574 
        575         # Send the request
    --> 576         r = adapter.send(request, **kwargs)
        577 
        578         # Total elapsed time of the request (approximately)

    /Users/me/anaconda/lib/python2.7/site-packages/requests/adapters.pyc in send(self, request, stream, timeout, verify, cert, proxies)
        368                     decode_content=False,
        369                     retries=self.max_retries,
    --> 370                     timeout=timeout
        371                 )
        372 

    /Users/me/anaconda/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.pyc in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, **response_kw)
        542             httplib_response = self._make_request(conn, method, url,
        543                                                   timeout=timeout_obj,
    --> 544                                                   body=body, headers=headers)
        545 
        546             # If we're going to release the connection in ``finally:``, then

    /Users/me/anaconda/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.pyc in _make_request(self, conn, method, url, timeout, **httplib_request_kw)
        339         # Trigger any extra validation we need to do.
        340         try:
    --> 341             self._validate_conn(conn)
        342         except (SocketTimeout, BaseSSLError) as e:
        343             # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout.

    /Users/me/anaconda/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.pyc in _validate_conn(self, conn)
        760         # Force connect early to allow us to validate the connection.
        761         if not getattr(conn, 'sock', None):  # AppEngine might not have  `.sock`
    --> 762             conn.connect()
        763 
        764         if not conn.is_verified:

    /Users/me/anaconda/lib/python2.7/site-packages/requests/packages/urllib3/connection.pyc in connect(self)
        236                                     ca_certs=self.ca_certs,
        237                                     server_hostname=hostname,
    --> 238                                     ssl_version=resolved_ssl_version)
        239 
        240         if self.assert_fingerprint:

    /Users/me/anaconda/lib/python2.7/site-packages/requests/packages/urllib3/util/ssl_.pyc in ssl_wrap_socket(sock, keyfile, certfile, cert_reqs, ca_certs, server_hostname, ssl_version, ciphers, ssl_context)
        261             raise
        262     if certfile:
    --> 263         context.load_cert_chain(certfile, keyfile)
        264     if HAS_SNI:  # Platform-specific: OpenSSL with enabled SNI
        265         return context.wrap_socket(sock, server_hostname=server_hostname)

    IOError: [Errno 22] Invalid argument

Environment

Python: Python 2.7.11 :: Anaconda 2.4.1 (x86_64)
Requests: 2.6.0
Mac OSX: Yosemite (10.10.5)

Bunghole answered 17/2, 2016 at 20:20 Comment(8)
Are you sure the cert and key file paths are correct, and have appropriate permission to be read by the program?Labradorite
@JohnGordon the paths are definitely correct (I got something along the lines of "invalid path" in an earlier version when I had a typo). In terms of whether the cert/key can be read I'm game to check via a different methodology to validate if there's one I can use. In previous iterations it would throw something akin to 'cert/key mismatch' or 'invalid ssl' before I got which cert/key files I needed squared awaBunghole
Are you running this program directly as yourself, or is it being executed within some other context (such as within a web server)? If the latter, make sure that the files are readable in that context.Labradorite
As a simple check, you could make a very short script that just tries to open both files, and see if it gets the same error.Labradorite
@JohnGordon running it as myself (on same box I hit the browser with w/ no issues); both files open ok from bash/terminalBunghole
check a related question there cert is a list not a tuple.Scathing
similair to @JohnGordon , or , if that you are supplementing wrong format / content, ( even file extension not always indicate what's inside , make sure you had cert in cert.pemEsau
I'll expand on @JohnGordon's question. If you do open("/Users/me/Documents/cert.pem") in the file you are trying to run, does that work?Krystinakrystle
F
1

One thing to check: The client certificate file must include all of the certificates in the certificate chain, up to and including the certificate of root CA that signed the client's certificate.

Flagon answered 15/5, 2022 at 17:55 Comment(0)
P
0

I may not be correct, but, are you sure the Python version you are using supports the arguments given in requests.get(*arguments)? Maybe update the Python version to like 3.7 and above

Pulsometer answered 17/3, 2022 at 14:42 Comment(1)
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From ReviewLeland

© 2022 - 2024 — McMap. All rights reserved.