<commit_before>//go:generate go run $GOROOT/src/crypto/tls/generate_cert.go -host "example.com,127.0.0.1" -ca -ecdsa-curve P256
//go:generate sh -c "go-bindata -o cert_test.go -pkg mitm *.pem"
package mitm

import (
	"bufio"
	"crypto/tls"
	"crypto/x509"
	"flag"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/http/httptest"
	"net/url"
	"os"
	"strings"
	"testing"
)

func init() {
	log.SetFlags(log.Lshortfile)
}

var hostname, _ = os.Hostname()

var (
	nettest = flag.Bool("nettest", false, "run tests over network")
)

func init() {
	flag.Parse()
}

var (
	caCert = MustAsset("cert.pem")
	caKey  = MustAsset("key.pem")
)

func testProxy(t *testing.T, setupReq func(req *http.Request), wrap func(http.Handler) http.Handler, downstream http.HandlerFunc, checkResp func(*http.Response)) {
	ds := httptest.NewTLSServer(downstream)
	defer ds.Close()

	rootCAs := x509.NewCertPool()
	if !rootCAs.AppendCertsFromPEM(caCert) {
		panic("can't add cert")
	}

	ca, err := tls.X509KeyPair(caCert, caKey)
	if err != nil {
		panic(err)
	}
	ca.Leaf, err = x509.ParseCertificate(ca.Certificate[0])
	if err != nil {
		panic(err)
	}
	cert, err := GenerateCert(&ca, "www.google.com")
	if err != nil {
		t.Fatal("GenerateCert:", err)
	}
	p := &Proxy{
		CA: &ca,
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
		},
		TLSServerConfig: &tls.Config{
			MinVersion:   tls.VersionTLS12,
			Certificates: []tls.Certificate{*cert},
		},
		Wrap: wrap,
	}

	l, err := net.Listen("tcp", "localhost:0")
	if err != nil {
		t.Fatal("Listen:", err)
	}
	defer l.Close()

	go func() {
		if err := http.Serve(l, p); err != nil {
			if !strings.Contains(err.Error(), "use of closed network") {<commit_msg>Add tests for using mitm as a transparent proxy<commit_after>//go:generate go run $GOROOT/src/crypto/tls/generate_cert.go -host "example.com,127.0.0.1" -ca -ecdsa-curve P256
//go:generate sh -c "go-bindata -o cert_test.go -pkg mitm *.pem"
package mitm

import (
	"bufio"
	"crypto/tls"
	"crypto/x509"
	"flag"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/http/httptest"
	"net/url"
	"os"
	"strings"
	"testing"
)

func init() {
	log.SetFlags(log.Lshortfile)
}

var hostname, _ = os.Hostname()

var (
	nettest = flag.Bool("nettest", false, "run tests over network")
)

func init() {
	flag.Parse()
}

var (
	caCert = MustAsset("cert.pem")
	caKey  = MustAsset("key.pem")
)

func testProxy(t *testing.T, setupReq func(req *http.Request), wrap func(http.Handler) http.Handler, downstream http.HandlerFunc, checkResp func(*http.Response)) {
	testProxyTransparent(t, setupReq, wrap, downstream, checkResp)
	testProxyDirect(t, setupReq, wrap, downstream, checkResp)
}

func setupCA() (*x509.CertPool, *tls.Certificate) {
	rootCAs := x509.NewCertPool()
	if !rootCAs.AppendCertsFromPEM(caCert) {
		panic("can't add cert")
	}

	ca, err := tls.X509KeyPair(caCert, caKey)
	if err != nil {
		panic(err)
	}
	ca.Leaf, err = x509.ParseCertificate(ca.Certificate[0])
	if err != nil {
		panic(err)
	}

	return rootCAs, &ca
}

// testProxyTransparent executes a test against Proxy using a
// simulating a transparent proxy (set up by NewListener).
func testProxyTransparent(t *testing.T, setupReq func(req *http.Request), wrap func(http.Handler) http.Handler, downstream http.HandlerFunc, checkResp func(*http.Response)) {
	ds := httptest.NewTLSServer(downstream)
	defer ds.Close()

	rootCAs, ca := setupCA()
	cert, err := GenerateCert(ca, "www.google.com")
	if err != nil {
		t.Fatal("GenerateCert:", err)
	}
	p := &Proxy{
		Director: HTTPSDirector,
		Wrap:     wrap,
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		},
	}

	l, err := net.Listen("tcp", "localhost:0")
	if err != nil {
		t.Fatal("Listen:", err)
	}
	l = NewListener(l, ca, &tls.Config{
		MinVersion:   tls.VersionSSL30,
		Certificates: []tls.Certificate{*cert},
	})
	defer l.Close()

	go func() {
		if err := http.Serve(l, p); err != nil {
			if !strings.Contains(err.Error(), "use of closed network") {
				t.Fatal("Serve:", err)
			}
		}
	}()

	t.Logf("requesting %q", ds.URL)
	req, err := http.NewRequest("GET", ds.URL, nil)
	if err != nil {
		t.Fatal("NewRequest:", err)
	}
	setupReq(req)
	d, err := tls.Dial(l.Addr().Network(), l.Addr().String(), &tls.Config{
		RootCAs: rootCAs,
	})
	if err != nil {
		t.Fatal("Dial error:", err)
	}

	err = req.Write(d)
	if err != nil {
		t.Fatal("Request write error:", err)
	}
	resp, err := http.ReadResponse(bufio.NewReader(d), req)
	checkResp(resp)
}

// testProxyDirect executes a test against Proxy with a client-side
// proxy configuration.
func testProxyDirect(t *testing.T, setupReq func(req *http.Request), wrap func(http.Handler) http.Handler, downstream http.HandlerFunc, checkResp func(*http.Response)) {
	ds := httptest.NewTLSServer(downstream)
	defer ds.Close()

	rootCAs, ca := setupCA()

	cert, err := GenerateCert(ca, "www.google.com")
	if err != nil {
		t.Fatal("GenerateCert:", err)
	}
	p := &Proxy{
		CA: ca,
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
		},
		TLSServerConfig: &tls.Config{
			MinVersion:   tls.VersionTLS12,
			Certificates: []tls.Certificate{*cert},
		},
		Wrap: wrap,
	}

	l, err := net.Listen("tcp", "localhost:0")
	if err != nil {
		t.Fatal("Listen:", err)
	}
	defer l.Close()

	go func() {
		if err := http.Serve(l, p); err != nil {
			if !strings.Contains(err.Error(), "use of closed network") {
{'fraction_non_alphanumeric': 0.17097193830143095, 'fraction_numerical': 0.010406987548782755, 'mean_word_length': 3.9879518072289155, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 3, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1397952', 'n_tokens_mistral': 2246, 'n_tokens_neox': 2095, 'n_words': 477}