This is the third post in a four-part series about extending a simple Webmachine resource. The first part discussed adding support for the HTTP method PUT, and the second part added basic authorization.
ETag
If I'm sharing management of a server with someone else, I want to be careful of overwriting that other person's changes. For instance, I might only want to engage "DANGER_MODE" if I can be sure that "COAST=clear".
I need to know that between my last GET and my next PUT, that the value of the "COAST" variable hasn't changed. I can handle this simply by generating an ETag for the resource:
-export([generate_etag/2]).
generate_etag(RD, Result) ->
{mochihex:to_hex(erlang:phash2(Result)), RD, Result}.
Now I can issue conditional requests. When I GET /_env the response will have an ETag header, which is reasonably guaranteed to change if the environment variables change. I can take that ETag and toss it back in an If-Match, and the request will only succeed if the environment variables are in the same state as I last saw them (because the ETag won't match otherwise). That is:
$ curl -u webmachine:rules -X PUT -H "If-Match: LAST_ETAG" \
-H "Content-type: application/json" http://localhost:8000/_env/ \
-d "{\"DANGER_MODE\":\"engaged\"}"
will only succeed if the enviroment is in the state it was when I issued the request that returned Etag: LAST_ETAG (when, hopefully, I checked to make sure that the coast was clear).
Update: part four is up.
Categories: Development Erlang Webmachine
Post Copyright © 2009 Bryan Fink