Open
Description
Hi, thanks for your work on the client.
I noticed strange behaviors while reading account data from arbitrary contracts, it seems that the solana official RPC is unhappy with httpx's injected content-length
header.
client = AsyncClient("https://api.mainnet-beta.solana.com")
account_info = await client.get_account_info(Pubkey.from_string("9tXiuRRw7kbejLhZXtxDxYs2REe43uH2e7k1kocgdM9B"))
The above code will generate this request on httpx.AsyncClient
's side:
{
"url": "https://api.mainnet-beta.solana.com",
"headers": {
"Content-Type": "application/json",
"Host": "api.mainnet-beta.solana.com",
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Connection": "keep-alive",
"User-Agent": "python-httpx/0.28.1",
"Content-Length": "194"
},
"content": {
"method": "getAccountInfo",
"jsonrpc": "2.0",
"id": 0,
"params": [
"9tXiuRRw7kbejLhZXtxDxYs2REe43uH2e7k1kocgdM9B",
{
"encoding": "base64",
"dataSlice": null,
"commitment": "finalized",
"minContextSlot": null
}
]
}
}
Here is a curl equivalent for quick testing:
curl -X POST https://api.mainnet-beta.solana.com \
-H "Host: api.mainnet-beta.solana.com" \
-H "Accept: */*" \
-H "Accept-Encoding: gzip, deflate" \
-H "Connection: keep-alive" \
-H "User-Agent: python-httpx/0.28.1" \
-H "Content-Type: application/json" \
-H "Content-Length: 194" \
-d '{
"method": "getAccountInfo",
"jsonrpc": "2.0",
"id": 0,
"params": [
"9tXiuRRw7kbejLhZXtxDxYs2REe43uH2e7k1kocgdM9B",
{
"encoding": "base64",
"dataSlice": null,
"commitment": "finalized",
"minContextSlot": null
}
]
}'
This breaks, Solana's RPC returning curl: (92) HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)
If the Content-Length
header is removed or fixed (set to 261 in this example), the query is processed:
{"jsonrpc":"2.0","result":{"context":{"apiVersion":"2.0.21","slot":315171374},"value":{"data":["P5XRDOGAYwkT5EH4ORPKaLBjT7Al/eqohzfoQRDRJV41ezN33e4czf8BAAEAZAAUBWX/vVkEl0kAAAAAAAAAAADsM72Lgpv6/wAAAAAAAAAA/v///4PttmUAAAAAdikpZgAAAAAXkkg7bIoqh7dHHYFPlZH5OVyECpzj2fTVun06S4p0nsqyXOJQokFo/NIz4KGnJohGd81f6eq6l6BjjIwLUZ+nYM3ZmMSMAQAAAAAAAAAAAMb6evO+2606PWXzaqvJdDGxu+TC0vbg5HymAgNFL11hBVu9tYk+VhpyfHYC4VK5YZdlNda5HFvU4kdV+KcipRPxYySYyoEBAAAAAAAAAAAAkf6NZwAAAAAXkkg7bIoqh7dHHYFPlZH5OVyECpzj2fTVun06S4p0nv2c/kXycevMpaE75U8vr7oK6kIb5ZvXWnjtDHAxc1dvvR0xrxfe/zwmhIFgCsr+SxQJjA/hQbf0oc34STRkRAMAAAAAAAAAAAAAAAAAAAAAdOft6ai1AAAAAAAAAAAAAAwA0K/rhhTafxmroC1A8YxpJYX2UCDfztPV5fmpwMTh+l31H+YC5Jblq6uF7Nol3Z5xgz0h5vC17r5W6ZKVBxe9HTGvF97/PCaEgWAKyv5LFAmMD+FBt/ShzfhJNGREAwAAAAAAAAAAAAAAAAAAAABdQP9ftBYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL0dMa8X3v88JoSBYArK/ksUCYwP4UG39KHN+Ek0ZEQDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","base64"],"executable":false,"lamports":5443300,"owner":"whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc","rentEpoch":18446744073709551615,"space":653}},"id":0}
Not sure if the header value not matching the actual content size is due to solana-py
or httpx