Skip to content

Instantly share code, notes, and snippets.

@mpfund
Created March 2, 2015 07:06
Show Gist options
  • Save mpfund/73b7ba24a751899cef1f to your computer and use it in GitHub Desktop.
Save mpfund/73b7ba24a751899cef1f to your computer and use it in GitHub Desktop.
HTTPS Interception Proxy in go
package main
import (
"crypto/tls"
//"crypto/x509"
"bufio"
"fmt"
"io"
"net/http"
// "net/url"
// "strings"
)
// A very simple http proxy
func main() {
simpleProxyHandler := http.HandlerFunc(simpleProxyHandlerFunc)
http.ListenAndServe(":8080", simpleProxyHandler)
}
func simpleProxyHandlerFunc(w http.ResponseWriter, r *http.Request) {
httpc := &http.Client{}
// request uri can't be set in client requests
r.RequestURI = ""
fmt.Println(*r)
if r.Method == "CONNECT" {
w.WriteHeader(200)
cert, err := tls.LoadX509KeyPair("c:\\sslkeys\\server.cert",
"c:\\sslkeys\\server.key")
if err != nil {
fmt.Println(err.Error())
}
config := tls.Config{Certificates: []tls.Certificate{cert}}
hj, ok := w.(http.Hijacker)
if !ok {
http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError)
return
}
conn, _, err := hj.Hijack()
tlsCon := tls.Server(conn, &config)
clientTlsReader := bufio.NewReader(tlsCon)
tlsCon.Handshake()
req, err := http.ReadRequest(clientTlsReader)
fmt.Println(req)
return
}
resp, err := httpc.Do(r)
defer resp.Body.Close()
if err != nil {
fmt.Println("url: " + r.URL.String())
fmt.Println("proto: " + r.Proto)
fmt.Println(r.URL, " ", err.Error())
return
}
copyHeaders(w.Header(), resp.Header)
// copy content
io.Copy(w, resp.Body)
}
func copyHeaders(dest http.Header, source http.Header) {
for header := range source {
dest.Add(header, source.Get(header))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment