Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A redis server with http interface

License

NotificationsYou must be signed in to change notification settings

arnos-stuff/webdis

Repository files navigation

Build

About Webdis

A very simple web server providing an HTTP interface to Redis. It useshiredis,jansson,libevent, andhttp-parser.

Webdis depends on libevent-dev. You can install it on Ubuntu by typingsudo apt-get install libevent-dev or on macOS by typingbrew install libevent.

To build Webdis with support for encrypted connections to Redis, seeBuilding Webdis with SSL support.

Build and run from source

$ 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"}

Try in Docker

$ docker run --name webdis-test --rm -d -p 127.0.0.1:7379:7379 nicolas/webdis0d2ce311a4834d403cc3e7cfd571b168ba40cede6a0e155a21507bb0bf7bee81$ curl http://127.0.0.1:7379/PING{"PING":[true,"PONG"]}# To stop it:$ docker stop webdis-test0d2ce311a483

Docker repositories and Docker Content Trust

Webdis images are published onDocker Hub andAmazon ECR.

Docker Hub

$ docker pull nicolas/webdis:0.1.21$ docker pull nicolas/webdis:latest

Starting from release0.1.12 and includinglatest, Docker Hub images are signed (download public key). You should see the following key ID if you verify the trust:

$ docker trust inspect nicolas/webdis:0.1.21 --prettySignatures for nicolas/webdis:0.1.21SIGNED TAG   DIGEST                                                             SIGNERS0.1.21       bea53be391b11fd8a33d55c5e3d49eb11c4c2f89e9e82ca70b3a91bc9c9aa208   (Repo Admin)List of signers and their keys for nicolas/webdis:0.1.21SIGNER      KEYSnicolasff   dd0768b9d35dAdministrative keys for nicolas/webdis:0.1.21  Repository Key:fed0b56b8a8fd4d156fb2f47c2e8bd3eb61948b72a787c18e2fa3ea3233bba1a  Root Key:40be21f47831d593892370a8e3fc5bfffb16887c707bd81a6aed2088dc8f4bef

The signing keys are listed onthis documentation page; please make sure they match what you see.

Amazon Elastic Container Registry (ECR)

$ docker pull public.ecr.aws/nicolas/webdis:0.1.21$ docker pull public.ecr.aws/nicolas/webdis:latest

A note on ECR and trust:AWS does not support Notary v2 at the time of this writing, althougha security talk from 2020 mentions that the feature could be available in 2021.

The consequence is thatWebdis images on ECR are not signed at this time.

They can still be verified, since the images uploaded there use the exact same hash as the ones on Docker Hub, whichare signed. This means that you can verify the signature using thedocker trust inspect command described above, as long as youalso make sure that the image hash associated with the image on ECR matches the one shown on Docker Hub.

For more details about Content Trust validation with ECR images, refer to the article titledWebdis and Docker Content Trust in theWebdis documentation.

Multi-architecture images

Starting withrelease 0.1.19, Docker images for Webdis are published asmanifest lists supportingmultiple architectures. Each release points to an x86-64 image and an ARM64v8 image:

$ docker manifest inspect nicolas/webdis:0.1.19 | jq -r '.manifests | .[] | .platform.architecture + " -> " + .digest'amd64 -> sha256:2ced2d99146e1bcaf10541d17dbac573cffd02237c3b268875be1868138d3b54arm64 -> sha256:d026c5675552947b6a755439dfd58360e44a8860436f4eddfe9b26d050801248

By defaultdocker pull will download only the relevant image for your architecture, but you canspecify the platform to download the image for a specific architecture, e.g.

$ docker pull nicolas/webdis:0.1.19 --platform linux/arm64/v8

Build and run a Docker image locally

Clone the repository and open a terminal in the webdis directory, then run:

$ docker build -t webdis:custom.[...]$ docker run --name webdis-test --rm -d -p 127.0.0.1:7379:7379 webdis:customf0a2763fd456ac1f7ebff80eeafd6a5cd0fc7f06c69d0f7717fb2bdcec65926e$ curl http://127.0.0.1:7379/PING{"PING":[true,"PONG"]}

To stop it:

$ docker stop webdis-testf0a2763fd456

Docker images and embedded Redis

ℹ️ The Docker imagesprovided on Docker Hub undernicolas/webdis contain both Webdis and an embedded Redis server. They were built this way to make it easy totry Webdis without having to configure a Docker deployment with two containers, but this is likely not the best way to run Webdis in production.

