Giter Club home page Giter Club logo

Comments (11)

Kane610 avatar Kane610 commented on June 24, 2024

Failing using httpx:

Session is created

self.session = httpx.AsyncClient(

Retrieving users

users = await self.request("get", PWDGRP_URL)

yield a raised transport error from
response = await self.session.request(method, url, **kwargs)

Full TCP dump capturing a failing session.
axis_v41_fw5.51_httpx.pcap.zip

These two are slightly modified to not use gather in order to be easier to compare with the synchronous flow of requests. 5.51 is failing and 5.75 is succeeding.
axis_v41_fw5.51_httpx_modified_dont_use_gather.pcap.zip
axis_v41_fw5.75_httpx_modified_dont_use_gather.pcap.zip

main.py ignores the first transport error when retrieving users because it needs admin level and main is mainly for verifying function calls.

python3 -m axis 10.0.0.254 root pass --params -D
10.0.0.254, root, pass, 80, False, True
Using selector: KqueueSelector
Connecting to Axis device
http://10.0.0.254:80/axis-cgi/pwdgrp.cgi?action=get {}
HTTP Request: GET http://10.0.0.254:80/axis-cgi/pwdgrp.cgi?action=get "HTTP/1.1 401 Unauthorized"
peer unexpectedly closed connection
Error connecting to the Axis device at 10.0.0.254
{}
http://10.0.0.254:80/axis-cgi/apidiscovery.cgi {'json': {'method': 'getApiList', 'apiVersion': '1.0', 'context': 'Axis library'}}
HTTP Request: POST http://10.0.0.254:80/axis-cgi/apidiscovery.cgi "HTTP/1.1 404 Not Found"
<Response [404 Not Found]>, 404 Client Error: Not Found for url: http://10.0.0.254:80/axis-cgi/apidiscovery.cgi
For more information check: https://httpstatuses.com/404
''
http://10.0.0.254:80/axis-cgi/param.cgi?action=list&group=root.Properties {}
http://10.0.0.254:80/axis-cgi/param.cgi?action=list&group=root.Brand {}
http://10.0.0.254:80/axis-cgi/param.cgi?action=list&group=root.StreamProfile {}
http://10.0.0.254:80/axis-cgi/param.cgi?action=list&group=root.Input {}
http://10.0.0.254:80/axis-cgi/param.cgi?action=list&group=root.IOPort {}
http://10.0.0.254:80/axis-cgi/param.cgi?action=list&group=root.Output {}
HTTP Request: GET http://10.0.0.254:80/axis-cgi/param.cgi?action=list&group=root.Properties "HTTP/1.1 401 Unauthorized"
HTTP Request: GET http://10.0.0.254:80/axis-cgi/param.cgi?action=list&group=root.Brand "HTTP/1.1 401 Unauthorized"
HTTP Request: GET http://10.0.0.254:80/axis-cgi/param.cgi?action=list&group=root.StreamProfile "HTTP/1.1 401 Unauthorized"
HTTP Request: GET http://10.0.0.254:80/axis-cgi/param.cgi?action=list&group=root.IOPort "HTTP/1.1 401 Unauthorized"
HTTP Request: GET http://10.0.0.254:80/axis-cgi/param.cgi?action=list&group=root.Input "HTTP/1.1 401 Unauthorized"
HTTP Request: GET http://10.0.0.254:80/axis-cgi/param.cgi?action=list&group=root.Output "HTTP/1.1 401 Unauthorized"
peer unexpectedly closed connection
Traceback (most recent call last):
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_exceptions.py", line 326, in map_exceptions
    yield
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_client.py", line 1502, in _send_single_request
    (status_code, headers, stream, ext,) = await transport.arequest(
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpcore/_async/connection_pool.py", line 200, in arequest
    response = await connection.arequest(
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpcore/_async/connection.py", line 100, in arequest
    return await self.connection.arequest(method, url, headers, stream, ext)
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpcore/_async/http11.py", line 72, in arequest
    ) = await self._receive_response(timeout)
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpcore/_async/http11.py", line 133, in _receive_response
    event = await self._receive_event(timeout)
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpcore/_async/http11.py", line 169, in _receive_event
    event = self.h11_state.next_event()
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/contextlib.py", line 131, in __exit__
    self.gen.throw(type, value, traceback)
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpcore/_exceptions.py", line 12, in map_exceptions
    raise to_exc(exc) from None
httpcore.RemoteProtocolError: peer unexpectedly closed connection

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/robertsv/Development/axis/axis/vapix.py", line 213, in request
    response = await self.session.request(method, url, **kwargs)
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_client.py", line 1371, in request
    response = await self.send(
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_client.py", line 1406, in send
    response = await self._send_handling_auth(
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_client.py", line 1444, in _send_handling_auth
    response = await self._send_handling_redirects(
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_client.py", line 1476, in _send_handling_redirects
    response = await self._send_single_request(request, timeout)
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_client.py", line 1502, in _send_single_request
    (status_code, headers, stream, ext,) = await transport.arequest(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/contextlib.py", line 131, in __exit__
    self.gen.throw(type, value, traceback)
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_exceptions.py", line 343, in map_exceptions
    raise mapped_exc(message, **kwargs) from exc  # type: ignore
httpx.RemoteProtocolError: peer unexpectedly closed connection

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/runpy.py", line 193, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/Users/robertsv/Development/axis/axis/__main__.py", line 99, in <module>
    asyncio.run(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/base_events.py", line 612, in run_until_complete
    return future.result()
  File "/Users/robertsv/Development/axis/axis/__main__.py", line 57, in main
    await device.vapix.initialize()
  File "/Users/robertsv/Development/axis/axis/vapix.py", line 103, in initialize
    await self.initialize_param_cgi(preload_data=False)
  File "/Users/robertsv/Development/axis/axis/vapix.py", line 161, in initialize_param_cgi
    await asyncio.gather(*tasks)
  File "/Users/robertsv/Development/axis/axis/param_cgi.py", line 80, in update_ports
    await asyncio.gather(
  File "/Users/robertsv/Development/axis/axis/api.py", line 38, in update
    raw = await self._request("get", path)
  File "/Users/robertsv/Development/axis/axis/vapix.py", line 238, in request
    raise RequestError("Connection error: {}".format(errc))
axis.errors.RequestError: Connection error: peer unexpectedly closed connection
/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_client.py:1781: UserWarning: Unclosed <httpx.AsyncClient object at 0x7fb878fffd30>. See https://www.python-httpx.org/async/#opening-and-closing-clients for details.

from axis.

Kane610 avatar Kane610 commented on June 24, 2024

Succeeding using requests

Session is created

session = requests.Session()

Retrieving users

users = self.request("get", PWDGRP_URL)
does not yield a transport error here
response = session(url, **kwargs)

TCP dump of a successful session using requests
axis_v37_fw5.51_requests.pcap.zip

from axis.

Kane610 avatar Kane610 commented on June 24, 2024

I was looking at moving from using get to post when retrieving users and noticed that this also failed, in this case both on 5.51 and 5.75. Going to even newer seems to work though.

from axis.

florimondmanca avatar florimondmanca commented on June 24, 2024

@Kane610 I'd recommend starting from a minimal test script and then ramping up to the actual code in the codebase. For example, what does a simple GET request to the device look like, does it succeed? If so, build a client like in the actual codebase, retry, and slowly make your way from there... Until you find at what point exactly things start looking off. Then share what this "minimal reproducible example" looks like, stripping away anything that doesn't make the bug go away.

If you haven't already you can review our Requests Compatibility guide in case that could give you som hints: https://www.python-httpx.org/compatibility/

from axis.

Kane610 avatar Kane610 commented on June 24, 2024

@florimondmanca absolutely i will try to reproduce it using a simple script. Indeed I followed the requests pages you'd written. And as stated above it works on newer devices so there is probably som quirk the older firmwares do that requests handle but httpx doesn't.

from axis.

Kane610 avatar Kane610 commented on June 24, 2024

@florimondmanca I've created the smallest thing to reproduce this issue, it fails as expected on some older devices and works fine on newer.

import httpx

client = httpx.Client(auth=httpx.DigestAuth("root", "pass"))
res = client.request("get", "http://10.0.0.254:80/axis-cgi/pwdgrp.cgi?action=get")
❯ python3 axis/debug.py
Traceback (most recent call last):
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_exceptions.py", line 326, in map_exceptions
    yield
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_client.py", line 861, in _send_single_request
    (status_code, headers, stream, ext) = transport.request(
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpcore/_sync/connection_pool.py", line 200, in request
    response = connection.request(
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpcore/_sync/connection.py", line 100, in request
    return self.connection.request(method, url, headers, stream, ext)
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpcore/_sync/http11.py", line 72, in request
    ) = self._receive_response(timeout)
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpcore/_sync/http11.py", line 133, in _receive_response
    event = self._receive_event(timeout)
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpcore/_sync/http11.py", line 169, in _receive_event
    event = self.h11_state.next_event()
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/contextlib.py", line 131, in __exit__
    self.gen.throw(type, value, traceback)
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpcore/_exceptions.py", line 12, in map_exceptions
    raise to_exc(exc) from None
httpcore.RemoteProtocolError: peer unexpectedly closed connection

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "axis/debug.py", line 5, in <module>
    res = client.request("get", "http://10.0.0.254:80/axis-cgi/pwdgrp.cgi?action=get")
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_client.py", line 733, in request
    return self.send(
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_client.py", line 767, in send
    response = self._send_handling_auth(
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_client.py", line 805, in _send_handling_auth
    response = self._send_handling_redirects(
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_client.py", line 837, in _send_handling_redirects
    response = self._send_single_request(request, timeout)
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_client.py", line 861, in _send_single_request
    (status_code, headers, stream, ext) = transport.request(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/contextlib.py", line 131, in __exit__
    self.gen.throw(type, value, traceback)
  File "/Users/robertsv/Development/Virtualenvs/python38/lib/python3.8/site-packages/httpx/_exceptions.py", line 343, in map_exceptions
    raise mapped_exc(message, **kwargs) from exc  # type: ignore
httpx.RemoteProtocolError: peer unexpectedly closed connection

from axis.

yuriy1337 avatar yuriy1337 commented on June 24, 2024

I'm getting the same error with:

AXIS M3004 Network Camera
Firmware version: 5.51.7.2

This the the newest firmware for this device.

from axis.

cdeler avatar cdeler commented on June 24, 2024

Hello @Kane610

I checked the PR to h11 with the real device. I mentioned the results there:

requests lib:

In [1]: import requests
In [2]: from requests.auth import HTTPDigestAuth
In [3]: url = "http://[REDACTED]/axis-cgi/pwdgrp.cgi?action=get"
In [4]: requests.get(url, auth=HTTPDigestAuth("[REDACTED]", "[REDACTED]"))
Out[4]: <Response [200]>

without fix:

In [1]: import httpx
In [2]: url = "http://[REDACTED]/axis-cgi/pwdgrp.cgi?action=get"
In [3]: auth = httpx.DigestAuth("[REDACTED]", "[REDACTED]")
In [4]: client = httpx.Client(auth=auth)
In [5]: client.get(url)
RemoteProtocolError: peer unexpectedly closed connection

with fix:

In [1]: import httpx
In [2]: url = "http://[REDACTED]/axis-cgi/pwdgrp.cgi?action=get"
In [3]: auth = httpx.DigestAuth("[REDACTED]", "[REDACTED]")
In [4]: client = httpx.Client(auth=auth)
In [5]: client.get(url)
Out[5]: <Response [200 OK]>

from axis.

Kane610 avatar Kane610 commented on June 24, 2024

Awesome! Thanks for the update @cdeler

from axis.

Kane610 avatar Kane610 commented on June 24, 2024

I've verified the fix to work on both a 5.51 device and a 5.75 and additionally that newer firmwares keep on working 🎉

from axis.

Kane610 avatar Kane610 commented on June 24, 2024

This has been solved upstream so there is no need to keep this issue open anymore.

from axis.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.