Samamba
Samamba

Reputation: 113

Python no response received using async, await, aiohttp

I'm writing a proxy that tampers SOAP requests and sends it to the destination using aiohttp web Application and aiohttp for async POSTs.

My request method definition is the following:

async def proxy(request):
    headers = dict(request.headers)
    headers.pop('access-token')

    async with ClientSession(connector=TCPConnector(ssl=False)) as session:
        result = await session.post(
            ACTION,
            data=await request.content.read(),
            headers=request.headers
        )
        retorno = await result.read()

    return web.Response(
        body=retorno,
        status=result.status
    )

This works just fine; async read from the source, async await from the destination.

But I need to do some tampering on the message, that follows:

async def proxy(request):
    headers = dict(request.headers)
    headers.pop('access-token')

    async with ClientSession(connector=TCPConnector(ssl=False)) as session:
        data = await request.content.read()
        data = data.replace(b'###USER###', AUTH_USER)
        data = data.replace(b'###PASSWORD###', AUTH_PASSWORD)
        result = await session.post(
            ACTION,
            data=data,
            headers=request.headers
        )
        retorno = await result.read()

    return web.Response(
        body=retorno,
        status=result.status
    )

And this just halts and forever awaits in the result = await session.post method. No response is received.

Any ideas?

Upvotes: 1

Views: 1411

Answers (1)

Samamba
Samamba

Reputation: 113

Oh, gosh, that`s both lame and shaming, but my original answer to my problem was wrong, due to improper testing.

The solution was far more simple and obscure than I thought.

Since I was replacing all the headers (trying not to temper the request to much), I`ve replaced the Content-Length header too. This caused the server to keep waiting for-ever to the end of the message.

Before tempering the message, just used a headers.pop('Content-Length') and sent all the headers that came from the sender.

It works like a charm.

--------- original (wrong) answer ----------

Just figured it out.

After testing against a SoapUI mock services, checked that the request was correct.

The remote API is implemented in an unknown technology to me, but, I couldn`t just push a byte array in the data field, even if the aiohttp.streams.StreamReader returned it as such.

Just decoded it as utf8 and everything worked great!

async def proxy(request):
    headers = dict(request.headers)
    headers.pop('access-token')

    async with ClientSession(connector=TCPConnector(ssl=False)) as session:
        data = await request.content.read()
        data = data.replace(b'###USER###', USER)
        data = data.replace(b'###PASSWORD###', PASSWORD)
        result = await session.post(
            ACTION,
            data=data.decode('utf8'),
            headers=request.headers
        )
        retorno = await result.read()

    return web.Response(
        body=retorno,
        status=result.status
    )

Thank you all!

Upvotes: 1

Related Questions