The following documentation pages cover various such use cases:

More articles are available in theWebdis documentation.

Building Webdis with SSL support

Webdis needs libraries that provide TLS support to encrypt its connections to Redis:

  • On Alpine Linux, installopenssl-dev withapk-add openssl-dev.
  • On Ubuntu, installlibssl-dev withapt-get install libssl-dev.
  • On macOS with HomeBrew, install OpenSSL withbrew install openssl@1.1.

Then, build Webdis with SSL support enabled:

$ make SSL=1

Configuring Webdis with SSL

Once Redis is configured with SSL support (seethis guide for step-by-step instructions), you can configure Webdis to connect to Redis over encrypted connections.

Add a block towebdis.json under a key named"ssl" placed at the root level, containing the following object:

{"enabled":true,"ca_cert_bundle":"/path/to/ca.crt","path_to_certs":"/path/to/trusted/certs","client_cert":"/path/to/redis.crt","client_key":"/path/to/redis.key","redis_sni":"redis.mydomain.tld"}

This means that"ssl" should be at the same level as"redis_host","redis_port", etc.

Important: the presence of the"ssl" configuration block alone does not necessarily enable secure connections to Redis. The key"enabled" inside this blockmust also be set totrue, otherwise Webdis will keep using unencrypted connections.

Use the following table to match the Redis configuration keys to the fields under"ssl" inwebdis.json:

Redis fieldWebdis fieldPurpose
tls-cert-fileclient_certClient certificate
tls-key-fileclient_keyClient key
tls-ca-cert-fileca_cert_bundleCA certificate bundle

Two other keys have no equivalent inredis.conf:

  • path_to_certs is an optional directory path where trusted CA certificate files are stored in an OpenSSL-compatible format.
  • redis_sni is an optional Redis server name, used as a server name indication (SNI) TLS extension.

See also theHiredis docs andHiredis source code for more information.

Running Redis and Webdis with SSL in Docker Compose

For a full tutorial showing how to configure and run Redis and Webdis under Docker Compose with SSL connections between the two services, head to thedocs folder and openRunning Webdis & Redis in Docker Compose with SSL connections.

SSL troubleshooting

Follow this table to diagnose issues with SSL connections to Redis.

Error message or issueCauseSolution
Unexpected key or incorrect value inwebdis.json: 'ssl'Webdis is not compiled with SSL supportBuild webdis withmake SSL=1
Unexpected key or incorrect value under 'ssl'Invalid configurationOne or more keys in thessl object in was not recognized, make sure they are all valid
Failed to load client certificateInvalid client certificateVerify the file thatclient_cert points to
Failed to load private keyInvalid client keyVerify the file thatclient_key points to
Failed to load CA Certificate or CA PathInvalid CA certificate bundleVerify the file thatca_cert_bundle points to
All requests fail with HTTP 503, logs show "Error disconnecting: Connection reset by peer"SSL disabled in config but Webdis connected to an SSL portMake sureenabled is set totrue and that Webdis connects to the SSL port for Redis
Logs show "Server closed the connection" at start-upSSL connection failedThe client key and/or client certificate was missing. Make sure the configuration is valid.
No error but all requests hangWebdis connected to the non-SSL portMake sure Webdis is connecting to the port set undertls-port inredis.conf

