retrieve gerrit project name from uri
diff --git a/src/backend.c b/src/backend.c
index c80dc0f..9fe9c62 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -210,6 +210,12 @@
 	int c;
 	int slashes = 0;
 	const char *start, *end;
+	int depth = 1;
+	int orig_uri_len = uri_len;
+	const char *orig_start;
+	const char *p, *params;
+	int buflen = 0;
+	char *buf;
 
 	if (px->lbprm.tot_weight == 0)
 		return NULL;
@@ -221,20 +227,116 @@
 	if (px->lbprm.arg_opt2) // "len"
 		uri_len = MIN(uri_len, px->lbprm.arg_opt2);
 
-	start = end = uri;
-	while (uri_len--) {
-		c = *end;
-		if (c == '/') {
-			slashes++;
-			if (slashes == px->lbprm.arg_opt3) /* depth+1 */
+        orig_start = start = end = uri;
+        if (px->lbprm.arg_opt4 == 1) {
+                p = memchr(uri, '?', uri_len);
+                params = p;
+                if (p) {
+                        p++;
+                        uri_len = p - uri;
+                        params = p;
+                        if (p[7] == '=') {
+                                if (memcmp(p, "service", 7) == 0) {
+                                        p += 8;
+                                        depth = 2;
+                                }
+                        }
+                }
+
+                end = uri + uri_len - 1;
+                while (uri_len--) {
+                        c = *end;
+                        if (c == '/') {
+                                if (p == NULL)
+                                        p = end + 1;
+                                slashes++;
+                                if (slashes == depth)
+                                        break;
+                        }
+                        end--;
+                }
+                if (p != NULL && (!strncmp(p, "git-receive-pack", 16) || !strncmp(p, "git-upload-pack", 15))) {
+                        // we have git request here
+                        // get rid of redundant '/'
+                        while ((end - start) > 1 && *(start+1) == '/')
+                                start++;
+                        while ((end - start) > 1 && *(end-1) == '/')
+                                end--;
+                        // get rid of trailing ".git"
+                        if ((end - start) > 4 && strncmp(end-4, ".git", 4) == 0)
+                                end -= 4;
+
+                        hash = gen_hash(px, start, (end - start));
+                } else {
+                        if (px->lbprm.arg_opt3 > 0){
+                                // reset state
+				uri_len = orig_uri_len;
+                                if (params != NULL)
+                                        uri_len = params - uri;
+                                depth = px->lbprm.arg_opt3;
+                                slashes = 0;
+                                buf = (char *)malloc(uri_len);
+                                orig_start = start = end = uri;
+                                while (uri_len--) {
+                                        c = *end;
+                                        if (c == '/') {
+                                                if (slashes == 1 && end - start == 2) {
+                                                        depth += 1;
+                                                        orig_start = start = end;
+                                                }
+                                                slashes++;
+                                                if (slashes == depth - 1) {
+                                                        if (memcmp(start, "/changes", end - start) != 0 && memcmp(start, "/projects", end - start) != 0)
+                                                                break;
+                                                        start = end;
+                                                        p = start;
+                                                }
+                                                else if (slashes == depth) { /* depth+1 */
+                                                        memcpy(buf + buflen, p, end - p);
+                                                        buflen += (end - p);
+                                                        break;
+                                                }
+                                        }
+                                        else if (c == '%') {
+                                                if (orig_start != start && uri_len > 2 && (memcmp(end, "%2F", 3) == 0 || memcmp(end, "%2f", 3) == 0)) {
+                                                        memcpy(buf + buflen, p, end - p);
+                                                        buflen += (end - p) + 1;
+                                                        buf[buflen - 1] = '/';
+                                                        p = end + 3;
+                                                }
+                                        }
+                                        else if (c == '~') {
+                                                if (orig_start != start) {
+                                                  memcpy(buf + buflen, p, end - p);
+                                                  buflen += (end - p);
+                                                  break;
+                                                }
+                                        }
+                                        end++;
+                                }
+                        }
+                        if (buflen > 0)
+                                hash = gen_hash(px, buf, buflen);
+                        if (buf != NULL)
+                                free(buf);
+                        if (buflen <= 0) /*let's fallback to round robin */
+                                return NULL;
+                }
+        } else {
+		while (uri_len--) {
+			c = *end;
+			if (c == '/') {
+				slashes++;
+				if (slashes == px->lbprm.arg_opt3) /* depth+1 */
+					break;
+			}
+			else if (c == '?' && !px->lbprm.arg_opt1) // "whole"
 				break;
+			end++;
 		}
-		else if (c == '?' && !px->lbprm.arg_opt1) // "whole"
-			break;
-		end++;
-	}
 
-	hash = gen_hash(px, start, (end - start));
+		hash = gen_hash(px, start, (end - start));
+	}
 
 	if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL)
 		hash = full_hash(hash);
@@ -1962,6 +2064,7 @@
 		curproxy->lbprm.arg_opt1 = 0; // "whole"
 		curproxy->lbprm.arg_opt2 = 0; // "len"
 		curproxy->lbprm.arg_opt3 = 0; // "depth"
+		curproxy->lbprm.arg_opt4 = 0; // "gerrit"
 
 		while (*args[arg]) {
 			if (!strcmp(args[arg], "len")) {
@@ -1987,6 +2090,16 @@
 				curproxy->lbprm.arg_opt1 = 1;
 				arg += 1;
 			}
+			else if (!strcmp(args[arg], "gerrit")) {
+                                if (!*args[arg+1] || (atoi(args[arg+1]) < 0)) {
+                                        memprintf(err, "%s : '%s' expects a non negative integer  (got '%s').", args[0], args[arg], args[arg+1]);
+                                        return -1;
+                                }
+                                curproxy->lbprm.arg_opt4 = 1;
+                                // 0 means whole uri
+                                curproxy->lbprm.arg_opt3 = atoi(args[arg+1]);
+                                arg += 2;
+			}
 			else {
 				memprintf(err, "%s only accepts parameters 'len', 'depth', and 'whole' (got '%s').", args[0], args[arg]);
 				return -1;