Skip to content

Commit

Permalink
Copy request body
Browse files Browse the repository at this point in the history
  • Loading branch information
nstogner committed Jan 18, 2024
1 parent 2ab82e0 commit 363aaa0
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 29 deletions.
7 changes: 6 additions & 1 deletion hack/failserver/main.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package main

import "net/http"
import (
"io"
"net/http"
"os"
)

func main() {
http.ListenAndServe(":8081", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
io.Copy(os.Stdout, r.Body)
w.WriteHeader(http.StatusServiceUnavailable)
w.Write([]byte("unavailable\n"))
}))
Expand Down
69 changes: 42 additions & 27 deletions hack/retryproxy/main.go
Original file line number Diff line number Diff line change
@@ -1,48 +1,63 @@
package main

import (
"bytes"
"errors"
"io"
"log"
"net/http"
"net/http/httputil"
"net/url"
)

func main() {
// go run ./hack/failserver
u1, err := url.Parse("http://localhost:8081")
if err != nil {
panic(err)
}
p1 := httputil.NewSingleHostReverseProxy(u1)
http.ListenAndServe(":8080", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
panic(err)
}
r.Body.Close()

// go run ./hack/successserver
u2, err := url.Parse("http://localhost:8082")
if err != nil {
panic(err)
}
p2 := httputil.NewSingleHostReverseProxy(u2)
// go run ./hack/failserver
first := newReverseProxy("http://localhost:8081")

p1.ModifyResponse = func(r *http.Response) error {
if r.StatusCode == http.StatusServiceUnavailable {
// Returning an error will trigger the ErrorHandler.
return errRetry
first.ModifyResponse = func(r *http.Response) error {
if r.StatusCode == http.StatusServiceUnavailable {
// Returning an error will trigger the ErrorHandler.
return errRetry
}
return nil
}
return nil
}

p1.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) {
if err == errRetry {
log.Println("retrying")
// Simulate calling the next backend.
p2.ServeHTTP(w, r)
return
first.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) {
if err == errRetry {
log.Println("retrying")

// Simulate calling the next backend.
// go run ./hack/successserver
next := newReverseProxy("http://localhost:8082")
next.ServeHTTP(w, newReq(r, body))
return
}
}
}

http.ListenAndServe(":8080", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
p1.ServeHTTP(w, r)
log.Println("serving")
first.ServeHTTP(w, newReq(r, body))
}))
}

var errRetry = errors.New("retry")

func newReq(r *http.Request, body []byte) *http.Request {
clone := r.Clone(r.Context())
clone.Body = io.NopCloser(bytes.NewReader(body))
return clone
}

func newReverseProxy(addr string) *httputil.ReverseProxy {
u, err := url.Parse(addr)
if err != nil {
panic(err)
}
return httputil.NewSingleHostReverseProxy(u)
}
7 changes: 6 additions & 1 deletion hack/successserver/main.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package main

import "net/http"
import (
"io"
"net/http"
"os"
)

func main() {
http.ListenAndServe(":8082", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
io.Copy(os.Stdout, r.Body)
w.Write([]byte("success\n"))
}))
}

0 comments on commit 363aaa0

Please sign in to comment.