[mod] follow HTTP redirect (only GET HTTP method)

close #48

git-svn-id: file:///srv/svn/repo/yukari/trunk@96 f3bd38d9-da89-464d-a02a-eb04e43141b5
This commit is contained in:
alex 2019-08-11 08:34:33 +00:00
parent dec4f8de05
commit 25f07b21e8

View File

@ -36,6 +36,8 @@ const (
const VERSION = "v0.2.0"
const MAX_REDIRECT_COUNT = 5
var CLIENT *fasthttp.Client = &fasthttp.Client{
MaxResponseBodySize: 10 * 1024 * 1024, // 10M
}
@ -287,7 +289,11 @@ func (p *Proxy) RequestHandler(ctx *fasthttp.RequestCtx) {
}
}
parsedURI, err := url.Parse(string(requestURI))
p.ProcessUri(ctx, string(requestURI), 0)
}
func (p *Proxy) ProcessUri(ctx *fasthttp.RequestCtx, requestURI string, redirectCount int) {
parsedURI, err := url.Parse(requestURI)
if err != nil {
// HTTP status code 500 : Internal Server Error
@ -338,16 +344,27 @@ func (p *Proxy) RequestHandler(ctx *fasthttp.RequestCtx) {
case 301, 302, 303, 307, 308:
loc := resp.Header.Peek("Location")
if loc != nil {
log.Println("redirect to", string(loc))
if ctx.IsGet() {
// GET method: Morty follows the redirect
if redirectCount < MAX_REDIRECT_COUNT {
p.ProcessUri(ctx, string(loc), redirectCount+1)
} else {
p.serveMainPage(ctx, 310, errors.New("Too many redirects"))
}
return
} else {
// Other HTTP methods: Morty does NOT follow the redirect
rc := &RequestConfig{Key: p.Key, BaseURL: parsedURI}
url, err := rc.ProxifyURI(loc)
if err == nil {
ctx.SetStatusCode(resp.StatusCode())
ctx.Response.Header.Add("Location", url)
log.Println("redirect to", string(loc))
return
}
}
}
}
error_message := fmt.Sprintf("invalid response: %d (%s)", resp.StatusCode(), requestURIStr)
p.serveMainPage(ctx, resp.StatusCode(), errors.New(error_message))
return