Using curl to test POST data: Difference between revisions

From Littledamien Wiki
Jump to navigation Jump to search
No edit summary
 
(4 intermediate revisions by the same user not shown)
Line 1: Line 1:
==Basic request passing variables as POST==
[[Category:Web Development]]
Use <code>--data</code> or <code>-d</code> option to pass variables to the page.
== Basic request passing variables as POST ==
 
Use `--data` or `-d` option to pass variables to the page.
 
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
$ curl -d "user=mylogin&pass=mypass&foo=bar&biz=bash" http://www.mydomain.com/mypage/
$ curl -d "user=mylogin&pass=mypass&foo=bar&biz=bash" http://www.mydomain.com/mypage/
</syntaxhighlight>
</syntaxhighlight>
==Request using basic authentication==
 
Use <code>--user</code> or <code>-u</code> option.
== Request using basic authentication ==
 
Use `--user` or `-u` option.
 
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
$ curl -u mylogin:mypass -d "user=mylogin&pass=mypass&foo=bar&biz=bash" http://www.mydomain.com/mypage/
$ curl -u mylogin:mypass -d "user=mylogin&pass=mypass&foo=bar&biz=bash" http://www.mydomain.com/mypage/
</syntaxhighlight>
</syntaxhighlight>
==Request using Windows integrated authentication==
 
Add <code>--ntlm</code> option.
== Request using Windows integrated authentication ==
 
Add `--ntlm` option.
 
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
$ curl -u mylogin:mypass --ntlm -d "user=mylogin&pass=mypass&foo=bar&biz=bash" http://www.mydomain.com/mypage/
$ curl -u mylogin:mypass --ntlm -d "user=mylogin&pass=mypass&foo=bar&biz=bash" http://www.mydomain.com/mypage/
</syntaxhighlight>
</syntaxhighlight>
==Special characters in username or password==
 
== Special characters in username or password ==
 
Escape special characters with back slash.
Escape special characters with back slash.
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
$ curl -u mylogin:myp\&ss --ntlm -d "user=mylogin&pass=mypass&foo=bar&biz=bash" http://www.mydomain.com/mypage/
$ curl -u mylogin:myp\&ss --ntlm -d "user=mylogin&pass=mypass&foo=bar&biz=bash" http://www.mydomain.com/mypage/
Line 22: Line 34:
== Storing arguments in a text file ==
== Storing arguments in a text file ==


Content of file, saved as <code>curlargs.txt</code>:
Content of file, saved as `curlargs.txt`:
<pre>
<syntaxhighlight lang="bash">
-d foo=bar&biz=bash http://localhost/mytestpage.html
-d foo=bar&biz=bash http://localhost/mytestpage.html
</pre>
</syntaxhighlight>
 
Run curl using contents of <code>curlargs.txt</code> (in a bash shell):
Run curl using contents of <code>curlargs.txt</code> (in a bash shell):
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
$ cat curlargs.txt | xargs -n3 curl
$ cat curlargs.txt | xargs -n3 curl
</syntaxhighlight>
</syntaxhighlight>
== Sending request headers ==
<syntaxhighlight lang="powershell">
> curl -H "X-MyHeader: 123" www.google.com
</syntaxhighlight>
The argument is either `-H` or `--header` followed by header name, colon, and header value.
For example, to send an Accept request-header for JSON data: `-H "Accept: application/json"`.
To view the request that is sent add the `-v` option to `curl`.


== Handling quotes in POST data ==
== Handling quotes in POST data ==
Line 38: Line 64:
curl -d '{ "id": "6650", "title": "A record title containing 'quotes'."}' http://mydomain.com/path/to/page/
curl -d '{ "id": "6650", "title": "A record title containing 'quotes'."}' http://mydomain.com/path/to/page/
</syntaxhighlight>
</syntaxhighlight>


'''Solution:''' Use the `@` character to read the data from a separate file.
'''Solution:''' Use the `@` character to read the data from a separate file.
Line 55: Line 80:
</syntaxhighlight>
</syntaxhighlight>


[[Category:Web Development]]
== Sending POST requests to Django projects ==
 
