Skip to content

Instantly share code, notes, and snippets.

@ejlp12
Last active February 10, 2024 11:03
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save ejlp12/b3949bb40e748ae8367e17c193fa9602 to your computer and use it in GitHub Desktop.
Save ejlp12/b3949bb40e748ae8367e17c193fa9602 to your computer and use it in GitHub Desktop.
nginx, openresty, transform/modify response body, header_filter_by_lua
http { 
    proxy_cache_path /tmp/cache levels=1:2 keys_zone=cache:60m max_size=1G; 
    server { 
      listen 8080; 

      location /replace-body { 
        proxy_pass http://127.0.0.1:$server_port/; 

        proxy_cache      cache; 
        proxy_cache_valid  200 30s; 

        # Reset the response's content_length, so that Lua can generate a 
        # body with a different length. 
        header_filter_by_lua '
            ngx.header.content_length = nil
        '; 

        body_filter_by_lua ' 
          local ctx = ngx.ctx 
          if ctx.buffers == nil then 
            ctx.buffers = {} 
            ctx.nbuffers = 0 
          end 

          local data = ngx.arg[1] 
          local eof = ngx.arg[2] 
          local next_idx = ctx.nbuffers + 1 

          if not eof then 
            if data then 
              ctx.buffers[next_idx] = data 
              ctx.nbuffers = next_idx 
              -- Send nothing to the client yet. 
              ngx.arg[1] = nil 
            end 
            return 
          elseif data then 
            ctx.buffers[next_idx] = data 
            ctx.nbuffers = next_idx 
          end 

          -- Yes, we have read the full body. 
          -- Make sure it is stored in our buffer. 
          assert(ctx.buffers) 
          assert(ctx.nbuffers ~= 0, "buffer must not be empty") 

          -- And send a new body 
          ngx.arg[1] = "Cool... " .. table.concat(ngx.ctx.buffers) 
        '; 
      } 
    } 
  } 

To try it out:

    $ curl localhost:8080/replace-body 
    Cool... <html><head><title>It works!</title></head><body>It 
works!</body></html> 

    $ curl localhost:8080/replace-body 
    Cool... <html><head><title>It works!</title></head><body>It 
works!</body></html> 

    $ curl localhost:8080/replace-body 
    Cool... <html><head><title>It works!</title></head><body>It 
works!</body></html> 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment