Mailing List Archive

Python Client Rest API Invocation - POST with empty body - Invalid character found in method name [{}POST]. HTTP method names must be tokens
I have a Tomcat+Java based server exposing REST APIs. I am writing a client in python to consume those APIs. Everything is fine until I send empty body in POST request. It is a valid use case for us. If I send empty body I get 400 bad request error - Invalid character found in method name [{}POST]. HTTP method names must be tokens.

If I send empty request from POSTMAN or Java or CURL it works fine, problem is only when I used python as a client.

Following is python snippet -

json_object={}

header = {'alias': 'A', 'Content-Type' : 'application/json', 'Content-Length' : '0'}

resp = requests.post(url, auth=(username, password), headers=header, json=json_object)



I tried using data as well instead of json param to send payload with not much of success.

I captured the wireshark dumps to understand it further and found that the request tomcat received is not as per RFC2616 (https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html). Especially the part -

Request-Line = Method SP Request-URI SP HTTP-Version CRLF

I could see in from wireshark dumps it looked like - {}POST <MY-APP-URI> HTTP/1.1

As we can see the empty body is getting prefixed with http-method, hence tomcat reports that as an error. I then looked at python http library code - client.py.

Following are relevant details -

File - client.py

Method - _send_output (starting at line # 1001) -



It first sends the header at line #1010 and then the body somewhere down in the code. My hunch is that (I could be wrong here) perhaps in this case header is way longer 310 bytes than body 2 bytes, so by the time complete header is sent on wire body is already pushed and hence TCP frames are order in such a way that body appears first. To corroborate this I added a delay of 1 second just after sending header line#1011 and bingo, the error disappeared and it started working fine. Not sure if this is completely correct analysis, but can someone in the know can confirm or let me know how to fix this.

Env Details - Client and Server on local machine as of now.

* Client
* Python Version - 3.9, Python Requests module version - 2.25
* Server
* Java 13, Tomcat 9.


P.S. - Please see attached screenshots of wireshark dump with relevant part highlighted.

Regards,
Bhushan

--
https://mail.python.org/mailman/listinfo/python-list
Re: Python Client Rest API Invocation - POST with empty body - Invalid character found in method name [{}POST]. HTTP method names must be tokens [ In reply to ]
Shelke, Bhushan wrote at 2020-11-19 15:12 +0000:
>I have a Tomcat+Java based server exposing REST APIs. I am writing a client in python to consume those APIs. Everything is fine until I send empty body in POST request. It is a valid use case for us. If I send empty body I get 400 bad request error - Invalid character found in method name [{}POST]. HTTP method names must be tokens.

`[{}POST]` would definitely be a wrong method.

I would use the Python debugger (--> module `pdb`) to
find out where it comes from.
--
https://mail.python.org/mailman/listinfo/python-list
RE: Python Client Rest API Invocation - POST with empty body - Invalid character found in method name [{}POST]. HTTP method names must be tokens [ In reply to ]
> Invalid character found in method name [{}POST]. HTTP method names must be tokens.

/snip

> I could see in from wireshark dumps it looked like - {}POST <MY-APP-URI> HTTP/1.1

The error message and your own debugging indicate the error.

Your method *name* is {}POST, you have somehow included two
brackets in the name of the method.

jlc
--
https://mail.python.org/mailman/listinfo/python-list
Re: Python Client Rest API Invocation - POST with empty body - Invalid character found in method name [{}POST]. HTTP method names must be tokens [ In reply to ]
On 2020-11-19 15:12:39 +0000, Shelke, Bhushan wrote:
> I have a Tomcat+Java based server exposing REST APIs. I am writing a
> client in python to consume those APIs. Everything is fine until I
> send empty body in POST request. It is a valid use case for us. If I
> send empty body I get 400 bad request error - Invalid character found
> in method name [{}POST]. HTTP method names must be tokens.
>
> If I send empty request from POSTMAN or Java or CURL it works fine,
> problem is only when I used python as a client.
>
> Following is python snippet -
>
> json_object={}
>
> header = {'alias': 'A', 'Content-Type' : 'application/json', 'Content-Length' : '0'}

'Content-Length' : '0' is wrong, but it seems that requests.post
overrides that, so it doesn't matter.


> resp = requests.post(url, auth=(username, password), headers=header, json=json_object)
>
>
>
> I tried using data as well instead of json param to send payload with
> not much of success.
>
> I captured the wireshark dumps to understand it further and found that
> the request tomcat received is not as per RFC2616
> (https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html). Especially
> the part -
>
> Request-Line = Method SP Request-URI SP HTTP-Version CRLF
>
> I could see in from wireshark dumps it looked like - {}POST
> <MY-APP-URI> HTTP/1.1
>
> As we can see the empty body is getting prefixed with http-method,
> hence tomcat reports that as an error. I then looked at python http
> library code - client.py.

I cannot reproduce this. Using Python 3.8.2 and requests 2.22.0 (as
included in Ubuntu 20.04), the request sent is "POST /env HTTP/1.1", not
"{}POST /env HTTP/1.1",


In wireshark "Follow TCP connection", the "{}" at the end of the request
is squished together with the "HTTP/1.1 302 Found" at the beginning of
the response, but they are in different colors so that shouldn't be a
problem unless you are visually impaired, and it doesn't match your
description.

hp

--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | hjp@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"