implement proxy forwarded/x-forwarded headers default tip

Thu, 12 Mar 2026 19:14:35 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 12 Mar 2026 19:14:35 +0100
changeset 727
4be837389b9e
parent 726
5ad3bda4aca1

implement proxy forwarded/x-forwarded headers

src/server/safs/proxy.c file | annotate | diff | comparison | revisions
--- a/src/server/safs/proxy.c	Sat Mar 07 23:35:16 2026 +0100
+++ b/src/server/safs/proxy.c	Thu Mar 12 19:14:35 2026 +0100
@@ -318,6 +318,22 @@
     const char *method = pblock_findkeyval(pb_key_method, rq->reqpb);
     const char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
     const char *query = pblock_findkeyval(pb_key_query, rq->reqpb);
+    const char *forward = pblock_findval("forwarded", rq->reqpb);
+    
+    char *host = pblock_findval("host", rq->headers);
+    
+    int forwarded_headers = 0;
+    if(forward) {
+        if(!strcmp(forward, "true")) {
+            forwarded_headers = 1;
+        } else if(!strcmp(forward, "forwarded")) {
+            forwarded_headers = 1;
+        } else if(!strcmp(forward, "rfc7239")) {
+            forwarded_headers = 1;
+        } else if(!strcmp(forward, "xforwarded")) {
+            forwarded_headers = 2;
+        }
+    }
     
     //log_ereport(LOG_INFORM, "reverse-proxy: %s %s", method, uri);
     
@@ -491,6 +507,25 @@
         return REQ_ABORTED;
     }
     
+    char *ip = pblock_findkeyval(pb_key_ip, sn->client);
+    if(forwarded_headers == 1) {
+        char buf[512];
+        int n = snprintf(buf, 512, "host=\"%s\";for=\"%s\";proto=%s", host, ip, "https"); // TODO: proto
+        if(n > 511 || http_client_add_request_header_copy(client, cx_str("forwarded"), cx_str(buf))) {
+            http_client_free(client);
+            return REQ_ABORTED;
+        }
+    } else if(forwarded_headers == 2) {
+        if(http_client_add_request_header(client, cx_mutstr("x-forwarded-for"), cx_mutstr(ip))) {
+            http_client_free(client);
+            return REQ_ABORTED;
+        }
+        if(http_client_add_request_header(client, cx_mutstr("x-forwarded-host"), cx_mutstr(host))) {
+            http_client_free(client);
+            return REQ_ABORTED;
+        }
+    }
+    
     // add request headers to the client
     CxIterator i = pblock_iterator(rq->headers);
     cx_foreach(pb_entry*, entry, i) {

mercurial