0

I'm new to Python programming and have tried researching my issue but haven't been able to find a solution as of yet. I'm hoping someone may be able to help.

I've got a script that makes an http get call to an IP address that is used to activate or deactivate a web relay switch. The relative part of the code looks like this:

import requests
r = requests.get('http://192.168.1.100/state.xml?relayState=1&noReply=0')

The above succeeds in turning on the web relay switch but the response from the web relay causes a number of exception messages as shown below and the script stops executing. I don't need to process any response for the purposes of my script, but if I need to in order to make the script function properly, I would. My hunch is that the problem revolves around the web relay switch using xml version 1.0 instead of 1.1. I haven't been able to land on a way of forcing requests to use 1.0 yet. I'm using Python 3.6.1

Traceback (most recent call last):
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 600, in urlopen
    chunked=chunked)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 386, in _make_request
    six.raise_from(e, None)
  File "<string>", line 2, in raise_from
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 382, in _make_request
    httplib_response = conn.getresponse()
  File "C:\Program Files (x86)\Python36-32\lib\http\client.py", line 1331, in getresponse
    response.begin()
  File "C:\Program Files (x86)\Python36-32\lib\http\client.py", line 297, in begin
    version, status, reason = self._read_status()
  File "C:\Program Files (x86)\Python36-32\lib\http\client.py", line 279, in _read_status
    raise BadStatusLine(line)
http.client.BadStatusLine: <?xml version='1.0' encoding='utf-8'?>



During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\adapters.py", line 423, in send
    timeout=timeout
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 649, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\packages\urllib3\util\retry.py", line 347, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\packages\urllib3\packages\six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 600, in urlopen
    chunked=chunked)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 386, in _make_request
    six.raise_from(e, None)
  File "<string>", line 2, in raise_from
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 382, in _make_request
    httplib_response = conn.getresponse()
  File "C:\Program Files (x86)\Python36-32\lib\http\client.py", line 1331, in getresponse
    response.begin()
  File "C:\Program Files (x86)\Python36-32\lib\http\client.py", line 297, in begin
    version, status, reason = self._read_status()
  File "C:\Program Files (x86)\Python36-32\lib\http\client.py", line 279, in _read_status
    raise BadStatusLine(line)
requests.packages.urllib3.exceptions.ProtocolError: ('Connection aborted.', BadStatusLine("<?xml version='1.0' encoding='utf-8'?>\r\n",))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "E:/Software/Python/test3.py", line 3, in <module>
    r = requests.get('http://192.168.1.100/state.xml?relayState=1')
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\api.py", line 70, in get
    return request('get', url, params=params, **kwargs)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\api.py", line 56, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\sessions.py", line 488, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\sessions.py", line 609, in send
    r = adapter.send(request, **kwargs)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\adapters.py", line 473, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', BadStatusLine("<?xml version='1.0' encoding='utf-8'?>\r\n",))
>>> 
MarkK
  • 1

2 Answers2

4

I'm a technical support specialist for the manufacturer of the web relay switch product listed above. A recent support email mentioned this thread and I thought it would be good to add information for any others that may run across this.

Several older modules designed quite some time ago had limited hardware resources and did not support full HTML headers for XML responses.

The products were redesigned with newer hardware several years ago. For backwards compatibility reasons, the /state.xml response still does not have full HTML headers to accommodate those who developed software for the older hardware series.

The newer products do now support full HTML headers, but a different request must be made - /stateFull.xml .

The correct code for the original example would be as follows:

import requests
r = requests.get('http://192.168.1.100/stateFull.xml?relayState=1&noReply=0')

Note: first time submitting to StackOverflow, so I apologize for missing any conventions that are normally followed.

Russell S.
  • 41
  • 1
2

Are you sure the url should be http instead of https? That was someone's issue here: Python requests.exception.ConnectionError: connection aborted "BadStatusLine"

Otherwise, the exception implies the error is with the response from the server, which I'm assuming you don't control. You could open a support ticket with whoever controls it, or, if you're in a hurry, you could work around it by catching and ignoring the exception, which is hacky but might be acceptable to you since you don't need the response and know that your request was successful on the other end:

try:
    requests.get('http://192.168.1.100/state.xml?relayState=1&noReply=0')
except requests.exceptions.ConnectionError as err:
    if "BadStatusLine" in repr(err):
        # TODO: be a responsible developer and figure out why I get BadStatusLine
        pass
    else:
        # wasn't the error I was expecting, so raise it
        raise

For production code, I'd want to get to the bottom of the error, but during development I might be willing to do something like the following so I could move on.

Brian from QuantRocket
  • 5,268
  • 1
  • 21
  • 18
  • I'm sure that it's http. I noticed when I input the same command into my browser it returned: This XML file does not appear to have any style information associated with it. Is that a problem? I tried your code and I got the same result as previous attempts except it had the following additional error message. File "E:\Software\Python\test3.py", line 5, in except http.client.BadStatusLine: NameError: name 'http' is not defined I would be fine in using "hacky" code that works, but I'm also willing to troubleshoot this to a final solution if I have some assistance. – MarkK May 16 '17 at 04:24
  • That error is telling you that you need to import the http module. Put this at the top of your file: import http (see edited code above) – Brian from QuantRocket May 16 '17 at 13:18
  • The style message in your browser is irrelevant, that's just your browser telling you that the XML doesn't reference any XSLT stylesheet. – Brian from QuantRocket May 16 '17 at 13:20
  • I added the import http line and I still get error messages. It's a little difficult for me to pick out the most important parts of the error messages, but I think the following is what is tripping me up. – MarkK May 19 '17 at 04:26
  • File "C:\Program Files (x86)\Python36-32\lib\http\client.py", line 279, in _read_status raise BadStatusLine(line) http.client.BadStatusLine: raise BadStatusLine(line) requests.packages.urllib3.exceptions.ProtocolError: ('Connection aborted.', BadStatusLine("\r\n",)) raise ConnectionError(err, request=request) requests.exceptions.ConnectionError: ('Connection aborted.', BadStatusLine("\r\n",)) – MarkK May 19 '17 at 04:41
  • There's a chain of exceptions, and ConnectionError is the last one, not BadStatusLine. Updated my answer. I would reiterate: this is hacky. – Brian from QuantRocket May 19 '17 at 13:10
  • Thanks so much Brian! The hacky code you've provided is working perfectly for me now. Props to you. – MarkK May 20 '17 at 18:39
  • I was able to use the hacky code as well, thanks! funny that python 2.7 has no issues with the xml that's returned. – beep_check Dec 27 '18 at 16:25