Help translating curl command to HTTP.jl

The basic change you’ve made seems to be the addition of Accept and Content-Type headers. Why did the curl and python apparent equivalents to your original work? Do curl and python automatically add those extra headers you’ve added, or perhaps does HTTP.jl include bad values for those headers by default?

It seems the default parameters are different. For Python’s requests library:

req = pyimport("requests")
req.post("http://localhost:8080", 
Dict("grant_type" => "client_credentials"), 
headers = Dict("Authorization" => "Basic $refreshtoken"))
~ > nc -l 8080
POST / HTTP/1.1
Host: localhost:8080
User-Agent: python-requests/2.22.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Authorization: Basic OT...E=
Content-Length: 29
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials

for curl:

run(`curl -X "POST" -H "Authorization: Basic $refreshtoken" -d grant_type=client_credentials http://localhost:8080`)
~ > nc -l 8080
POST / HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.68.0
Accept: */*
Authorization: Basic OT...E=
Content-Length: 29
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials

And HTTP.jl

HTTP.post("http://localhost:8080", ["Authorization" => "Basic $refreshtoken"], "grant_type=client_credentials")
~ > nc -l 8080
POST / HTTP/1.1
Authorization: Basic OT...E=
Host: localhost
User-Agent: HTTP.jl/1.5.3
Content-Length: 29

grant_type=client_credentials

Whether this is good or bad I cannot judge. For my usecase it was bad since it deviates from what you have to do in curl which seems to be the standard in all the API docs. But with the nc -l 8080 trick this was quite easy to figure out.

1 Like

See https://github.com/JuliaWeb/HTTP.jl/issues/661

2 Likes

I also need to set

    "Content-Type" => "application/x-www-form-urlencoded"

which is also the default in both requests and curl

Should I open a separate issue?

Based on @mbauman’s initial comment on the issue I did the request without "Accept" => "*/*" and it still worked so in this case the problem really seems to be "Content-Type"=>"application/x-www-form-urlencoded".

It’s interesting because that Content-Type doesn’t appear in Requests’ default headers. Do they dynamically add it in certain situations? Ah, it looks like it does indeed depend upon the body — it’ll either be a multipart or this x-www-form-urlencoded or nothing:

requests/models.py#L505-L520 (Apache License 2.0)