HTTP language representation - http

In the HTTP language, the following lines expresses a GET request on a collection of articles:
GET /articles HTTP/1.1
Accept: application/json; level=1
Host: example.com
However, in this language, how can we express a request through a POST with its data? Is there an official spec? Thank you.
Edit
Using curl, a such request could be:
curl -H 'Accept: application/json; level=1' \
-X POST \
-d '<json>' \
http://example.com/articles
...where <json> could be:
{
"article": {
"title": "foo"
}
}

This example can be a POST with an empty body since your request is composed only of HTTP headers. But I don't recommend this.
You can read about HTTP in the RFC

Related

Symfony Request::getContent(true) strange behaviour in wget but not curl

A user is able to upload a file. During the upload the file is scanned. If there is an issue with the file Symfony returns a Response(400) and the rest of the file is not uploaded, saving the user and the host time and bandwidth.
This is done via \Symfony\Component\HttpFoundation\Request::getContent(true)
$resource = $request->getContent(true);
The file is scanned a line at a time using:
fgets($resource);
The resource is also closed before the response is sent to the user:
fclose($resource);
However there is unexpected and strange behaviour happening for some user clients.
For example wget:
wget -4 --no-check-certificate --method PUT --timeout=0 --header 'Authorization: Bearer xxx' --body-file='xxx' 'https://example.com/xxx' --content-on-error -d -O -
Response hangs:
---request begin---
PUT /xxx HTTP/1.1
User-Agent: Wget/1.20.3 (linux-gnu)
Accept: */*
Accept-Encoding: identity
Host: xxx
Connection: Keep-Alive
Content-Length: 37767602
Authorization: Bearer xxx
---request end---
[writing BODY file xxx ...
It appears that wget does not understand the upload does not need to be completed, is this a header that php is failing to send or a flag required in the wget command?
A similar command in curl works
curl -k --location --request PUT 'https://example.com/xxx' \
--header 'Authorization: Bearer xxx' \
--data-binary '#/xxx'
Response
< Server: Apache/2.4.38 (Debian)
< Vary: Authorization
< X-Robots-Tag: noindex
< Transfer-Encoding: chunked
* HTTP error before end of send, stop sending
<
* Closing connection 0
* TLSv1.3 (OUT), TLS alert, close notify (256):

How to create special http requests using curl?

What I want to do is, is create special fuzz based request using curl for type 1 and another type 2 request which is based on 4 requests simultaneously and separately using curl, there is a command of perl, I also want that to include in the request
This is what I came up with.
My Curl Code Type 1:
curl -X GET -d '
Content-Length: 22
Foo: HTTP/1.1 200 OK
Content-Length: 0
Content-Type: text/html
Last-Modified: ...
Refresh: 0; URL=http://www.google.com/
Bar:
' -i $Local'
My Curl Code Type 2 for 4 requests:
#!/bin/bash
echo -e "[ + ] Enter Local Server
read Local
curl -X POST -d ' / HTTP/1.1
Host: google.com
Connection: Keep-Alive
Content-Length: 49225
perl -e 'print (A x 49255)
-i '$Local'
curl -X POST -d ' / HTTP/1.1
Host: google.com
Connection: Keep-Alive
Content-Length: 33
-i '$Local'
curl -X POST -d ' / HTTP/1.1
xxxx: POST /loader/cmd.exe?/c+dir HTTP/1.1
-i '$Local'
curl -X POST -d ' / HTTP/1.1
Connection: Keep-Alive
It didn't work, I tried lots of method, I am not familiar with this type of requests. I want to include exactly all this, what you're seeing.
Error was:
./curl.sh: line 2: unexpected EOF while looking for matching
./curl.sh: line 27: syntax error: unexpected end of file

curl uses POST for all requests after redirect

According to the documentation and some similar questions on SO curl should follow a redirect using GET method, unless --post30x is specified as a parameter. However that's the result of my testing
curl -kvv -b /tmp/tmp.BEo6w3GKDq -c /tmp/tmp.BEo6w3GKDq -X POST -H "Accept: application/json" -L https://localhost/api/v1/resource
> POST /api/v1/resource HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost
> Cookie: JSESSIONIDSSO=AB59F2FD09D38EDBAACB726CF212EA2E; JSESSIONID=743FD68B520840094B6D283A81CF3CFA
> Accept: application/json
>
< HTTP/1.1 302 Found
< Server: Apache-Coyote/1.1
< Strict-Transport-Security: max-age=15768000; includeSubDomains
< Cache-control: no-cache, no-store
< Pragma: no-cache
< Location: https://testserver.int/api/v1/resource
< Content-Length: 0
< Date: Fri, 27 Jan 2017 08:41:05 GMT
<
> POST /api/v1/resource HTTP/1.1
> User-Agent: curl/7.29.0
> Host: testserver.int
> Cookie: JSESSIONID=1tcxpkul4qyqh1hycpf9insei9
> Accept: application/json
I would expect the second request to actually be using GET instead of POST.
curl's man page says:
When curl follows a redirect and the request is not a plain GET (for
example POST or PUT), it will do the following request with a GET if
the HTTP response was 301, 302, or 303. If the response code was any
other 3xx code, curl will re-send the following request using the same
unmodified method.
You can tell curl to not change the non-GET request method to GET
after a 30x response by using the dedicated options for that:
--post301, --post302 and --post303.
Unfortunatelly that's not what I'm seeing and there is no option for --get30x.
So my question is - how to make curl follow a redirect response (301/302/303) with a GET request to the Location as it is written in the documentation?
I've tested it with curl/7.29.0 as well as curl/7.50.3.
Problem: You are telling curl to do that with your use of -X POST. As the man page section for -X explains this:
The method string you set with -X, --request will be used for all requests, which
if you for example use -L, --location may cause unintended side-effects when curl
doesn't change request method according to the HTTP 30x response codes - and
similar.
Fix: Remove the -X POST from your command line. Use -d "" instead to send an empty post that will adjust accordingly to the proper method after redirect.
More: Explanation and rant in my blog post unnecessary use of curl -X.

How to send a POST request using HTTPie?

I have a basic silex application, and I try to test it using HTTPie. Yet when posting using:
http POST http://localhost:1337 data="hello world"
The data, that I get from the Request object via:
$data = $request->request->get('data');
will always be empty. What is the problem here?
It was an httpie usage problem as the form flag was necessary, as silex requires the parameters to be form-encoded, yet the default of HTTPie is to pass a JSON object.
$ http --form POST http://localhost:1337 data="hello world"
HTTP/1.1 200 OK
Cache-Control: no-cache
Connection: close
Content-Type: application/json
Date: Wed, 14 Oct 2015 15:04:09 GMT
Host: localhost:1337
X-Powered-By: PHP/5.5.9-1ubuntu4.13
{
"message": "hello world"
}
Just to clarify what kOpernikus said, when you are making a POST request using httpie, use the following syntax:
http --form post :3000/register username="gilbert" password="stackoverflow!"
Alternatively, since forms are for post requests you can leave out post and also abbreviate --form to -f like so:
http -f :3000/register username=gilbert password=stackoverflow!
EDIT (thanks to Aerials)
To pass csrf token as header in the post request do:
http --form POST http://localhost:8000/login/ username=user password=pass X-CSRFToken:assQ$%auxASDLSIAJSd

How do I POST form data with UTF-8 encoding by using curl?

I would like to POST (send) some form data to a webserver using cURL on a terminal-prompt.
This is what I got so far:
curl --data-ascii "content=derinhält&date=asdf" http://myserverurl.com/api/v1/somemethod
The problem is that the umlaute ("äöü") are replaced by "?" when I receive the post request on the server.
I think I need to use an UTF-8 encoding for the POST request.
Does anybody know how I can achieve this?
You CAN use UTF-8 in the POST request, all you need is to specify the charset in your request.
You should use this request:
curl -X POST -H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" --data-ascii "content=derinhält&date=asdf" http://myserverurl.com/api/v1/somemethod

Resources