Skip to content

Commit

Permalink
proxy: move handleHttp function to a dedicated file http.go
Browse files Browse the repository at this point in the history
This is for parity with HTTPS and the handleHttps function.
  • Loading branch information
mmatczuk committed Nov 9, 2022
1 parent acbd370 commit 4cfa244
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 79 deletions.
85 changes: 85 additions & 0 deletions http.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package goproxy

import (
"io"
"net/http"
"sync/atomic"
)

func (proxy *ProxyHttpServer) handleHttp(w http.ResponseWriter, r *http.Request) {
ctx := &ProxyCtx{Req: r, Session: atomic.AddInt64(&proxy.sess, 1), Proxy: proxy}

var err error
ctx.Logf("Got request %v %v %v %v", r.URL.Path, r.Host, r.Method, r.URL.String())
if !r.URL.IsAbs() {
proxy.NonproxyHandler.ServeHTTP(w, r)
return
}
r, resp := proxy.filterRequest(r, ctx)

if resp == nil {
if isWebSocketRequest(r) {
ctx.Logf("Request looks like websocket upgrade.")
proxy.serveWebsocket(ctx, w, r)
}

if !proxy.KeepHeader {
removeProxyHeaders(ctx, r)
}
resp, err = ctx.RoundTrip(r)
if err != nil {
ctx.Error = err
resp = proxy.filterResponse(nil, ctx)

}
if resp != nil {
ctx.Logf("Received response %v", resp.Status)
}
}

var origBody io.ReadCloser

if resp != nil {
origBody = resp.Body
defer origBody.Close()
}

resp = proxy.filterResponse(resp, ctx)

if resp == nil {
var errorString string
if ctx.Error != nil {
errorString = "error read response " + r.URL.Host + " : " + ctx.Error.Error()
ctx.Logf(errorString)
http.Error(w, ctx.Error.Error(), 500)
} else {
errorString = "error read response " + r.URL.Host
ctx.Logf(errorString)
http.Error(w, errorString, 500)
}
return
}
ctx.Logf("Copying response to client %v [%d]", resp.Status, resp.StatusCode)
// http.ResponseWriter will take care of filling the correct response length
// Setting it now, might impose wrong value, contradicting the actual new
// body the user returned.
// We keep the original body to remove the header only if things changed.
// This will prevent problems with HEAD requests where there's no body, yet,
// the Content-Length header should be set.
if origBody != resp.Body {
resp.Header.Del("Content-Length")
}
copyHeaders(w.Header(), resp.Header, proxy.KeepDestinationHeaders)
w.WriteHeader(resp.StatusCode)
var copyWriter io.Writer = w
if w.Header().Get("content-type") == "text/event-stream" {
// server-side events, flush the buffered data to the client.
copyWriter = &flushWriter{w: w}
}

nr, err := io.Copy(copyWriter, resp.Body)
if err := resp.Body.Close(); err != nil {
ctx.Warnf("Can't close response body %v", err)
}
ctx.Logf("Copied %v bytes to client error=%v", nr, err)
}
79 changes: 0 additions & 79 deletions proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"net/http"
"os"
"regexp"
"sync/atomic"
)

// The basic proxy type. Implements http.Handler.
Expand Down Expand Up @@ -132,84 +131,6 @@ func (proxy *ProxyHttpServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
}
}

func (proxy *ProxyHttpServer) handleHttp(w http.ResponseWriter, r *http.Request) {
ctx := &ProxyCtx{Req: r, Session: atomic.AddInt64(&proxy.sess, 1), Proxy: proxy}

var err error
ctx.Logf("Got request %v %v %v %v", r.URL.Path, r.Host, r.Method, r.URL.String())
if !r.URL.IsAbs() {
proxy.NonproxyHandler.ServeHTTP(w, r)
return
}
r, resp := proxy.filterRequest(r, ctx)

if resp == nil {
if isWebSocketRequest(r) {
ctx.Logf("Request looks like websocket upgrade.")
proxy.serveWebsocket(ctx, w, r)
}

if !proxy.KeepHeader {
removeProxyHeaders(ctx, r)
}
resp, err = ctx.RoundTrip(r)
if err != nil {
ctx.Error = err
resp = proxy.filterResponse(nil, ctx)

}
if resp != nil {
ctx.Logf("Received response %v", resp.Status)
}
}

var origBody io.ReadCloser

if resp != nil {
origBody = resp.Body
defer origBody.Close()
}

resp = proxy.filterResponse(resp, ctx)

if resp == nil {
var errorString string
if ctx.Error != nil {
errorString = "error read response " + r.URL.Host + " : " + ctx.Error.Error()
ctx.Logf(errorString)
http.Error(w, ctx.Error.Error(), 500)
} else {
errorString = "error read response " + r.URL.Host
ctx.Logf(errorString)
http.Error(w, errorString, 500)
}
return
}
ctx.Logf("Copying response to client %v [%d]", resp.Status, resp.StatusCode)
// http.ResponseWriter will take care of filling the correct response length
// Setting it now, might impose wrong value, contradicting the actual new
// body the user returned.
// We keep the original body to remove the header only if things changed.
// This will prevent problems with HEAD requests where there's no body, yet,
// the Content-Length header should be set.
if origBody != resp.Body {
resp.Header.Del("Content-Length")
}
copyHeaders(w.Header(), resp.Header, proxy.KeepDestinationHeaders)
w.WriteHeader(resp.StatusCode)
var copyWriter io.Writer = w
if w.Header().Get("content-type") == "text/event-stream" {
// server-side events, flush the buffered data to the client.
copyWriter = &flushWriter{w: w}
}

nr, err := io.Copy(copyWriter, resp.Body)
if err := resp.Body.Close(); err != nil {
ctx.Warnf("Can't close response body %v", err)
}
ctx.Logf("Copied %v bytes to client error=%v", nr, err)
}

// NewProxyHttpServer creates and returns a proxy server, logging to stderr by default
func NewProxyHttpServer() *ProxyHttpServer {
proxy := ProxyHttpServer{
Expand Down

0 comments on commit 4cfa244

Please sign in to comment.