[MEDIUM] http: add support for proxy authentication
We're already able to know if a request is a proxy request or a
normal one, and we have an option "http-use-proxy-header" which states
that proxy headers must be checked. So let's switch to use the proxy
authentication headers and responses when this option is set and we're
facing a proxy request. That allows haproxy to enforce auth in front
of a proxy.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 2ef3639..48c90c7 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -2691,6 +2691,11 @@
that this option can only be specified in a frontend and will affect the
request along its whole life.
+ Also, when this option is set, a request which requires authentication will
+ automatically switch to use proxy authentication headers if it is itself a
+ proxied request. That makes it possible to check or enforce authentication in
+ front of an existing proxy.
+
This option should normally never be used, except in front of a proxy.
See also : "option httpclose", "option forceclose" and "option
diff --git a/src/proto_http.c b/src/proto_http.c
index 4ac53b3..1b59c68 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -111,6 +111,15 @@
"\r\n"
"<html><body><h1>401 Unauthorized</h1>\nYou need a valid user and password to access this content.\n</body></html>\n";
+const char *HTTP_407_fmt =
+ "HTTP/1.0 407 Unauthorized\r\n"
+ "Cache-Control: no-cache\r\n"
+ "Connection: close\r\n"
+ "Content-Type: text/html\r\n"
+ "Proxy-Authenticate: Basic realm=\"%s\"\r\n"
+ "\r\n"
+ "<html><body><h1>401 Unauthorized</h1>\nYou need a valid user and password to access this content.\n</body></html>\n";
+
const int http_err_codes[HTTP_ERR_SIZE] = {
[HTTP_ERR_400] = 400,
@@ -1507,7 +1516,16 @@
txn->auth.method = HTTP_AUTH_WRONG;
ctx.idx = 0;
- if (!http_find_header("Authorization", txn->req.sol, &txn->hdr_idx, &ctx))
+
+ if (txn->flags & TX_USE_PX_CONN) {
+ h = "Proxy-Authorization";
+ len = strlen(h);
+ } else {
+ h = "Authorization";
+ len = strlen(h);
+ }
+
+ if (!http_find_header2(h, len, txn->req.sol, &txn->hdr_idx, &ctx))
return 0;
h = ctx.line + ctx.val;
@@ -2969,7 +2987,7 @@
if (!realm)
realm = do_stats?STATS_DEFAULT_REALM:px->id;
- sprintf(trash, HTTP_401_fmt, realm);
+ sprintf(trash, (txn->flags & TX_USE_PX_CONN) ? HTTP_407_fmt : HTTP_401_fmt, realm);
chunk_initlen(&msg, trash, sizeof(trash), strlen(trash));
txn->status = 401;
stream_int_retnclose(req->prod, &msg);