Description

Hi guys, i'm try to make reverse proxy server with gin. Everything work as i expect except when i try to response.Request.Body, it read blank byte array.

How to reproduce

package main

import (
    "io/ioutil"
    "net/http"
    "net/http/httputil"
    "net/url"

    "github.com/gin-gonic/gin"
)

func proxy(c *gin.Context) {

    remote, err := url.Parse("https://google.com")
    if err != nil {
        panic(err)
    }

    proxy := httputil.NewSingleHostReverseProxy(remote)
    proxy.ModifyResponse = func(resp *http.Response) error {
        if resp.Request.Body != nil {
            req := *resp.Request
            b, err := ioutil.ReadAll(req.Body)
            if err != nil {
                c.AbortWithError(http.StatusInternalServerError, err)
            }

            println(string(b)) // this is blank what i expect is request body
        }

        return nil
    }

    proxy.ServeHTTP(c.Writer, c.Request)
}

func main() {
    r := gin.Default()

    r.Any("/graphql", proxy)
    r.Run()
}

Expectations

$ curl -d '{"key1":"value1", "key2":"value2"}' -H "Content-Type: application/json" -X POST http://localhost:3000/graphql
{"key1":"value1", "key2":"value2"}

Actual result

$ curl -d '{"key1":"value1", "key2":"value2"}' -H "Content-Type: application/json" -X POST http://localhost:3000/graphql
blank result

Environment

  • go version: 1.19
  • gin version (or commit ref):1.8.1
  • operating system:macos

Comment From: webstradev

What is it you are actually trying to do with the body and is there a specific reason you are doing it in the ModifyResponse function. I'm not sure if ModifyResponse is the most suitable place to do anything with the request body. Have you considered using middleware on the proxy to modify the request body.