Skip to content

Commit

Permalink
Merge pull request #2 from josephcopenhaver/jpcope/develop
Browse files Browse the repository at this point in the history
support response buffering
  • Loading branch information
josephcopenhaver authored May 26, 2021
2 parents b6e7b19 + 6a5f7c4 commit ececbcd
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 9 deletions.
2 changes: 1 addition & 1 deletion cmd/autocertproxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func main() {
)
}

ctx := proxy.RootContext()
ctx, _ := proxy.RootContext()

if err := p.ListenAndServe(ctx); err != nil {
os.Exit(1)
Expand Down
1 change: 1 addition & 0 deletions internal/proxy/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type Config struct {
DstHost string `json:"DST_HOST" envconfig:"DST_HOST" default:"127.0.0.1"`
DstHostHeader string `json:"DST_HOST_HEADER" envconfig:"DST_HOST_HEADER" default:""`
DstPort int `json:"DST_PORT" envconfig:"DST_PORT" default:"8080"`
ResponseBufferEnabled bool `json:"RESPONSE_BUFFER_ENABLED" envconfig:"RESPONSE_BUFFER_ENABLED" default:"false"`
AdminEmail string `json:"ADMIN_EMAIL" envconfig:"ADMIN_EMAIL" default:""`
AutocertCacheDir string `json:"AUTOCERT_CACHE_DIR" envconfig:"AUTOCERT_CACHE_DIR" default:"./.autocert"`
Authorization string `json:"AUTHORIZATION" default:""`
Expand Down
20 changes: 14 additions & 6 deletions internal/proxy/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,26 @@ import (

// RootContext returns a context that is canceled when the
// system process receives an interrupt, sigint, or sigterm
func RootContext() context.Context {
//
// Also returns a function that can be used to cancel the context.
func RootContext() (context.Context, func()) {

ctx, cancel := context.WithCancel(context.Background())

done := make(chan os.Signal, 1)
procDone := make(chan os.Signal, 1)

signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
signal.Notify(procDone, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)

go func() {
<-done
cancel()
defer cancel()

done := ctx.Done()

select {
case <-procDone:
case <-done:
}
}()

return ctx
return ctx, cancel
}
39 changes: 37 additions & 2 deletions internal/proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package proxy

import (
"context"
"io"
"net"
"net/http"
"net/http/httptest"
"net/http/httputil"
"net/url"
"os"
Expand Down Expand Up @@ -227,7 +229,40 @@ func (p *proxy) ListenAndServe(ctx context.Context) error {
})
}

if p.cfg.Authorization != "" {
if cfg.ResponseBufferEnabled {
prevHandler := handler

handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

// read response body till end
var resp *http.Response
{
rec := httptest.NewRecorder()

prevHandler.ServeHTTP(rec, r)

resp = rec.Result()
}

// send response headers
{
h := w.Header()
for k, values := range resp.Header {
for _, v := range values {
h.Add(k, v)
}
}
}

w.WriteHeader(resp.StatusCode)

// send response body
_, err := io.Copy(w, resp.Body)
_ = err // intentionally ignoring error, upstream or downstream must have had an issue
})
}

if cfg.Authorization != "" {
prevHandler := handler

handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand All @@ -236,7 +271,7 @@ func (p *proxy) ListenAndServe(ctx context.Context) error {
{
user, pass, ok := r.BasicAuth()

if !ok || user+":"+pass != p.cfg.Authorization {
if !ok || user+":"+pass != cfg.Authorization {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
Expand Down

0 comments on commit ececbcd

Please sign in to comment.