Reputation: 1192
I am trying to create a HTTPConnection
using python3 http.client
. Here is my code:
import http.client
import base64
if __name__ == '__main__':
username = "xx" # enter your username
password = "xxx" # enter your password
device_id = "00000000-00000000-00409DFF-FF7660EC" # enter device id of target
# Nothing below this line should need to be changed
# -------------------------------------------------
# create HTTP basic authentication string, this consists of
encodestring = '%s:%s' % (username, password)
auth = base64.encodebytes(encodestring.encode('utf-8'))[:-1]
# message to send to server
message = """<sci_request version="1.0">
<send_message>
<targets>
<device id="%s"/>
</targets>
<rci_request version="1.1">
<query_state/>
</rci_request>
</send_message>
</sci_request>
"""%(device_id)
webservice = http.client.HTTPConnection("login.etherios.com ", 80)
# to what URL to send the request with a given HTTP method
webservice.putrequest("POST", "/ws/sci")
# add the authorization string into the HTTP header
webservice.putheader("Authorization", "Basic %s" % auth)
webservice.putheader("Content-type", "text/xml; charset=\"UTF-8\"")
webservice.putheader("Content-length", "%d" % len(message))
webservice.endheaders()
webservice.send(message)
# get the response
statuscode, statusmessage, header = webservice.getreply()
response_body = webservice.getfile().read()
# print the output to standard out
print (statuscode, statusmessage)
print (response_body)
The error message when I run the script is
FileNotFoundError: [Errno 2] No such file or directory
the error points to line 40 (webservice.endheaders()
) which I find a bit confusing. Can anybody shed light on the error message?
Here is the full traceback:
In [47]: run import_sensor
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
/usr/lib/python3/dist-packages/IPython/utils/py3compat.py in execfile(fname, glob, loc)
74 def execfile(fname, glob, loc=None):
75 loc = loc if (loc is not None) else glob
---> 76 exec(compile(open(fname, 'rb').read(), fname, 'exec'), glob, loc)
77
78 # Refactor print statements in doctests.
/home/markus/python/precirrr-py/precirr/import_sensor.py in <module>()
38 webservice.putheader("Content-type", "text/xml; charset=\"UTF-8\"")
39 webservice.putheader("Content-length", "%d" % len(message))
---> 40 webservice.endheaders()
41 webservice.send(message)
42 # get the response
/usr/lib/python3.3/http/client.py in endheaders(self, message_body)
1055 else:
1056 raise CannotSendHeader()
-> 1057 self._send_output(message_body)
1058
1059 def request(self, method, url, body=None, headers={}):
/usr/lib/python3.3/http/client.py in _send_output(self, message_body)
900 msg += message_body
901 message_body = None
--> 902 self.send(msg)
903 if message_body is not None:
904 # message_body was not a string (i.e. it is a file), and
/usr/lib/python3.3/http/client.py in send(self, data)
838 if self.sock is None:
839 if self.auto_open:
--> 840 self.connect()
841 else:
842 raise NotConnected()
/usr/lib/python3.3/http/client.py in connect(self)
816 """Connect to the host and port specified in __init__."""
817 self.sock = socket.create_connection((self.host,self.port),
--> 818 self.timeout, self.source_address)
819 if self._tunnel_host:
820 self._tunnel()
/usr/lib/python3.3/socket.py in create_connection(address, timeout, source_address)
415 host, port = address
416 err = None
--> 417 for res in getaddrinfo(host, port, 0, SOCK_STREAM):
418 af, socktype, proto, canonname, sa = res
419 sock = None
FileNotFoundError: [Errno 2] No such file or directory
Upvotes: 1
Views: 1393
Reputation: 365597
The problem is here:
webservice = http.client.HTTPConnection("login.etherios.com ", 80)
That extra space at the end of "login.etherios.com "
means it's not a valid DNS name. For example:
>>> socket.getaddrinfo('login.etherios.com', 80, 0, socket.SOCK_STREAM)
[(2, 1, 6, '', ('108.166.22.160', 80))]
>>> socket.getaddrinfo('login.etherios.com ', 80, 0, socket.SOCK_STREAM)
gaierror: [Errno 8] nodename nor servname provided, or not known
(The unfriendly gaierror
is being translated to a friendly—but not very accurate—FileNotFoundError
farther up the chain, but that's not too important here.)
So, why are you seeing the error come up all the way down in webservice.endheaders()
? Well, Python is trying to be smart here. If it opened the socket immediately, then sent one line of data at a time as you provided it, leaving the socket sitting around in between, it would waste CPU and network resources on your machine, probably on the remote server and/or router, maybe even on the internet. It's much better to just open the connection and immediately send the whole request (or, when you have a lot of data, at least up to the end of the headers). So, Python tries to do that for you. Which means that it won't realize you've given it bad information until it actually tries to use it.
Upvotes: 1