Features

  • GET andPOST are supported, as well asPUT for file uploads (see example ofPUT usagehere).
  • JSON output by default, optional JSONP parameter (?jsonp=myFunction or?callback=myFunction).
  • Raw Redis 2.0 protocol output with.raw suffix.
  • MessagePack output with.msg suffix.
  • HTTP 1.1 pipelining (70,000 http requests per second on a desktop Linux machine.)
  • Multi-threaded server, configurable number of worker threads.
  • WebSocket support (Currently using the specification fromRFC 6455).
  • Connects to Redis using a TCP or UNIX socket.
  • Support forsecure connections to Redis (requiresRedis 6 or newer).
  • Restricted commands by IP range (CIDR subnet + mask) or HTTP Basic Auth, returning 403 errors.
  • Support for Redis authentication in the config file: setredis_auth to a single string to use a password value, or to an array of two strings to use username+password auth (new in Redis 6.0).
  • Environment variables can be used as values in the config file, starting with$ and in all caps (e.g.$REDIS_HOST).
  • Pub/Sub usingTransfer-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, or with?type=some/thing.
  • URL-encoded parameters for binary data or slashes and question marks. For instance,%2f is decoded as/ but not used as a command separator.
  • Logs, with a configurable verbosity.
  • Configurablefsync frequency for the log file:
    • Set"log_fsync": "auto" (default) to let the file system handle file persistence on its own.
    • Set"log_fsync": N whereN is a number to callfsync everyN milliseconds.
    • Set"log_fsync": "all" (very slow) to persist the log file to its storage device on each log message.
  • Cross-origin requests, usable with XMLHttpRequest2 (Cross-Origin Resource Sharing - CORS).
  • File upload withPUT.
  • With the JSON output, the return value of INFO is parsed and transformed into an object.
  • Optionally run as a daemon process: set"daemonize": true and"pidfile": "/var/run/webdis.pid" in webdis.json.
  • Default root object: Add"default_root": "/GET/index.html" in webdis.json to substitute the request to/ with a Redis request.
  • HTTP request limit withhttp_max_request_size (in bytes, set to 128 MB by default).
  • Database selection in the URL, using e.g./7/GET/key to run the command on DB 7.

Ideas, TODO…

  • Add better support for PUT, DELETE, HEAD, OPTIONS? How? For which commands?
    • This could be done using a “strict mode” with a table of commands and the verbs that can/must be used with each command. Strict mode would be optional, configurable. How would webdis know of new commands remains to be determined.
  • MULTI/EXEC/DISCARD/WATCH are disabled at the moment; find a way to use them.
  • 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 (maybe for some commands only?). What should the response be? 504 Gateway Timeout? 503 Service Unavailable?
  • Multi-server support, using consistent hashing.
  • SSL/TLS?
    • It makes more sense to terminate SSL with nginx used as a reverse-proxy.
  • SPDY?
    • SPDY is mostly useful for parallel fetches. Not sure if it would make sense for Webdis.
  • Send your ideas using the github tracker, on twitter@yowgi or by e-mail ton.favrefelix@gmail.com.

HTTP error codes

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

Command format

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

  • GET /COMMAND/arg0/.../argN.ext
  • POST / withCOMMAND/arg0/.../argN in the HTTP body.
  • PUT /COMMAND/arg0.../argN-1 withargN in the HTTP body (see section onfile uploads.)

.ext is an optional extension; it is not read as part of the last argument but only represents the output format. Several formats are available (see below).

Special characters:/ and. have special meanings,/ separates arguments and. changes the Content-Type. They can be replaced by%2f and%2e, respectively.

Redis authentication

Webdis can connect to a Redis server that requires credentials.For Redis versions before 6.0, provide the password as a single string inwebdis.json using the key"redis_auth". For example:

"redis_auth":"enter-password-here"

Redis 6.0 introduces a more granularaccess control system and switches from a single password to a pair of username and password. To use these two values with Webdis, set"redis_auth" to an array containing the two strings, e.g.

"redis_auth": ["my-username","my-password"]

This new authentication system is only supported in Webdis 0.1.13 and above.

ACL

Access control is configured inwebdis.json. Each configuration tries to match a client profile according to two criteria:

Each ACL contains two lists of commands,enabled anddisabled. 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. The special value "*" matches all commands.

Environment variables

Environment variables can be used inwebdis.json to read values from the environment instead of using constant values.For this, the value must be a string starting with a dollar symbol and written in all caps. For example, to make the redis host and port configurable via environment variables, use the following:

{"redis_host":"$REDIS_HOST","redis_port":"$REDIS_PORT",}

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$5hello// 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$3abc$3def// 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 unknowncommand'MAKE-ME-COFFEE'

Custom content-type

Several content-types are available:

  • .json forapplication/json (this is the default Content-Type).
  • .msg forapplication/x-msgpack. Seehttps://msgpack.org/ for the specs.
  • .txt fortext/plain
  • .html fortext/html
  • .xhtml forapplication/xhtml+xml
  • .xml fortext/xml
  • .png forimage/png
  • .jpg or.jpeg forimage/jpeg
  • Any other with the?type=anything/youwant query string.
  • Add a custom separator for list responses with?sep=, query string.
