Curl exercises
jvns.ca
jvns.ca
This will output the HTTP status code for a given URL.
alias hstat="curl -o /dev/null --silent --head --write-out '%{http_code}\n'" $1
Example: $ hstat google.com
301
I also use curl as an 'uptime monitor' by adding onto that code section. (a file with a list of URLs, and "if http status code !=200" then email me.)There are variations on this all over the place but I really depend on it and I like it.
Also works great with fx (https://github.com/antonmedv/fx). Just pipe the output from HTTPie and you get easy json processing.
cURL really is an excellent tool for web debugging. Using something like "Copy as cURL" makes it possible to generate a request which is textually identical to a request made by a real browser, which is really important when debugging subtle weirdness in a browser (or, exploring a web server for bugs!). It's easy to script and comes with a decent progress UI. It's also practically omnipresent and slightly more common than wget - I often need to use foreign systems where I have to make do with the least-common denominator tools, so learning the ins and outs of cURL have been quite handy for me.
cat payload.json | curl $url --data -@-
You can use this to re-play access logs, like so: sed -n 23p accesslog.json | jq '.args' | curl $endpoint --data -@-For example if you want to download a gallery of images with some fixed format you can do
curl "http://example.com/imgs/[01-99].jpg" -o "#1.jpg"
And it will fetch them and name them with the correct zero padding.Or if you want to download the first 10 pages of hn:
curl https://news.ycombinator.com/news?p=[1-10] -o "hn_page_#1.html"
It can glob pretty complicated patterns! See this for syntax: https://ec.haxx.se/cmdline-globbing.html wget http://example.com/imgs/{01..99}.jpg c=x; while [ $c ]; do clear; curl -c k -b k hex.m-chrzan.xyz/$c; read c; done
(just make sure you don't have an important file called "k" in the directory you run it in, or it will get overwritten)Most web browsers have a "Copy as cURL" function in the web developer menus.
in Firefox it is: tools -> Web Developer -> Network
Under this tab, you will see all the requests used to construct a web page.
You can right click on an item and do "Copy as cURL"
If a web page has some API you want to explore or use in a program, you can recreate it this way.
curl -vsI https://example.com | grep "^[<>] "Maybe a kind of "digital archaeology" story, in which you have to coax data off of an old server in various ways and analyze old git repos? Does sound kind of fun...
After making changes to some argument values in the body, I was getting a weird error. It turns out that I was suppose to also update the content length header. The work around was to simply eliminate that header. But I wasn’t able to find a good explanation as to why.
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://www.google.com/">here</A>.
</BODY></HTML>
So not an empty response...Another exercise could be to have a page where the Access Control Allow Origin is set to a specific domain, then make a request by setting a different origin.
E.g:
curl -H "Origin: https://wrong.origin.com" https://httpbin.org/anything
Many people think CORS is enforced by the server.I am interested in this because we're starting to work on a project where these two ingredients will come together.
After looking at the cURL site, it looks like someone had the need and the will to bake in kerberos, so why not OAuth? Then I looked at the OAuth specs. It would be quite an undertaking for sure, but it could be good :-)
There is also the -w option to format. Sometimes I’ll write a small python script to pipe output into for wrangling data.
Or near enough to that effect.
There are several complications:
- URI building (things that need URL escaping)
- path components
- query parameters
- headers
- including common standard ones that should have
their own command-line options
- things like ETags that can benefit from storing
them in xattrs
- things like conditional requests and range
requests (think download restart)
- whether there's a body
- whether it's an "HTML form" or something else
- Content-Type
- whether to chase redirects
- trust anchors for TLS (HTTPS)
- what to do with response headers
- how to integrate filtering of response body vs
headers (can't use stderr for either)
- authentication options
- cookie jars
- proxies and proxy auth
HTTP is such a complex beast that using it from a shell feels fraught with peril.For ease of use in a functional way, it'd be nice if, for example, one could set a header value as-is on the command-line, but also by reading from a file (or possibly a pipe, so read only once).
Perhaps something like:
$ VERB $base_URI [options]
with options for: - appending URI local part elements
- adding query parameters
- adding headers
- specifying where to write response headers
- specifying where to write response body
- if a file, maybe set [some] response headers
as xattrs!
- specifying request body source (default: stdin
for VERBs that normally have a request body)
- trust anchors
- authentication
Examples: $ # GET with various options:
$ GET https://base-URI-here \
-a local-part-element \
-q param value -q ... \
-H header value ...
$
$ # POST with file as request body source
$ POST https://base-URI-here \
--file file
$ # POST with HTML form specified on command-line
$ POST https://base-URI-here \
--form field value --form field value ...
$
$ # And so on for all HTTP methods
Besides the options shown above, which are fairly obvious, it'd be nice to have: --rheaders PATH # where to put headers
--xheader header # save given response header
# value as an xattr
-T trust_anchors.pem # or a directory, or whatever
-C client_cert_and_key.pem
-U username # for Basic, DIGEST, SCRAM
--password-file FILE # for Basic, DIGEST, SCRAM
-N ... # For Negotiate. This could
# be key/value pairs that can
# be used with
# gss_acquire_cred_from()
-J ... # Get a JWT token and use it
A convention for using xattrs for storing Content-Type and ETag (and a few other things perhaps) would be very very nice. wget http://something.comConsider how you might write your comment if the sex of the OP was male - would you make the same statement?
You may have missed the key word there: "platonic".
Consider how you might be hurting your cause and lowering the quality of discourse here by being overly sensitive and self-righteous; if you knew the lengths to which I've gone in support and defense of my gay and trans-gendered cousins, would you refrain from polluting the thread w/ knee-jerk PC Politburo bs?
"I want to lean to program" or "I want to become a better programmer"
Her blog still has that pure joy of learning and doing with computers that we all remember.
% which curl
/usr/bin/curl
% which cURL
cURL not found