Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for body in GET requests #675

Closed
pieterjongsma opened this issue Oct 25, 2020 · 9 comments
Closed

Support for body in GET requests #675

pieterjongsma opened this issue Oct 25, 2020 · 9 comments

Comments

@pieterjongsma
Copy link

I feel the HTTP spec is a bit murky regarding this topic, but as far as I can tell, including a body with a GET request is allowed:

A payload within a GET request message has no defined semantics;
sending a payload body on a GET request might cause some existing
implementations to reject the request.

One example of an API that accepts (json) bodies on GET requests is Elasticsearch. Possibly because Elastic felt GET is more appropriate for a non-mutating request.

Currently, httr seems to simply not include specified bodies in GET requests. As such, it is currently not possible to use httr for all endpoints in Elasticsearch.

I'd be happy to attempt and make a PR for this change. Just want to make sure this is something that would be accepted.

@gabrielmagno
Copy link

I miss exactly this feature/behaviour.
I needed to do some queries in Elasticsearch, which uses a GET request with a json body, but I was unable to do it with httr.

@maldridgeepa
Copy link

I tried to get around this issue by using the VERB() function, specifying verb="GET" and supplying data for a body (see below for a non-reproducible query). Unfortunately server response always indicates a missing body from the request.

VERB(verb = "GET", url = "https://FakeURL/Endpoint", body = list(a="a", b="b"), encode = "json" )

@gabrielmagno
Copy link

Update regarding ElasticSearch requests: I was able to do the same request using POST.

@herrseverin
Copy link

I just spent 45 minutes trying to talk to Elastic via httr. And already thought I was infinitely stupid and despaired of myself. :D Thanks so much for the clarification. It would be really cool if GET would support body too.

@Andy-nen
Copy link

Hello, is there any update on GET supporting body? Thanks!

@pieterjongsma
Copy link
Author

I don't use R much anymore, but I just noticed there is a new httr2 package: https://github.com/r-lib/httr2. I don't know whether the new package support GET bodies, but if there is to be a fix, it will be in this new version.

@Andy-nen
Copy link

Thanks @pieterjongsma,

I also had a look at httr2, but it also seems to not support body when using the GET function.

@MrFlick
Copy link

MrFlick commented Oct 26, 2023

I have had success using AWS opensearch with a GET with a JSON body by calling httr::POST but then setting the "customrequest" config to "GET". For example

query <- list(
  "query" = list(
    "match" = list(
      "title" = "wind"
    )
  )
)
resp <- httr::POST(paste0("https://", os_domain, "/document/_search"),
           body=query, encode="json", 
           httr::authenticate(os_login$username, os_login$password),
           config(customrequest="GET"))

@hadley
Copy link
Member

hadley commented Oct 31, 2023

Content in a GET is definitely not recommended:

Although request message framing is independent of the method used, content received in a GET request has no generally defined semantics, cannot alter the meaning or target of the request, and might lead some implementations to reject the request and close the connection because of its potential as a request smuggling attack (Section 11.2 of [HTTP/1.1]). A client SHOULD NOT generate content in a GET request unless it is made directly to an origin server that has previously indicated, in or out of band, that such a request has a purpose and will be adequately supported. An origin server SHOULD NOT rely on private agreements to receive content, since participants in HTTP communication are often unaware of intermediaries along the request chain.

https://www.rfc-editor.org/rfc/rfc9110#section-9.3.1-6

So that means you'll always need to set a custom method like @MrFlick suggested, or with httr2:

library(httr2)

request("http://httpbin.org/post") |> 
  req_body_form(a = 1, a = 2, a = 3) |> 
  req_method("GET") |> 
  req_dry_run()
#> GET /post HTTP/1.1
#> Host: httpbin.org
#> User-Agent: httr2/0.2.3.9000 r-curl/5.1.0 libcurl/8.1.2
#> Accept: */*
#> Accept-Encoding: deflate, gzip
#> Content-Type: application/x-www-form-urlencoded
#> Content-Length: 11
#> 
#> a=1&a=2&a=3

Created on 2023-10-31 with reprex v2.0.2

@hadley hadley closed this as completed Oct 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants