When sending a post it returns error 400 bad request for url

Hi,
i"m trying to send a Post request with Robot framework like i do with Postman:

in Postman i send a Podt request with body which is in form-data and contains some value like:
data: 2.2.2,aaa.111
name: test
and i validate the respons status 201
it works fine.

Now i want to do the same with Robot Framework:

test-1: i send a Post request for login where i validate response status with 200 and save the token as global variable.
test-1 works fine.

test-2: i send a Post request to create an account and i have to validate the response status 201.
it uses the global variable token.

*** Variables ***
${data} 2.2.2,aaa.111
${name} test

*** Test Cases ***
Create_account
Create Session test ${base_url} verify=False
${body}= Create Dictionary data=${data} name=${name}
${headers}= Create Dictionary Cache-Control=no-cache Content-Type=application/json charset=UTF-8-BOM Authorization=Bearer ${token}
${response}= POST On Session test json=${body} headers=${headers}
Should Be Equal As strings ${response.status_code} 201

When i excute the Create_account it returns HTTPError: 400 Client invalid request

i am not able to log the response because it stops at post session.
in the Log test, i see invalid request for the url…
If i open the url it says status: 401 and no_authenticated

I log the token at then end of login test and at the begining of the create account test and compare them, they are exactly the same.

In the log test: i see the same token in login and create account.
so i don’t understand why i receive a 400 error.

Any help/
Thank you

Hi @RobotK,

You said:

in Postman i send a Podt request with body which is in form-data

Yet your post body in requests library is JSON?

${response}= POST On Session test json=${body} headers=${headers}

HTTP 400 code is

400 Bad Request
The 400 Bad Request status code means that the server could not understand the request because of invalid syntax.

So perhaps you need to send form data not JSON? Maybe something like this:

${response}= POST On Session test data=${body} headers=${headers}

*Note the json=${body} changed to data=${body}

Hope that helps,

Dave.

Hi Dave,
Thank you for your help.
if i send the POST request with data=${body} like this
${response}= POST On Session test data=${body} headers=${headers}
it returns hte same error 400 and it says JSON parse error, expecting value: line1 column1

If i send POST request with form-data i returns it returns error 415 media tyoe non supported.
Something is wrong with body or content-type or Accept-Encoding=gzip, deflat, br
or other.

Hi @RobotK,

All I can tell you is to compare the request body that requests library is sending to the one that postman (look at the raw request body not the parsed request body) is sending and see what’s different, and change what your doing in requests library to make it the same as what postman is sending

Unless you can show the request bodies that postman and requests library are sending all I can do is guess.

The fact your now getting 415 instead of 400 could be progress in the right direction?

Dave.

This is what i see.

Postman request body:
data: “2.2.2,aaa.111”
name: “test”

Robot framework request body:
body=b’ {“data”: “2.2.2,aaa.111”, “name”: “test” }’

In Postman the request headers:
Authorization: “Bearer uyhyffdd…”
User-Agent: "PostmanRuntime/7.37.0
Accept: “/”
Cache-Control: “no-cache”
Postman token: “…”
Host: “…”
Accept-Encoding: “gzip, deflate, br”
Connection: “Keep-Alive”
Content-Type: :multipart/form-data: boundary=--------0348…
Content-Length: “628”

In Robot Framework the request body: is in json format
headers={
User-Agent: “pyhton-requests/2.31.0”,
Accept-Encoding: “gzip, deflate, br”,
Accept: “/”,
Connection: “Keep-Alive”,
Cache-Control: “no-cache”,
Content-Type: :“application/json”,
Authorization: “Bearer fy…”,
Content-Length: “144”
body=b’ {“data”: “2.2.2,aaa.111”, “name”: “test” }’
}

Hi @RobotK

You need to get the raw request from the consol in postman (see below)

It wasn’t obvious to me at first how to do this, so here’s what I did:

Now you can see what was really sent by postman, this is what you need to reproduce with requests.

form data body can look like:

----------------------------postman
Content-Disposition: form-data; name="data"
2.2.2.aaa.111
----------------------------postman
Content-Disposition: form-data; name="name"
test
----------------------------postman--

it can also look like:

data=2.2.2.aaa.111&name=test

where JSON body’s look like:

{"data":"2.2.2.aaa.111","name":"test"}

Once you really know what postman is sending and what your app server is expecting you can then know what you need to recreate.

Here is an example of a form-data post body from one of my request library scripts:


as you can see the request headers (orange box) is separate from the the request body (green box) so having the body in the headers json that you showed doesn’t look right.

This line:

 Content-Type: :multipart/form-data: boundary=--------0348…

Indicates that it’s probably the first form data body type I mentioned, if so you’ll need to construct the boundary string first, add it into your headers and then construct the body with it, then put it all together in the post. If my suspicions is correct you’ll need a completely different approach to constructing the request body.

Hopefully this gets you on the right track, let me know if you need help constructing the form data body with the boundary strings,

Dave.

yes i see the raw console.
this line: Content-Type: :multipart/form-data: boundary=--------0348
is worrying me.
i need to search about how i have to construct the request body.
it’s a bit advanced for me.

This might help; python - Robotframework.request - How to make a POST request with content "multipart/form-data" - Stack Overflow - Answer on that one gives a pretty decent description on what could help.

1 Like

Hi,
i found this on google and tried by passing a file.
it returns invalid request.
so i really need to search and undesrtand how RF send the multi-part form.

FYI: So the problem is with Content-Type = multipart/form-data; boundary=----------------3e324324
Robot Framework doesn’t seem to have solution to send request with this for now.
I tried to construct by generating dynamically boundary even with that it’s working for me.
It’s almost like i have to create a new lib for this.
So i’m still searching…

Hi @RobotK,

I’m a little disappointed @rasjani’s suggestion didn’t work for you, It looked like it would have been an easy way to do the form submit.

Not a whole new lib, just a keyword is probably enough, probably called something like post form data on session with the arguments of session, url and a dictionary of form fields and values.

Do you need help with that? If you can show what ended up working I can help you put it in a generic keyword.

Dave.

Yes i can send it in private msg

Yeah, thats sort of why I hinted at “maybe it could help” as i wasn’t sure and didn’t have any resources at hand to try it out =(

1 Like

Hi,
the issue is resolved, there was a problem on the dev side when they developped the request.
now it works.
Finally!

1 Like