0
votes

i am trying to cache POST request by using Varnish cache. I am using vcl file as

vcl 4.0;

import std;
import bodyaccess;

backend default {
  .host = "**.***.**.***";          
  .port = "**";     
}

sub vcl_recv {
    unset req.http.x-cache; 
    unset req.http.X-Body-Len;

    if (req.method == "POST") {
        std.log("Will cache POST for: " + req.http.host + req.url);
        std.cache_req_body(3000KB);
        set req.http.X-Body-Len = bodyaccess.len_req_body();
        if (req.http.X-Body-Len == "-1") {
            return(synth(400, "The request body size exceeds the limit"));
        }
        return (hash);
    }
}

sub vcl_hash {
    # To cache POST and PUT requests
    if (req.http.X-Body-Len) {
        bodyaccess.hash_req_body();
    } else {
        hash_data("");
    }
}

sub vcl_backend_fetch {
    if (bereq.http.X-Body-Len) {
        set bereq.method = "POST";
    }
}

sub vcl_backend_response {
  set beresp.ttl = 86400s;
  unset beresp.http.Cache-Control;
  set beresp.http.Cache-Control = "public, max-age=86400";
}

sub vcl_hit {
    set req.http.x-cache = "hit";
}

sub vcl_miss {
    set req.http.x-cache = "miss";
}

sub vcl_pass {
    set req.http.x-cache = "pass";
}

sub vcl_pipe {
    set req.http.x-cache = "pipe uncacheable";
}

sub vcl_synth {
    set resp.http.x-cache = "synth synth";
}

sub vcl_deliver {
    if (obj.uncacheable) {
        set req.http.x-cache = req.http.x-cache + " uncacheable" ;
    } else {
        set req.http.x-cache = req.http.x-cache + " cached" ;
    }
    set resp.http.x-cache = req.http.x-cache;
}

When i am doing post request directly it is working fine but as soon as I go through Cache Server, backend Server is returning "HTTP Error 411. The request must be chunked or have a content length." On debugging furthet

What I found from varnishlog is

         3 BereqMethod    b POST
         3 BereqURL       b /someurl
         3 BereqProtocol  b HTTP/1.1
         3 BereqHeader    b Content-Type: application/json
         3 BereqHeader    b Accept-Language: en-US
         3 BereqHeader    b User-Agent: PostmanRuntime/7.24.0
         3 BereqHeader    b Accept: */*
         3 BereqHeader    b Postman-Token: 6fe71b81-841d-400f-957a-45b6518bfca6
         3 BereqHeader    b Host: *.*.*.*
         3 BereqHeader    b X-Forwarded-For: *.*.*.*
         3 BereqHeader    b X-Body-Len: 161
         3 BereqHeader    b Accept-Encoding: gzip
         3 BereqHeader    b x-cache: miss
         3 BereqMethod    b GET
         3 BereqHeader    b X-Varnish: 3

Varnish is not sending Content-Length where backend server needs it

How can I set this content-length

1

1 Answers

0
votes

You can set it as any other header, i.e. in vcl_recv:

set req.http.Content-Length = "value"