5 obscure HTTP methods to impress your hipster friends

April 13, 2020
Written by

5 obscure HTTP methods to impress your hipster friends

GET, POST, PUT, and DELETE are classics for a reason but also they’re soooo 1999. In this post, you’ll learn about 5 HTTP methods you’ve probably never heard of.

If you’re new to web development, you may want to check out this guide to REST APIs first.

1. PATCH

Image of a small dog with a peg leg, an eye patch, and a pirate hat with its ears adorably poking through.

"Pirate Dog" by Tony Werman is licensed under CC BY 2.0.

PATCH is similar to PUT, but with a couple of key differences.

Let’s review the difference between PUT and POST, because TBH I need to look it up every time. PUT is idempotent and POST is not.

I·dem·po·tent, /ˌīdemˈpōt(ə)nt (adjective)

An operation is idempotent if it produces the same result no matter how many times you run it. In terms of APIs, let’s say you had a  /v1/corgis/create endpoint. If you made a POST request to /v1/corgis/create?color=fawn twice, you’d have created two fawn corgis. If you made two identical PUT requests, PUT would only create a new corgi the first time. For this reason, often POST is used for creating new resources while PUT is used for updating existing ones.

PATCH requests only update part of a resource. You supply a “diff” so that the server knows which parts of the resource to update. PUT requests must supply the entire resource to be updated.

For example, let’s say we have the following resource:

{
  "name": "Ollie",
  "breed": "Corgi,
  "age": "2",
}

And then we apply the following update with PATCH:

{
  "color": "sable"
}

The entire resource contains the following attributes:

{
  "name": "Ollie",
  "breed": "Corgi,
  "age": "2",
  "color": "sable"
}

If you took that PATCH call and made it a PUT, your entire resource would only contain the `color` attribute:

 

{
  "color": "sable"
}

PATCH doesn’t have to be idempotent, but it can be.

What’s the advantage of using PATCH? PATCH requests take up less bandwidth than the corresponding PUT request, as PUT requests need to specify the entire resource.

2. CONNECT

animated black and white gif of two dogs in bow ties "speaking" on old-fashioned telephones.

HTTP requests can be either encrypted or unencrypted. Unencrypted requests are sent in plain text, which means an attacker could see exactly what data is requested and returned.  

Encrypted requests are sent securely via transport-level security (TLS). Only the client and server can decode the requests and responses. An attacker intercepting encrypted traffic would only see seemingly random strings of characters. Not only the request and response is encrypted -- the hostname and port are too.

A proxy is a server that forwards requests to another server. Proxies are useful for lots of things, such as:

  • caching pages to improve performance
  • getting around restrictions, like nation-state firewalls or parental control software

What happens if you want to pass an encrypted request through a proxy? Since the hostname and port are also encrypted, the proxy wouldn’t know where to send the request. That’s where CONNECT comes in. The browser sends a CONNECT request to the proxy, specifying the hostname and port of the final destination server, followed by a bunch of encrypted bytes to pass through.

Note that CONNECT requests are not idempotent. CONNECT leaves the TCP connection in a different state afterwards, which is technically considered a side effect.

3. OPTIONS

animated gif of AT LEAST 10, possibly more, puppies (beagles maybe?) running out of the trunk of a car.

OPTIONS explains what options exist for a particular endpoint. Sensible naming there. What’s it used for?

In general, browsers only let you make fetch and XmlHttp requests from the same domain, protocol, and port. For example, from JavaScript code on https://www.twilio.com/en-us  I cannot fetch data from http://foo.horse. This restriction is known as the same-origin policy (SOP). The SOP prevents websites from attacking one another. If foo.horse could make a request to gmail.com, it could access the session cookies from gmail.com and read all your email.

Cross-origin resource sharing, or CORS, is a way of saying “hey, it’s okay to make requests from these particular  domains / protocols / ports even if they don’t match.” CORS requests and responses are coordinated via the exchange of HTTP headers.

Some CORS requests that are more complex trigger preflighting. Preflighted requests make an OPTIONS call, to figure out if the request that comes after that is allowed. The server then has an opportunity to determine whether the request is acceptable. If yes, the actual request is sent after the OPTIONS call.

4. HEAD

animated gif of a corgi in a box with only its head sticking out, running around the corner and looking around.

Head is exactly like a GET request, but it doesn’t return the request body. Bo-ring. What is HEAD actually useful for? The only use case I could come up with is caching. If you grab the lastModified and or contentLength headers, you could decide whether you want to refetch an entire resource or load it from cache. Cache invalidation is the second hardest problem in computer science, after all.

If you’ve got good uses for HEAD that I’m not thinking of, please come at me on Twitter.

To make a HEAD request from the command line you’d run this command:

curl --head https://twilio.com

And get the following response:

HTTP/2 301
content-type: text/html
content-length: 150
location: https://www.twilio.com:443/
server: awselb/2.0
date: Thu, 09 Apr 2020 00:08:05 GMT
x-cache: Miss from cloudfront
animated gif of a corgi puppy chasing its leash around an upturned milk crate in an endless circle.


TRACE echoes request input back to the sender, which can be useful for debugging proxy server issues.

TRACE is widely considered to be a security vulnerability, but is it really?

OWASP says you should disable TRACE as it can be used for Cross-Site Tracing (XST). As a vulnerability, cross-site tracing (XST) is a little misunderstood. As we discussed earlier, modern browsers disallow sending cross-site requests from scripts for security reasons. Furthermore, modern browsers prevent you from sending TRACE requests from JavaScript at all. Go ahead, open a JS console in your browser and try running this code:

const xhr = new XMLHttpRequest();
xhr.open('TRACE', 'http://twilio.com/', false);
xhr.send(null);

Unless you have a strong reason to need TRACE capabilities, might as well disable it on your servers. TRACE can still leak header information you may not want exposed. Better safe than sorry.

The End

Now that you know about these arcane request methods, you’ll undoubtedly be the most popular httpster at the party. Go forth and impress people, you glorious nerd you.

animated gif of a rather hipster dog dressed in a button up shirt, tie, and glasses, turning to "smile" at the camera.