add support http forward

This commit is contained in:
fan 2019-05-05 19:04:54 +08:00
parent 202f8fc58a
commit 94dee576bf
2 changed files with 57 additions and 2 deletions

View File

@ -13,6 +13,7 @@ import (
"mime/multipart" "mime/multipart"
"net" "net"
"net/http" "net/http"
"net/http/httputil"
"net/url" "net/url"
"os" "os"
"strings" "strings"
@ -1026,3 +1027,23 @@ func (c *Context) Value(key interface{}) interface{} {
} }
return nil return nil
} }
// ReverseProxy is an HTTP Handler that takes an incoming request and
// sends it to another server, proxying the response back to the client.
// You can use it to forward.
func (c *Context) Forward(target string) {
host := c.Request.Host
scheme := c.Request.URL.Scheme
if scheme == "" {
scheme = "http"
}
var proxy = httputil.ReverseProxy{
Director: func(req *http.Request) {
req.URL.Scheme = scheme
req.URL.Host = host
req.Host = host
},
}
c.Request.URL.Path = target
proxy.ServeHTTP(c.Writer, c.Request)
}

View File

@ -10,21 +10,22 @@ import (
"fmt" "fmt"
"html/template" "html/template"
"io" "io"
"io/ioutil"
"mime/multipart" "mime/multipart"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"reflect" "reflect"
"strings" "strings"
"sync"
"testing" "testing"
"time" "time"
"github.com/gin-contrib/sse" "github.com/gin-contrib/sse"
"github.com/gin-gonic/gin/binding" "github.com/gin-gonic/gin/binding"
testdata "github.com/gin-gonic/gin/testdata/protoexample"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"golang.org/x/net/context" "golang.org/x/net/context"
testdata "github.com/gin-gonic/gin/testdata/protoexample"
) )
var _ context.Context = &Context{} var _ context.Context = &Context{}
@ -1812,3 +1813,36 @@ func TestContextResetInHandler(t *testing.T) {
c.Next() c.Next()
}) })
} }
func TestContext_Forward(t *testing.T) {
g := sync.WaitGroup{}
g.Add(1)
go func(g *sync.WaitGroup) {
g.Done()
e := Default()
e.GET("/test", func(c *Context) {
c.Forward("/test2")
})
e.GET("/test2", func(c *Context) {
p := c.Query("p")
c.String(http.StatusOK, p)
})
e.Run(":9998")
}(&g)
g.Wait()
p := "test"
resp, err := http.Get("http://127.0.0.1:9998/test?p=" + p)
assert.NoError(t, err)
defer resp.Body.Close()
bytes, err := ioutil.ReadAll(resp.Body)
assert.NoError(t, err)
assert.Equal(t, p, string(bytes))
}