Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sending a pull request #3

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions examples/arrays.vcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#
# A trivial example to demonstrate how to use this vmod
#

import redis;

backend be1 {
.host = "192.168.0.1";
.port = "80";
}

backend be2 {
.host = "192.168.0.1";
.port = "80";
}

#sub vcl_init {
#
# By default, the redis module will attempt to connect to a Redis server
# at 127.0.0.1:6379 with a connect timeout of 200 milliseconds.
#
# The function redis.init_redis(host, port, timeout_ms) may be used to
# connect to an alternate Redis server or use a different connect timeout.
#
# redis.init_redis("localhost", 6379, 200); /* default values */
#}

sub vcl_recv {
#
# redis.call is a function that sends the command to redis and return the
# return value as a string.
#
# As an example I have a hash on redis that permits me control a domain's redirect:
#
# redis-cli> add vrnsh mydomain.com
# redis-cli> hmset vrnsh:mydomain.com 'type' 'r' 'to' 'anotherdomain.com' 'code' '301'
#
# And I have another domain appointment to a backend server:
#
# redis-cli> sadd vrnsh mydomaintwo.com
# redis-cli> hmset vrnsh:mydomaintwo.com 'type' 'd' 'backend' 'be2'
#
# So, now I can read the request and check on redis if it's exists.
# If the response is true, the string returned would be something
# like this:
#
# REDIRECT
#
# r:anotherdomain.com:301
#
# DOMAIN
#
# d:be2
#
# The keys set on the array will be disconsidered and the values
# will be concatenated using ":" as wildcard to make the correct separation.
#
set req.http.redis_key = redis.call("HGETALL vrnsh:" + req.http.host);

if( req.http.redis_key ) {
# Read type param
set req.http.htype = regsub(req.http.redis_key, "^(r|d):(.*)", "\1");

# Read the domain backend from redis
if( req.http.htype == "d" ) {
# This regex is the number of parameters that you have returned.
# If you have more or less parameters, please adapt this.
# Don't forget to respect the correct parameters' sequences.
set req.http.hbackend = regsub(req.http.redis_key, "(.*):(.*)", "\2");

if( req.http.hbackend == "be1" ) {
set req.backend = be11;
} else if( req.http.hbackend == "be2" ) {
set req.backend = be2;
}
}

# Read and set a redirect from redis
if( req.http.htype == "r" ) {
set req.http.Location = regsub(req.http.redis_key,"(.*):(.*):(.*)", "\2");
set req.http.herror = regsub(req.http.redis_key,"(.*):(.*):(.*)", "\3");

if( req.http.herror == "302" ) {
error 302 req.http.Location;
} else if( req.http.herror == "301" ) {
error 301 req.http.Location;
} else {
error 705 req.http.Location;
}
}
# If not found, raise the correct error
} else {
error 404
}
}
28 changes: 27 additions & 1 deletion src/vmod_redis.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,32 @@ vmod_send(struct sess *sp, struct vmod_priv *priv, const char *command)
}
}

const char *
arr_to_str(redisReply *reply)
{
int i = 0;
int len = 0;
const char *ret = NULL;
char *digits;

digits = malloc(reply->elements*sizeof(int));

for(i;i<reply->elements;i++) {
if( i%2 != 0 ) {
strcat(digits,reply->element[i]->str);
strcat(digits,":");
}
}

len = strlen(digits);
digits[len-1] = '\0';

ret = strdup(digits);
free(digits);

return ret;
}

const char *
vmod_call(struct sess *sp, struct vmod_priv *priv, const char *command)
{
Expand Down Expand Up @@ -183,7 +209,7 @@ vmod_call(struct sess *sp, struct vmod_priv *priv, const char *command)
ret = strdup(reply->str);
break;
case REDIS_REPLY_ARRAY:
ret = strdup("array");
ret = arr_to_str(reply);
break;
default:
ret = strdup("unexpected");
Expand Down