HTTPBuilder set requestBody on GET method - groovy

Using cURL I can send a GET request with a body. Example:
curl -i -X GET http://localhost:8081/myproject/someController/l2json -H "content-type: application/json" -d "{\"stuff\":\"yes\",\"listThing\":[1,2,3],\"listObjects\":[{\"one\":\"thing\"},{\"two\":\"thing2\"}]}"
Here is the JSON in a reasonable format for legibility's sake:
{"stuff":"yes",
"listThing":[1,2,3],
"listObjects":[{"one":"thing"},{"two":"thing2"}]}
Normally -d will tell cURL to send a POST but I have confirmed that the -X GET is overriding that and it is sending GET. Is it possible to replicate this with HTTPBuilder?
I have done:
def http = new HTTPBuilder( 'http://localhost:8081/' )
http.post(path:'/myproject/myController/l2json', body:jsonMe, requestContentType:ContentType.JSON) { resp ->
println "Tweet response status: ${resp.statusLine}"
assert resp.statusLine.statusCode == 200
}
Which works, but if I change .post to .get I get the error:
Cannot set a request body for a GET method. Stacktrace follows:
Message: Cannot set a request body for a GET method
Line | Method
->> 1144 | setBody in groovyx.net.http.HTTPBuilder$RequestConfigDelegate
Is there a way to send a GET with a request body using HTTPBuilder?

Short answer: No.
Long answer: The HTTPBuilder doesn't let you set the HTTP method for a request at any time other than when actually creating a request.
Parameters are also set at creating by a closure which checks the type of request and throws that exception if the request is not of type HttpEntityEnclosingRequest.
You can check the source code here: https://fisheye.codehaus.org/browse/gmod/httpbuilder/trunk/src/main/java/groovyx/net/http/HTTPBuilder.java?hb=true
On a side note, the HTTP 1.1 spec doesn't say outright that a GET can't have a body, but it says that if a request semantics doesn't allow one, then it must not be provided, and that servers receiving such requests should ignore it.
Since most people are used to that convention, I would suggest sticking with it, and not having your service actually make use of the body when sending a GET request.
See also this question: HTTP GET with request body

Related

How do I get signature and landed_at data in typeform API?

It used to work like this:
import requests
u = "https://uza3fcl1odf.typeform.com/app/form/result/token/tCsWUtMB/default"
j = requests.post(u, headers={"Accept": "application/json"}).json()
# {'token': '20903331626f396431746f397777693832713331626f39643136747572367978706434313339363936363463366336363533373434333536343134353337366237613339343233303664373236613737353935613431363436393336343833313335333833383332333733393336333333373633653233363637346132653432343938383963326537663165326535633262373837326336613437343539666638653932613131393266386236393635626131353838323739363337', 'landed_at': '1588279637'}
Also here are the topics about this:
Post request to Typeform failing due to Invalid payload
Python post request, problem with posting
error with signature token when filling a typeform
How to get JSON data from a Python POST request
Here is my test form: https://uza3fcl1odf.typeform.com/to/tCsWUtMB
But now this solution does not work, I do not know why. What kind of POST request should I make to get "signature" and" landed_at " data in response?
It is desirable that your example can be easily checked in Postman.

Scrapy - is it possible to extract Payload Request from Response

is it possible to extract and set as variable the "Payload Request" which has been pushed in order to receive particular response?
You can access the request object in the callback function by response.request.
This object is the request object itself, so it contains everything you passed in the request. It doesn't have a "payload" attribute though.
The equivalent should be response.request.body, assuming you had a body in the request. Everything else is still there, headers, cookies, meta, method, etc
More on the params of request here.

405 - Method Not Allowed in Robot Framework

I am new to Robot Framework. I was trying to access an URL and generate a token.
I am getting the below error.
Test 1 | FAIL |
405 != 200
upon checking the log
00:52:49.347 INFO POST Response :
url=XXX
status=405, reason=Method Not Allowed
body=None
URL is getting passed correctly and the same is working fine in Postman.
Create Session myssion ${auth_url}
${response}= Post Request myssion /oauth2/token auth=${auth} headers=${headers}
grant_type=${grant_type}
Should Be Equal As Strings ${response.status_code} 200
${token}= evaluate $resp.json().get("access_token")
Please help.
It appears that the problem is a missing space. You only have one space between auth=${auth} and headers=${headers}. You need two or more spaces:
${response}= Post Request myssion /oauth2/token auth=${auth} headers=${headers}
^^

Sending data in GET request Python

I know that it is not an advisable solution to use GET however I am not in control of how this server works and have very little experience with requests.
I'm looking to add a dictionary via a GET request and was told that the server had been set up to accept this but I'm not sure how that works. I have tried using
import requests
r = request.get('www.url.com', data = 'foo:bar')
but this leaves the webpage unaltered, any ideas?
To use request-body with a get request, you must override the post method. e.g.
request_header={
'X-HTTP-Method-Override': 'GET'
}
response = requests.post(request_uri, request_body, headers=request_header)
Use requests like this pass the the data in the data field of the requests
requests.get(url, headers=head, data=json.dumps({"user_id": 436186}))
It seems that you are using the wrong parameters for the get request. The doc for requests.get() is here.
You should use params instead of data as the parameter.
You are missing the http in the url.
The following should work:
import requests
r = request.get('http://www.url.com', params = {'foo': 'bar'})
print(r.content)
The actual request can be inspected via r.request.url, it should be like this:
http://www.url.com?foo=bar
If you're not sure about how the server works, you should send a POST request, like so:
import requests
data = {'name', 'value'}
requests.post('http://www.example.com', data=data)
If you absolutely need to send data with a GET request, make sure that data is in a dictionary and instead pass information with params keyword.
You may find helpful the requests documentation

What does "content-type" mean in headers of python requests library and if the value is text/html;charset=UTF-8?

I want to do some operations with response from python requests library. After I use below function;
response = requests.get(f'{AUTHORIZE_URL}?client_id={CLIENT_ID}&response_type=code&state={STATE}&redirect_uri={REDIRECT_URI}')
I need to get an URL something like this in return;
http://127.0.0.1:8000/products/auth/?state=2b33fdd45jbevd6nam&code=MGY1MTMyNWY0YjQ0MzEwNmMxMjY2ZjcwMWE2MWY5ZDE5MzJlMjA1YjdkNWExNGRhYjIzOGI5NzQ5OWZkNTA5NA
While doing it, it will be easier to use JSON in order to get state and code values from URL but I cannot use it because I think the content type does not allow this.
See this for Content-Type explanation: Content-Type
In short the "content-type" in the headers of response got by using requests.get tells you what kind of the content server did send, in your case you'we got a response in the form of the HTML (like .html document) and you can read that response with response.text, if the "content-type" is "application/json" then you can read it as JSON like this response.json().
I see that you use some local server, your local server should send in headers "Content-Type": "application/json" and then you should be able to read JSON from response like this (you need to send JSON not hmtl or text from server):
targetURL = 'http://127.0.0.1:8000/products/auth/?state=2b33fdd45jbevd6nam&code=MGY1MTMyNWY0YjQ0MzEwNmMxMjY2ZjcwMWE2MWY5ZDE5MzJlMjA1YjdkNWExNGRhYjIzOGI5NzQ5OWZkNTA5NA'
response.get(targetURL).json()

Resources