Using "Content-Type:application/json" to post in curl gives HTTP/1.1 400 BAD REQUEST

The Recruit picture The Recruit · Oct 22, 2012 · Viewed 22.6k times · Source

When I make a post request using the following

curl -i -d "username=rock&password=rock" http://my_VM_IP/api/1.1/json/my_login/

it generates the required response generating a token like this(abridged):

HTTP/1.1 200 OK
Date: Mon, 22 Oct 2012 08:37:39 GMT
Vary: Authorization,Accept-Language,Cookie,Accept-Encoding
Content-Type: text/plain
Transfer-Encoding: chunked
OK{"success": {"my_token": "required_token"}}

But when I try the same including a header as:

curl -i -H "Content-Type:application/json" -d "username=rock&password=rock" http://my_VM_IP/api/1.1/json/my_login/ 

it gives me the following error:

HTTP/1.1 400 BAD REQUEST
Date: Mon, 22 Oct 2012 11:12:04 GMT
Vary: Authorization,Accept-Language,Cookie,Accept-Encoding
***Content-Type: text/plain***
Content-Language: en-us
Connection: close
Transfer-Encoding: chunked
Bad Request

I dont understand why this happens. And also why does the content-Type show text/plain, I also tried looking at some other questions like Why Setting POST Content-type:"Application/Json" causes a "Bad Request" on REST WebService? . It also addresses the same problem I have. Following the answer in that I tried giving the data in various formats as

{"username":"rock", "password":"rock"} 

but without success. Thanks in advance.

Answer

Anuj Gupta picture Anuj Gupta · Oct 22, 2012

By using -H "Content-Type:application/json" you're setting the Content-Type header for your request. The response will still return whatever your view tells it to return.

To return a response with Content-Type application/json, use something along these lines:

import json
from django.http import HttpResponse

def json_response(return_vars):
    'JSON-encodes return_vars returns it in an HttpResponse with a JSON mimetype'
    return HttpResponse(json.dumps(return_vars), content_type = "application/json")

#Usage: return json_response({'admin_token': admin_api_token.token})