A Redis HTTP interface with JSON output
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
Nicolas Favre-Felix 95945578b8 Ideas 14 years ago
formats Refactoring. 14 years ago
hiredis HiRedis update. 14 years ago
jansson Added missing file. 14 years ago
libb64 Base64 encode of user:password for HTTP Basic Auth. 14 years ago
md5 Added ETag and If-None-Match. 14 years ago
COPYING Added missing license file. 14 years ago
Makefile Added ETag and If-None-Match. 14 years ago
README.markdown Ideas 14 years ago
acl.c ACL refactoring. 14 years ago
acl.h ACL refactoring. 14 years ago
cmd.c Cleanup. 14 years ago
cmd.h Cleanup. 14 years ago
conf.c Drop privileges. 14 years ago
conf.h Drop privileges. 14 years ago
server.c Removed debug info. 14 years ago
server.h Refactoring 14 years ago
webdis.c Refactoring 14 years ago
webdis.json ACL doc. 14 years ago

README.markdown

About

A very simple web server providing an HTTP interface to Redis. It uses hiredis, jansson and libevent.

make clean all
./webdis &
curl http://127.0.0.1:7379/SET/hello/world
→ {"SET":[true,"OK"]}
curl http://127.0.0.1:7379/GET/hello
→ {"GET":"world"}

curl -d "GET/hello" http://127.0.0.1:7379/
→ {"GET":"world"}

Features

  • GET and POST are supported.
  • JSON output by default, optional JSONP parameter (?jsonp=myFunction).
  • Raw Redis 2.0 protocol output with .raw suffix
  • HTTP 1.1 pipelining (50,000 http requests per second on a desktop Linux machine.)
  • Connects to Redis using a TCP or UNIX socket.
  • Restricted commands by IP range (CIDR subnet + mask) or HTTP Basic Auth, returning 403 errors.
  • Possible Redis authentication in the config file.
  • Pub/Sub using Transfer-Encoding: chunked, works with JSONP as well. Webdis can be used as a Comet server.
  • Drop privileges on startup.
  • Custom Content-Type using a pre-defined file extension.
  • URL-encoded parameters for binary data or slashes. For instance, %2f is decoded as / but not used as a command separator.

Ideas, TODO...

  • Support PUT, DELETE, HEAD, OPTIONS? How? For which commands?
  • MULTI/EXEC/DISCARD/WATCH are disabled at the moment; find a way to use them.
  • Add logs.
  • Support POST of raw Redis protocol data, and execute the whole thing. This could be useful for MULTI/EXEC transactions.
  • Enrich config file:
    • Provide timeout (this needs to be added to hiredis first.)
  • Multi-server support, using consistent hashing.
  • Add WebSocket support (with which protocol?)
  • Allow cross-origin XHR.
  • Allow file upload with PUT? Saving a file in Redis using the SET command should be easy to do with cURL.
  • Send your ideas using the github tracker, on twitter @yowgi or by mail to n.favrefelix@gmail.com.

HTTP error codes

  • Unknown HTTP verb: 405 Method Not Allowed
  • Redis is unreachable: 503 Service Unavailable
  • Matching ETag sent using If-None-Match: 304 Not Modified.
  • Could also be used:
    • Timeout on the redis side: 503 Service Unavailable (this isn't supported by HiRedis yet).
    • Missing key: 404 Not Found.
    • Unauthorized command (disabled in config file): 403 Forbidden.

Command format

The URI /COMMAND/arg0/arg1/.../argN executes the command on Redis and returns the response to the client. GET and POST are supported:

  • GET /COMMAND/arg0/.../argN
  • POST / with COMMAND/arg0/.../argN in the HTTP body.

Special characters: / and . have special meanings, / separates arguments and . adds a file extension to change the Content-Type. They can be replaced by %2f and %2e, respectively.

ACL

Access control is configured in webdis.json. Each configuration tries to match a client profile according to two criterias:

Each ACL contains two lists of commands, enabled and disabled. All commands being enabled by default, it is up to the administrator to disable or re-enable them on a per-profile basis. Examples:

{
	"disabled":	["DEBUG", "FLUSHDB", "FLUSHALL"],
},

{
	"http_basic_auth": "user:password",
	"disabled":	["DEBUG", "FLUSHDB", "FLUSHALL"],
	"enabled":	["SET"]
},

{
	"ip": 		"192.168.10.0/24",
	"enabled":	["SET"]
},

{
	"http_basic_auth": "user:password",
	"ip": 		"192.168.10.0/24",
	"enabled":	["SET", "DEL"]
}

ACLs are interpreted in order, later authorizations superseding earlier ones if a client matches several.

JSON output

JSON is the default output format. Each command returns a JSON object with the command as a key and the result as a value.

Examples:

// string
$ curl http://127.0.0.1:7379/GET/y
{"GET":"41"}

// number
$ curl http://127.0.0.1:7379/INCR/y
{"INCR":42}

// list
$ curl http://127.0.0.1:7379/LRANGE/x/0/1
{"LRANGE":["abc","def"]}

// status
$ curl http://127.0.0.1:7379/TYPE/y
{"TYPE":[true,"string"]}

// error, which is basically a status
$ curl http://127.0.0.1:7379/MAKE-ME-COFFEE
{"MAKE-ME-COFFEE":[false,"ERR unknown command 'MAKE-ME-COFFEE'"]}

// JSONP callback:
$ curl  "http://127.0.0.1:7379/TYPE/y?jsonp=myCustomFunction"
myCustomFunction({"TYPE":[true,"string"]})

RAW output

This is the raw output of Redis; enable it with the .raw suffix.


// string
$ curl http://127.0.0.1:7379/GET/z.raw
$5
hello

// number
curl http://127.0.0.1:7379/INCR/a.raw
:2

// list
$ curl http://127.0.0.1:7379/LRANGE/x/0/-1?.raw
*2
$3
abc
$3
def

// status
$ curl http://127.0.0.1:7379/TYPE/y.raw
+zset

// error, which is basically a status
$ curl http://127.0.0.1:7379/MAKE-ME-COFFEE.raw
-ERR unknown command 'MAKE-ME-COFFEE'

Custom content-type

Several content-types are available: * .json for application/json (this is the default Content-Type). * .txt for text/plain * .html for text/html * .png for image/png

curl -v "http://127.0.0.1:7379/GET/hello.html"	# the key is “hello” here, not “hello.html”
[...]
< HTTP/1.1 200 OK
< Content-Type: text/html
< Date: Mon, 03 Jan 2011 20:43:36 GMT
< Content-Length: 137
<
<!DOCTYPE html>
<html>
...
</html>