You can pass data into curl via STDIN like so:
echo -e '...data...\n' | curl -X POST --data-binary @- http://foo.com
The @-
tells curl
to pull in from STDIN.
To pipe binary data to curl (for example):
echo -e '\x03\xF1' | curl -X POST --data-binary @- http://foo.com
The relevant RFC, Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing contains the answer to your question: that each line of a HTTP request should end with CR/LF.
The grammar for the HTTP Message Format specifies that each header line should end with a Carriage Return character (0x0d
in ASCII) followed by a line feed character (0x0a
):
HTTP-message = start-line
*( header-field CRLF )
CRLF
[ message-body ]
This is expressed more clearly in the description of the Request Line:
A request-line begins with a method token, followed by a single space (SP), the request-target, another single space (SP), the protocol version, and ends with CRLF.
request-line = method SP request-target SP HTTP-version CRLF
Since curl
is a specifically developed for HTTP requests it already uses the appropriate line-endings when making HTTP requests. However, netcat is a more general purpose program. As a Unix utility, it uses line-feed characters for line endings by default, thus requiring the user to ensure that lines are terminated correctly.
You can use the unix2dos
utility to convert the file containing the request headers to use Carriage Return / Line Feed endings.
If you want to type the HTTP request by hand and have a recent version of nc
, you should use its -C
option to use CRLF
for line endings:
nc -C www.youtypeitwepostit.com 80
By the way, it’s worth noting that most popular Internet protocols (e.g., SMTP) use CR/LF line endings.
Note that some web servers (e.g. Apache) are more forgiving and will accept request lines that are terminated only with a Line Feed character. The HTTP specification allows for this, as mentioned in the Message Parsing Robustness section:
Although the line terminator for the start-line and header fields is the sequence CRLF, a recipient MAY recognize a single LF as a line terminator and ignore any preceding CR.
Best Answer
The simplest way is to store the response and compare it:
I haven't tested that. The syntax might be off, but that's the idea. I'm sure there are more sophisticated ways of doing it such as checking curl's exit code or something.
update
curl
returns quite a few exit codes. I'm guessing a failed post might result in55 Failed sending network data.
So you could probably just make sure the exit code was zero by comparing to$?
(Expands to the exit status of the most recently executed foreground pipeline.
):Or if your command is relatively short and you want to do something when it fails, you could rely on the exit code as the condition in a conditional statement:
I think this format is often preferred, but personally I find it less readable.