Because of [https://docs.djangoproject.com/en/dev/ref/contrib/csrf/ Cross Site Request Forgery protection] in Django, POST requests have to include a CSRF token generated by the Django app.
 
It's not really practical or safe to generate the token so it can be used with `curl`.
 
Instead right above the Django view that is being called, place an CSRF exemption:
<syntaxhighlight lang="python">
from django.views.decorators.csrf import csrf_exempt
 
@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')
</syntaxhighlight>
 
It's possible to pass the token with `curl`:
 
<syntaxhighlight lang="bash">
curl
-X POST
-d "email=test@test.com&a=1&csrfmiddlewaretoken=<inserttoken>"
--cookie "csrftoken=[as above]"
http://127.0.0.1:8083/registrations/register/
</syntaxhighlight>
 
It's also possible to use `--header "X-CSRFToken: <token>"` instead of including it in the form data.
 
== Following redirects ==
 
<syntaxhighlight lang="bash">
$ curl -L -X POST -d "foo=bar&biz=bash" http://dev-server.com
</syntaxhighlight>
 
* `-L` '''location''' Tells `curl` to reattempt the get if the server reports that the page is at a different location (`301` and `302` responses)
* `-X POST` Explicitly use the POST method (as opposed to the `-d` option which implicitly uses POST.<ref>[http://man.cx/curl curl man page]</ref> (man.cx manual pages)
 
This happens with Symfony, which sends a `301` response with its controllers.<ref>[http://stackoverflow.com/a/22654902 php curl post request to symfony2 app shows an empty ParameterBag] (Stackoverflow)</ref>,<ref>[http://www.recursion.org/2011/11/18/following-redirects-with-curl Following Redirects with Curl] (recursion.org blog)</ref>
 
<p class="alert-warning">N.B. This did not work on the first attempt with Symfony. Not sure if it's not a solution, or if I was doing something wrong.</p>
 
== Notes ==
<references />

Latest revision as of 01:32, 3 March 2015

Basic request passing variables as POST[edit]

Use --data or -d option to pass variables to the page.

$ curl -d "user=mylogin&pass=mypass&foo=bar&biz=bash" http://www.mydomain.com/mypage/

Request using basic authentication[edit]

Use --user or -u option.

$ curl -u mylogin:mypass -d "user=mylogin&pass=mypass&foo=bar&biz=bash" http://www.mydomain.com/mypage/

Request using Windows integrated authentication[edit]

Add --ntlm option.

$ curl -u mylogin:mypass --ntlm -d "user=mylogin&pass=mypass&foo=bar&biz=bash" http://www.mydomain.com/mypage/

Special characters in username or password[edit]

Escape special characters with back slash.

$ curl -u mylogin:myp\&ss --ntlm -d "user=mylogin&pass=mypass&foo=bar&biz=bash" http://www.mydomain.com/mypage/

Storing arguments in a text file[edit]

Content of file, saved as curlargs.txt:

-d foo=bar&biz=bash http://localhost/mytestpage.html

Run curl using contents of curlargs.txt (in a bash shell):

$ cat curlargs.txt | xargs -n3 curl

Sending request headers[edit]

> curl -H "X-MyHeader: 123" www.google.com

The argument is either -H or --header followed by header name, colon, and header value.

For example, to send an Accept request-header for JSON data: -H "Accept: application/json".

To view the request that is sent add the -v option to curl.

Handling quotes in POST data[edit]

Problem: The value of the -d or --data argument (typically a JSON string) contains either a single or double quote:

# Error is thrown when it hits the first quote in the ''title'' string.
curl -d '{ "id": "6650", "title": "A record title containing 'quotes'."}' http://mydomain.com/path/to/page/

Solution: Use the @ character to read the data from a separate file.

Curl arguments stored in curargs.txt:

-d @jsondata.txt http://mydomain.com/path/to/page/

Contents of jsondata.txt:

{ "id": "6650", "title": "A record title containing 'quotes'."}

Then pass the contents of the two files to curl with

$ cat curlargs.txt | xargs -n3 curl

Sending POST requests to Django projects[edit]

Because of Cross Site Request Forgery protection in Django, POST requests have to include a CSRF token generated by the Django app.

It's not really practical or safe to generate the token so it can be used with curl.

Instead right above the Django view that is being called, place an CSRF exemption:

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')

It's possible to pass the token with curl:

curl
 -X POST
 -d "email=test@test.com&a=1&csrfmiddlewaretoken=<inserttoken>"
 --cookie "csrftoken=[as above]"
 http://127.0.0.1:8083/registrations/register/

It's also possible to use --header "X-CSRFToken: <token>" instead of including it in the form data.

Following redirects[edit]

$ curl -L -X POST -d "foo=bar&biz=bash" http://dev-server.com
  • -L location Tells curl to reattempt the get if the server reports that the page is at a different location (301 and 302 responses)
  • -X POST Explicitly use the POST method (as opposed to the -d option which implicitly uses POST.[1] (man.cx manual pages)

This happens with Symfony, which sends a 301 response with its controllers.[2],[3]

N.B. This did not work on the first attempt with Symfony. Not sure if it's not a solution, or if I was doing something wrong.

Notes[edit]