Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions pubnub/request_handlers/async_aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ async def async_request(self, options_func, cancellation_event):
uuid=uuid,
auth_key=auth_key,
client_request=None,
client_response=response
client_response=response,
http_version=f"HTTP/{response.version.major}.{response.version.minor}" if response.version else None
Comment thread
parfeon marked this conversation as resolved.
)

# if body is not None and len(body) > 0 and not options.non_json_response:
Expand Down Expand Up @@ -172,7 +173,7 @@ async def async_request(self, options_func, cancellation_event):
else:
data = "N/A"

logger.debug(data)
logger.debug("[%s %s] %s" % (options.operation_type, response_info.http_version, data))

if response.status not in (200, 307, 204):

Expand Down
8 changes: 5 additions & 3 deletions pubnub/request_handlers/async_httpx.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ def __init__(self, pubnub):
async def create_session(self):
self._session = httpx.AsyncClient(
timeout=httpx.Timeout(self.pubnub.config.connect_timeout),
transport=self._connector
transport=self._connector,
http2=True
)

async def close_session(self):
Expand Down Expand Up @@ -193,7 +194,8 @@ async def async_request(self, options_func, cancellation_event):
uuid=uuid,
auth_key=auth_key,
client_request=None,
client_response=response
client_response=response,
http_version=response.http_version
)

# if body is not None and len(body) > 0 and not options.non_json_response:
Expand Down Expand Up @@ -224,7 +226,7 @@ async def async_request(self, options_func, cancellation_event):
else:
data = "N/A"

logger.debug(data)
logger.debug("[%s %s] %s" % (options.operation_type, response_info.http_version, data))

if response.status_code not in (200, 307, 204):

Expand Down
17 changes: 9 additions & 8 deletions pubnub/request_handlers/httpx.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def _ensure_session(self):
with self._session_lock:
if self._session is None or self._session.is_closed:
logger.debug("Creating new HTTP session")
self._session = httpx.Client()
self._session = httpx.Client(http2=True)
return self._session

def close(self):
Expand Down Expand Up @@ -318,7 +318,8 @@ def _build_envelope(self, p_options, e_options):
origin=res.url.host,
uuid=uuid,
auth_key=auth_key,
client_request=res.request
client_request=res.request,
http_version=res.http_version
)

if res.status_code not in [200, 204, 307]:
Expand Down Expand Up @@ -433,15 +434,15 @@ def _invoke_request(self, p_options, e_options, base_origin):

try:
res = session.request(**args)
# Safely access response text - read content first for streaming responses

try:
logger.debug("GOT %s" % res.text)
logger.debug("[%s %s] %s" % (e_options.operation_type, res.http_version, res.text))
except httpx.ResponseNotRead:
# For streaming responses, we need to read first
logger.debug("GOT %s" % res.content.decode('utf-8', errors='ignore'))
content = res.content.decode('utf-8', errors='ignore')
logger.debug("[%s %s] %s" % (e_options.operation_type, res.http_version, content))
except Exception as e:
# Fallback logging in case of any response reading issues
logger.debug("GOT response (content access failed: %s)" % str(e))
msg = "(content access failed: %s)" % str(e)
logger.debug("[%s %s] %s" % (e_options.operation_type, res.http_version, msg))

except httpx.ConnectError as e:
if use_watchdog and self._watchdog.triggered:
Expand Down
13 changes: 11 additions & 2 deletions pubnub/request_handlers/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,11 @@ def _build_envelope(self, p_options, e_options):
origin=url.hostname,
uuid=uuid,
auth_key=auth_key,
client_request=res.request
client_request=res.request,
http_version=(
Comment thread
parfeon marked this conversation as resolved.
f"HTTP/{res.raw.version // 10}.{res.raw.version % 10}"
if res.raw and res.raw.version else None
)
)

if not res.ok:
Expand Down Expand Up @@ -268,7 +272,12 @@ def _invoke_request(self, p_options, e_options, base_origin):

try:
res = self.session.request(**args)
logger.debug("GOT %s" % res.text)
http_ver = (
f"HTTP/{res.raw.version // 10}.{res.raw.version % 10}"
if res.raw and res.raw.version else "unknown"
)
logger.debug("[%s %s] %s" % (e_options.operation_type, http_ver, res.text))

except requests.exceptions.ConnectionError as e:
raise PubNubException(
pn_error=PNERR_CONNECTION_ERROR,
Expand Down
4 changes: 3 additions & 1 deletion pubnub/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,16 @@ def __init__(self, headers, pn_config):


class ResponseInfo(object):
def __init__(self, status_code, tls_enabled, origin, uuid, auth_key, client_request, client_response=None):
def __init__(self, status_code, tls_enabled, origin, uuid, auth_key, client_request,
client_response=None, http_version=None):
self.status_code = status_code
self.tls_enabled = tls_enabled
self.origin = origin
self.uuid = uuid
self.auth_key = auth_key
self.client_request = client_request
self.client_response = client_response
self.http_version = http_version


class Envelope(object):
Expand Down
4 changes: 2 additions & 2 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ flake8>=7.1.2
pytest>=8.3.5
pytest-asyncio>=1.0.0
httpx>=0.28
h2>=4.1
h2>=4.3
Comment thread
parfeon marked this conversation as resolved.
requests>=2.32.2
aiohttp>=3.10.11
aiohttp>=3.10.11,<3.11
cbor2>=5.6
behave>=1.2.6
vcrpy>=6.0.2
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
install_requires=[
'pycryptodomex>=3.3',
'httpx>=0.28,<1.0',
'h2>=4.1',
'h2>=4.3',
'requests>=2.32.2',
'aiohttp>3.10.11',
'cbor2>=5.6'
Expand Down
15 changes: 15 additions & 0 deletions tests/integrational/asyncio/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import asyncio
import pytest


@pytest.fixture(autouse=True)
def event_loop_for_sync_tests():
try:
asyncio.get_running_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
yield
loop.close()
else:
yield
Loading