curl -XPOST --jp username=YOUR.USERNAME password=YOUR.PASSWORD https://api.ctl.io/v2/authentication/login
Which isn't too far from your desired outcome (notably, without relying on argument position for meaning). Although, I guess the argument that "curl is already installed on almost every server", sorta gets moot because I imagine it will take a while for most distros to move to the latest curl that will support --json/--jpThere's a happy medium, and we're not in it.
Curl is a command line tool. As long as they only add new functionality, there is very little that prevents an upgrade.
Most dependencies get updated much more quickly. It wouldn't even shock me if this change got picked up mid-cycle.
POST https://api.ctl.io/v2/authentication/login
{
"username": "YOUR.USERNAME",
"password": "YOUR.PASSWORD"
}
and it will send the same POST request with a json body: hurl post.hurl
You can add asserts on the response too: POST https://api.ctl.io/v2/authentication/login
{
"username": "YOUR.USERNAME",
"password": "YOUR.PASSWORD"
}
HTTP/1.0 200
[Asserts]
jsonpath "$.status" == "LOGGED"
Under the hood, we use libcurl and a Rust binding. The HTTP engine is curl because curl is awesome! curl -d @post.json http://example.comAwesome name.
Happy to see that xh supports HTTP/2 out of the box.
I alias it to http so it's memorable and the commands make more sense though.
$ jo foo=$(jo bar=qux) | http example.com
Piped JSON automatically uses POSTYou might be in luck since Nested JSON support is going to be star feature of our upcoming release. Here is a sneak peek:
$ http --offline --print=B pie.dev/post \ search[type]=client \ search[stars]:=50000 \ search[platforms][]=Web \ search[platforms][]=Desktop \ search[platforms][]=Mobile \ search[platforms][]=CLI
{ "search": { "platforms": [ "Web", "Desktop", "Mobile", "CLI" ], "stars": 50000, "type": "client" } }
We are rolling a brand-new mini-language that integrates really well with the existing request building syntax, but also features stuff like JSON type-safety and amazing error messages for basic syntax errors.
curl -H'Content-Type: application/json' -d @- << 'JSON'
Invoke with post_json <url>
Then just paste or write JSON without caring about quotes etc, finish the heredoc, done.I can hand another dev a curl statement without having to worry if they have the requisite software to reproduce the call.
Also Postman, Insomnia, Sentry, & Swagger all support ability export to curl.
-s: if HTTPie disables progress bar by default, that's just a different design choice, the advantage is in the eye of the beholder
--data '{"user...: likewise, HTTPie's default to JSON is a design choice. I wouldn't say the default is superior
-H "Content-Type...: likewise, if HTTPie adds this header by default, thats just getting in my way when I don't want that header
-X POST: you don't need to specify that in cURL if using --datahttps POST api.ctl.io/v2/authentication/login username=YOUR.USERNAME password=YOUR.PASSWORD
You can use the `name==value` query parameter syntax [0]:
$ http --offline pie.dev/get AAA==AAA AAA==BBB
GET /get?AAA=AAA&AAA=BBB HTTP/1.1
Or simply: $ http --offline 'pie.dev/get?AAA=AAA&AAA=BBB'
GET /get?AAA=AAA&AAA=BBB HTTP/1.1
[0]https://httpie.io/docs/cli/querystring-parameters post api.ctl.io/v2/authentication/login < 1.txt|openssl s_client -connect api.ctl.io:443
post is a 702-character shell script. printf is a built-in. #!/bin/sh
(
y=Connection;n=0;while read x;do
x1=${1#*//};x2=${x1%%/*};x3=${x1#*/};
x=$(printf "%s" "${x%%:*}:";echo "${x#*:}");
if test x"${x3}" = x"${x2}";then x3="";fi;
printf "%s\r\n%s\r\n%s\r\n%s\r\n" \
"POST /${x3} HTTP/1.1" \
"Host: ${x2}" \
"Content-Type: application/json" \
"Content-Length: ${#x}";
if [ $n -gt 1 ];then
printf "%s\r\n\r\n%s\r\n" "$y: keep-alive" "$x";else
printf "%s\r\n\r\n%s\r\n" "$y: close" "$x";fi;
export n=$((n+1));
done;
if [ $n -gt 1 ];then
printf "%s\r\n%s\r\n%s\r\n" \
"GET /robots.txt HTTP/1.0" \
"Host: ${x2}" \
"$y: close";fi;
)
Data to be posted may be stored in a one-line file named "1.txt" cat > 1.txt
{ "username": "YOUR.USERNAME", "password": "YOUR.PASSWORD" }
^D
Examine the request post api.ctl.io/v2/authentication/login < 1.txt
POST the request post api.ctl.io/v2/authentication/login < 1.txt|nc -vvn 127.1 80
Alternatively, data to be posted can be read from stdin echo '{ "username": "YOUR.USERNAME", "password": "YOUR.PASSWORD" }' \
|post api.ctl.io/v2/authentication/login \
|nc -vvn 127.1 80
If the data to be posed is JSON formatted as multiple lines such as {
"username": "YOUR.USERNAME",
"password": "YOUR.PASSWORD"
}
then (tr -d '\12' < 1.txt;echo) \
|post api.ctl.io/v2/authentication/login \
|nc -vvn 127.1 80
For TLS we use proxy listening on 127.0.0.1, e.g., stunnel, sslsplit, haproxy, etc. cat > 1.cfg
pid=/tmp/1.pid
[ x ]
accept=127.0.0.1:80
client=yes
connect=64.15.182.200:443
options=NO_TICKET
options=NO_RENEGOTIATION
renegotiation=no
sni=
sslVersion=TLSv1.3
^D
stunnel 1.cfg post api.ctl.io/v2/authentication/login < 1.txt|openssl s_client -connect api.ctl.io:443 -ign_eof
post is a 702-character shell script. printf is a built-in. #!/bin/sh
(
y=Connection;n=0;while read x;do
x1=${1#*//};x2=${x1%%/*};x3=${x1#*/};
x=$(printf "%s" "${x%%:*}:";echo "${x#*:}");
if test x"${x3}" = x"${x2}";then x3="";fi;
printf "%s\r\n%s\r\n%s\r\n%s\r\n" \
"POST /${x3} HTTP/1.1" \
"Host: ${x2}" \
"Content-Type: application/json" \
"Content-Length: ${#x}";
if [ $n -gt 1 ];then
printf "%s\r\n\r\n%s\r\n" "$y: keep-alive" "$x";else
printf "%s\r\n\r\n%s\r\n" "$y: close" "$x";fi;
export n=$((n+1));
done;
if [ $n -gt 1 ];then
printf "%s\r\n%s\r\n%s\r\n" \
"GET /robots.txt HTTP/1.0" \
"Host: ${x2}" \
"$y: close";fi;
)
Data to be posted may be stored in a one-line file named "1.txt" cat > 1.txt
{ "username": "YOUR.USERNAME", "password": "YOUR.PASSWORD" }
^D
Examine the request post api.ctl.io/v2/authentication/login < 1.txt
POST the request post api.ctl.io/v2/authentication/login < 1.txt|nc -vvn 127.1 80
Alternatively, data to be posted can be read from stdin echo '{ "username": "YOUR.USERNAME", "password": "YOUR.PASSWORD" }' \
|post api.ctl.io/v2/authentication/login \
|nc -vvn 127.1 80
If the data to be posted is JSON formatted as multiple lines such as {
"username": "YOUR.USERNAME",
"password": "YOUR.PASSWORD"
}
then something like (tr -d '\12' < 1.txt;echo) \
|post api.ctl.io/v2/authentication/login \
|nc -vvn 127.1 80
For TLS we use proxy listening on 127.0.0.1, e.g., stunnel, sslsplit, haproxy, etc. This way we only ever have to type a single address and port, i.e., 127.1 80, or short alias for the hostname, e.g., echo 127.0.0.1 p >> /etc/hosts. cat > 1.cfg
pid=/tmp/1.pid
[ x ]
accept=127.0.0.1:80
client=yes
connect=64.15.182.200:443
options=NO_TICKET
options=NO_RENEGOTIATION
renegotiation=no
sni=
sslVersion=TLSv1.3
^D
stunnel 1.cfg
For example, here's a JSONy POST request with cURL:
curl -s -H "Content-Type: application/json" -X POST https://api.ctl.io/v2/authentication/login --data '{"username":"YOUR.USERNAME","password":"YOUR.PASSWORD"}'
Here's that same request with HTTPie:
http POST https://api.ctl.io/v2/authentication/login username=YOUR.USERNAME password=YOUR.PASSWORD