Skip to content

Instantly share code, notes, and snippets.

@lalloni
Last active December 7, 2016 20:42
Show Gist options
  • Save lalloni/0ccbb97adb8ef68f4627bbedaf0a1419 to your computer and use it in GitHub Desktop.
Save lalloni/0ccbb97adb8ef68f4627bbedaf0a1419 to your computer and use it in GitHub Desktop.
A contrived example of writing a transforming http proxy using oxy.
package main
import (
"io"
"net/http"
"strconv"
"github.com/mailgun/multibuf"
"github.com/mailgun/oxy/forward"
"github.com/mailgun/oxy/utils"
)
const (
targetScheme = "http"
targetHost = "www.google.com"
targetPath = "/foo"
)
type counterWriter struct {
Count int64
Writer io.Writer
}
func (c *counterWriter) Write(p []byte) (n int, err error) {
written, err := c.Writer.Write(p)
c.Count = c.Count + int64(written)
return written, err
}
func transform(mediaType string, r io.Reader, w io.Writer) {
// do something with r contents and write result to w
io.Copy(w, r)
w.Write([]byte("added content")) // just add some bytes
}
func proxy(w http.ResponseWriter, r *http.Request) {
fwd, _ := forward.New()
writer, _ := multibuf.NewWriterOnce(multibuf.MemBytes(64 * 1024))
defer writer.Close()
bw := utils.NewBufferWriter(writer)
r.URL.Scheme = targetScheme
r.URL.Host = targetHost
r.URL.Path = targetPath + "/" + r.URL.Path
fwd.ServeHTTP(bw, r)
tw, _ := multibuf.NewWriterOnce(multibuf.MemBytes(64 * 1024))
defer tw.Close()
rdr, _ := writer.Reader()
cnt := &counterWriter{0, tw}
transform(bw.Header().Get("Content-Type"), rdr, cnt)
tr, _ := tw.Reader()
utils.CopyHeaders(w.Header(), bw.Header())
w.Header().Set("Content-Length", strconv.FormatInt(cnt.Count, 10))
w.WriteHeader(bw.Code)
io.Copy(w, tr)
}
func main() {
http.ListenAndServe(":8888", http.HandlerFunc(proxy))
}
@lalloni
Copy link
Author

lalloni commented Dec 7, 2016

Please note that for the sake of simplicity all error handling has been removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment