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.
 
 
 
 
 
 
mrb 133ceccbc5 gitignore tweak 14 years ago
formats Cleanup. 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
.gitignore gitignore tweak 14 years ago
COPYING Added missing license file. 14 years ago
Makefile first pass at a simple log 14 years ago
README.markdown Drop privileges. 14 years ago
acl.c ACL refactoring. 14 years ago
acl.h ACL refactoring. 14 years ago
cmd.c ACL refactoring. 14 years ago
cmd.h Refactoring 14 years ago
conf.c first pass at a simple log 14 years ago
conf.h first pass at a simple log 14 years ago
server.c first pass at a simple log 14 years ago
server.h Refactoring 14 years ago
slog.c first pass at a simple log 14 years ago
slog.h first pass at a simple log 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.
  • Raw Redis 2.0 protocol output with ?format=raw
  • 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.

Ideas, TODO...

  • Add meta-data info per key (MIME type in a second key, for instance).
  • 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.
  • 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
  • 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.

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 ?format=raw.


// string
$ curl http://127.0.0.1:7379/GET/z?format=raw
$5
hello

// number
curl http://127.0.0.1:7379/INCR/a?format=raw
:2

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

// status
$ curl http://127.0.0.1:7379/TYPE/y?format=raw
+zset

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