$ curl -v "http://127.0.0.1:7379/GET/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>$ curl -v "http://127.0.0.1:7379/GET/hello.txt"[...]< HTTP/1.1 200 OK< Content-Type: text/plain< Date: Mon, 03 Jan 2011 20:43:36 GMT< Content-Length: 137[...]$ curl -v "http://127.0.0.1:7379/GET/big-file?type=application/pdf"[...]< HTTP/1.1 200 OK< Content-Type: application/pdf< Date: Mon, 03 Jan 2011 20:45:12 GMT[...]

File upload

Webdis supports file upload using HTTP PUT. The command URI is slightly different, as the last argument is taken from the HTTP body.For example: instead of/SET/key/value, the URI becomes/SET/key and the value is the entirety of the body. This works for other commands such as LPUSH, etc.

Uploading a binary file to webdis:

$ file redis-logo.pngredis-logo.png: PNG image, 513 x 197, 8-bit/color RGBA, non-interlaced$ wc -c redis-logo.png16744 redis-logo.png$ curl -v --upload-file redis-logo.png http://127.0.0.1:7379/SET/logo[...]> PUT /SET/logo HTTP/1.1> User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15> Host: 127.0.0.1:7379> Accept: */*> Content-Length: 16744> Expect: 100-continue>< HTTP/1.1 100 Continue< HTTP/1.1 200 OK< Content-Type: application/json< ETag: "0db1124cf79ffeb80aff6d199d5822f8"< Date: Sun, 09 Jan 2011 16:48:19 GMT< Content-Length: 19<{"SET":[true,"OK"]}$ curl -vs http://127.0.0.1:7379/GET/logo.png -o out.png> GET /GET/logo.png HTTP/1.1> User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15> Host: 127.0.0.1:7379> Accept: */*>< HTTP/1.1 200 OK< Content-Type: image/png< ETag: "1991df597267d70bf9066a7d11969da0"< Date: Sun, 09 Jan 2011 16:50:51 GMT< Content-Length: 16744$ md5sum redis-logo.png out.png1991df597267d70bf9066a7d11969da0  redis-logo.png1991df597267d70bf9066a7d11969da0  out.png

The file was uploaded and re-downloaded properly: it has the same hash and the content-type was set properly thanks to the.png extension.

WebSockets

Webdis supports WebSocket clients implementingRFC 6455.

Important: WebSocket support is currentlydisabled by default. To enable WebSocket support, set the key named"websockets" to valuetrue inwebdis.json, e.g.

{"daemonize":false,"websockets":true,}

(start and end of file omitted).

WebSockets are supported with the following formats, selected by the connection URL:

  • JSON (on/ or/.json)
  • Raw Redis wire protocol (on/.raw)

Example:

functiontestJSON(){varjsonSocket=newWebSocket("ws://127.0.0.1:7379/.json");jsonSocket.onmessage=function(messageEvent){console.log("JSON received:",messageEvent.data);};jsonSocket.onopen=function(){console.log("JSON socket connected!");jsonSocket.send(JSON.stringify(["SET","hello","world"]));jsonSocket.send(JSON.stringify(["GET","hello"]));};}testJSON();

This produces the following output:

JSON socket connected!JSON received: {"SET":[true,"OK"]}JSON received: {"GET":"world"}

WebSockets HTML demo

The Webdis repository contains a demo web page with JavaScript code that can be used to test WebSocket support.

In a terminal, check out Webdis, build it, and configure it with WebSocket support:

$cd~/src/webdis$ make$ vim webdis.json# (edit the file to add "websockets": true)$ grep websockets webdis.json"websockets":true,$ ./webdis

Then go to thetests/ directory and openwebsocket.html with a web browser.

Pub/Sub with chunked transfer encoding

Webdis exposes Redis PUB/SUB channels to HTTP clients, forwarding messages in the channel as they are published by Redis. This is done using chunked transfer encoding.

Example using XMLHttpRequest:

varprevious_response_length=0xhr=newXMLHttpRequest()xhr.open("GET","http://127.0.0.1:7379/SUBSCRIBE/hello",true);xhr.onreadystatechange=checkData;xhr.send(null);functioncheckData(){if(xhr.readyState==3){response=xhr.responseText;chunk=response.slice(previous_response_length);previous_response_length=response.length;console.log(chunk);}};

Publish messages to redis to see output similar to the following:

{"SUBSCRIBE":["subscribe","hello",1]}{"SUBSCRIBE":["message","hello","some message"]}{"SUBSCRIBE":["message","hello","some other message"]}

About

A redis server with http interface

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors23


[8]ページ先頭

©2009-2025 Movatter.jp