Skip to content

Commit

Permalink
Modified version of github.com/elazarl/goproxy
Browse files Browse the repository at this point in the history
Important changes:

Fixes elazarl#256:  connections are closed after usage, so FD-count remains
congruent with the actual amount of open connections.

Added ProxyHttpServer.Signer of type
	type Signer func(ca *tls.Certificate, hostname []string) (*tls.Certificate, error)
If ProxyHttpServer.Signer is set, the goproxy uses that function to
retrieve Certificates for TLS-interception.  This allows consumers of
goproxy to implement f.e. caching of certificates.

Minor changes:

- adjusted import-path to github.com/oec/goproxy
- go fmt on all files
  • Loading branch information
oec committed Nov 28, 2018
1 parent 947c36d commit 096338b
Show file tree
Hide file tree
Showing 32 changed files with 213 additions and 107 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Introduction

[![GoDoc](https://godoc.org/github.com/elazarl/goproxy?status.svg)](https://godoc.org/github.com/elazarl/goproxy)
[![Join the chat at https://gitter.im/elazarl/goproxy](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/elazarl/goproxy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![GoDoc](https://godoc.org/github.com/oec/goproxy?status.svg)](https://godoc.org/github.com/oec/goproxy)
[![Join the chat at https://gitter.im/oec/goproxy](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/oec/goproxy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

Package goproxy provides a customizable HTTP proxy library for Go (golang),

Expand All @@ -27,7 +27,7 @@ before their development.

## Latest Stable Release

Get the latest goproxy from `gopkg.in/elazarl/goproxy.v1`.
Get the latest goproxy from `gopkg.in/oec/goproxy.v1`.

# Why not Fiddler2?

Expand All @@ -48,7 +48,7 @@ To get a taste of `goproxy`, a basic HTTP/HTTPS transparent proxy
package main

import (
"github.com/elazarl/goproxy"
"github.com/oec/goproxy"
"log"
"net/http"
)
Expand Down Expand Up @@ -103,8 +103,8 @@ See additional examples in the examples directory.
# What's New

1. Ability to `Hijack` CONNECT requests. See
[the eavesdropper example](https://github.com/elazarl/goproxy/blob/master/examples/goproxy-eavesdropper/main.go#L27)
2. Transparent proxy support for http/https including MITM certificate generation for TLS. See the [transparent example.](https://github.com/elazarl/goproxy/tree/master/examples/goproxy-transparent)
[the eavesdropper example](https://github.com/oec/goproxy/blob/master/examples/goproxy-eavesdropper/main.go#L27)
2. Transparent proxy support for http/https including MITM certificate generation for TLS. See the [transparent example.](https://github.com/oec/goproxy/tree/master/examples/goproxy-transparent)

# License

Expand Down
4 changes: 2 additions & 2 deletions certs/openssl.cnf
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ basicConstraints = critical,CA:true
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = IL
countryName_default = DE
countryName_min = 2
countryName_max = 2

Expand All @@ -35,5 +35,5 @@ commonName_default = goproxy.github.io
commonName_max = 64

emailAddress = Email Address
emailAddress_default = [email protected]
emailAddress_default = [email protected]
emailAddress_max = 64
2 changes: 1 addition & 1 deletion counterecryptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"math/rand"
"testing"

"github.com/elazarl/goproxy"
"github.com/oec/goproxy"
)

type RandSeedReader struct {
Expand Down
4 changes: 4 additions & 0 deletions ctx.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package goproxy

import (
"crypto/tls"
"net/http"
"regexp"
)
Expand All @@ -20,13 +21,16 @@ type ProxyCtx struct {
UserData interface{}
// Will connect a request to a response
Session int64
signer Signer
proxy *ProxyHttpServer
}

type RoundTripper interface {
RoundTrip(req *http.Request, ctx *ProxyCtx) (*http.Response, error)
}

type Signer func(ca *tls.Certificate, hostname []string) (*tls.Certificate, error)

type RoundTripperFunc func(req *http.Request, ctx *ProxyCtx) (*http.Response, error)

func (f RoundTripperFunc) RoundTrip(req *http.Request, ctx *ProxyCtx) (*http.Response, error) {
Expand Down
10 changes: 5 additions & 5 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ we close the body of the original repsonse, and return a new 403 response with a
Example use cases:
1. https://github.com/elazarl/goproxy/tree/master/examples/goproxy-avgsize
1. https://github.com/oec/goproxy/tree/master/examples/goproxy-avgsize
To measure the average size of an Html served in your site. One can ask
all the QA team to access the website by a proxy, and the proxy will
Expand All @@ -79,20 +79,20 @@ All requests to your web servers should be directed through the proxy,
when the proxy will detect html pieces sent as a response to AJAX
request, it'll send a warning email.
3. https://github.com/elazarl/goproxy/blob/master/examples/goproxy-httpdump/
3. https://github.com/oec/goproxy/blob/master/examples/goproxy-httpdump/
Generate a real traffic to your website by real users using through
proxy. Record the traffic, and try it again for more real load testing.
4. https://github.com/elazarl/goproxy/tree/master/examples/goproxy-no-reddit-at-worktime
4. https://github.com/oec/goproxy/tree/master/examples/goproxy-no-reddit-at-worktime
Will allow browsing to reddit.com between 8:00am and 17:00pm
5. https://github.com/elazarl/goproxy/tree/master/examples/goproxy-jquery-version
5. https://github.com/oec/goproxy/tree/master/examples/goproxy-jquery-version
Will warn if multiple versions of jquery are used in the same domain.
6. https://github.com/elazarl/goproxy/blob/master/examples/goproxy-upside-down-ternet/
6. https://github.com/oec/goproxy/blob/master/examples/goproxy-upside-down-ternet/
Modifies image files in an HTTP response via goproxy's image extension found in ext/.
Expand Down
4 changes: 2 additions & 2 deletions examples/cascadeproxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import (
"strings"
"time"

"github.com/elazarl/goproxy/ext/auth"
"github.com/oec/goproxy/ext/auth"

"github.com/elazarl/goproxy"
"github.com/oec/goproxy"
)

const (
Expand Down
5 changes: 3 additions & 2 deletions examples/goproxy-basic/main.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package main

import (
"github.com/elazarl/goproxy"
"log"
"flag"
"log"
"net/http"

"github.com/oec/goproxy"
)

func main() {
Expand Down
2 changes: 1 addition & 1 deletion examples/goproxy-customca/cert.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"crypto/tls"
"crypto/x509"

"github.com/elazarl/goproxy"
"github.com/oec/goproxy"
)

var caCert = []byte(`-----BEGIN CERTIFICATE-----
Expand Down
2 changes: 1 addition & 1 deletion examples/goproxy-customca/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"log"
"net/http"

"github.com/elazarl/goproxy"
"github.com/oec/goproxy"
)

func main() {
Expand Down
44 changes: 22 additions & 22 deletions examples/goproxy-eavesdropper/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"net/http"
"regexp"

"github.com/elazarl/goproxy"
"github.com/oec/goproxy"
)

func orPanic(err error) {
Expand All @@ -26,28 +26,28 @@ func main() {
// enable curl -p for all hosts on port 80
proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile("^.*:80$"))).
HijackConnect(func(req *http.Request, client net.Conn, ctx *goproxy.ProxyCtx) {
defer func() {
if e := recover(); e != nil {
ctx.Logf("error connecting to remote: %v", e)
client.Write([]byte("HTTP/1.1 500 Cannot reach destination\r\n\r\n"))
}
client.Close()
}()
clientBuf := bufio.NewReadWriter(bufio.NewReader(client), bufio.NewWriter(client))
remote, err := net.Dial("tcp", req.URL.Host)
orPanic(err)
remoteBuf := bufio.NewReadWriter(bufio.NewReader(remote), bufio.NewWriter(remote))
for {
req, err := http.ReadRequest(clientBuf.Reader)
orPanic(err)
orPanic(req.Write(remoteBuf))
orPanic(remoteBuf.Flush())
resp, err := http.ReadResponse(remoteBuf.Reader, req)
defer func() {
if e := recover(); e != nil {
ctx.Logf("error connecting to remote: %v", e)
client.Write([]byte("HTTP/1.1 500 Cannot reach destination\r\n\r\n"))
}
client.Close()
}()
clientBuf := bufio.NewReadWriter(bufio.NewReader(client), bufio.NewWriter(client))
remote, err := net.Dial("tcp", req.URL.Host)
orPanic(err)
orPanic(resp.Write(clientBuf.Writer))
orPanic(clientBuf.Flush())
}
})
remoteBuf := bufio.NewReadWriter(bufio.NewReader(remote), bufio.NewWriter(remote))
for {
req, err := http.ReadRequest(clientBuf.Reader)
orPanic(err)
orPanic(req.Write(remoteBuf))
orPanic(remoteBuf.Flush())
resp, err := http.ReadResponse(remoteBuf.Reader, req)
orPanic(err)
orPanic(resp.Write(clientBuf.Writer))
orPanic(clientBuf.Flush())
}
})
verbose := flag.Bool("v", false, "should every proxy request be logged to stdout")
addr := flag.String("addr", ":8080", "proxy listen address")
flag.Parse()
Expand Down
4 changes: 2 additions & 2 deletions examples/goproxy-httpdump/httpdump.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (
"sync"
"time"

"github.com/elazarl/goproxy"
"github.com/elazarl/goproxy/transport"
"github.com/oec/goproxy"
"github.com/oec/goproxy/transport"
)

type FileStream struct {
Expand Down
5 changes: 3 additions & 2 deletions examples/goproxy-jquery-version/main.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package main

import (
"github.com/elazarl/goproxy"
"github.com/elazarl/goproxy/ext/html"
"log"
"net/http"
"regexp"

"github.com/oec/goproxy"
"github.com/oec/goproxy/ext/html"
)

var (
Expand Down
3 changes: 2 additions & 1 deletion examples/goproxy-no-reddit-at-worktime/noreddit.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package main

import (
"github.com/elazarl/goproxy"
"log"
"net/http"
"time"

"github.com/oec/goproxy"
)

func main() {
Expand Down
3 changes: 2 additions & 1 deletion examples/goproxy-sokeepalive/sokeepalive.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package main

import (
"flag"
"github.com/elazarl/goproxy"
"log"
"net"
"net/http"

"github.com/oec/goproxy"
)

func main() {
Expand Down
7 changes: 4 additions & 3 deletions examples/goproxy-sslstrip/sslstrip.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package main

import (
"github.com/elazarl/goproxy"
"log"
"flag"
"log"
"net/http"

"github.com/oec/goproxy"
)

func main() {
Expand All @@ -13,7 +14,7 @@ func main() {
flag.Parse()
proxy := goproxy.NewProxyHttpServer()
proxy.OnRequest().HandleConnect(goproxy.AlwaysMitm)
proxy.OnRequest().DoFunc(func (req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
proxy.OnRequest().DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
if req.URL.Scheme == "https" {
req.URL.Scheme = "http"
}
Expand Down
5 changes: 3 additions & 2 deletions examples/goproxy-stats/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package main

import (
"fmt"
"github.com/elazarl/goproxy"
"github.com/elazarl/goproxy/ext/html"
"io"
"log"
. "net/http"
"time"

"github.com/oec/goproxy"
"github.com/oec/goproxy/ext/html"
)

type Count struct {
Expand Down
4 changes: 2 additions & 2 deletions examples/goproxy-transparent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This transparent example in goproxy is meant to show how to transparenty proxy a

## Why not explicit?

Transparent proxies are more difficult to maintain and setup from a server side, but they require no configuration on the client(s) which could be in unmanaged systems or systems that don't support a proxy configuration. See the [eavesdropper example](https://github.com/elazarl/goproxy/blob/master/examples/goproxy-eavesdropper/main.go) if you want to see an explicit proxy example.
Transparent proxies are more difficult to maintain and setup from a server side, but they require no configuration on the client(s) which could be in unmanaged systems or systems that don't support a proxy configuration. See the [eavesdropper example](https://github.com/oec/goproxy/blob/master/examples/goproxy-eavesdropper/main.go) if you want to see an explicit proxy example.

## Potential Issues

Expand All @@ -14,4 +14,4 @@ If you're routing table allows for it, an explicit http request to goproxy will

## Routing Rules

Example routing rules are included in [proxy.sh](https://github.com/elazarl/goproxy/blob/master/examples/goproxy-transparent/proxy.sh) but are best when setup using your distribution's configuration.
Example routing rules are included in [proxy.sh](https://github.com/oec/goproxy/blob/master/examples/goproxy-transparent/proxy.sh) but are best when setup using your distribution's configuration.
45 changes: 22 additions & 23 deletions examples/goproxy-transparent/transparent.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import (
"net/url"
"regexp"

"github.com/elazarl/goproxy"
"github.com/inconshreveable/go-vhost"
"github.com/oec/goproxy"
)

func orPanic(err error) {
Expand Down Expand Up @@ -46,28 +45,28 @@ func main() {
HandleConnect(goproxy.AlwaysMitm)
proxy.OnRequest(goproxy.ReqHostMatches(regexp.MustCompile("^.*:80$"))).
HijackConnect(func(req *http.Request, client net.Conn, ctx *goproxy.ProxyCtx) {
defer func() {
if e := recover(); e != nil {
ctx.Logf("error connecting to remote: %v", e)
client.Write([]byte("HTTP/1.1 500 Cannot reach destination\r\n\r\n"))
}
client.Close()
}()
clientBuf := bufio.NewReadWriter(bufio.NewReader(client), bufio.NewWriter(client))
remote, err := connectDial(proxy, "tcp", req.URL.Host)
orPanic(err)
remoteBuf := bufio.NewReadWriter(bufio.NewReader(remote), bufio.NewWriter(remote))
for {
req, err := http.ReadRequest(clientBuf.Reader)
orPanic(err)
orPanic(req.Write(remoteBuf))
orPanic(remoteBuf.Flush())
resp, err := http.ReadResponse(remoteBuf.Reader, req)
defer func() {
if e := recover(); e != nil {
ctx.Logf("error connecting to remote: %v", e)
client.Write([]byte("HTTP/1.1 500 Cannot reach destination\r\n\r\n"))
}
client.Close()
}()
clientBuf := bufio.NewReadWriter(bufio.NewReader(client), bufio.NewWriter(client))
remote, err := connectDial(proxy, "tcp", req.URL.Host)
orPanic(err)
orPanic(resp.Write(clientBuf.Writer))
orPanic(clientBuf.Flush())
}
})
remoteBuf := bufio.NewReadWriter(bufio.NewReader(remote), bufio.NewWriter(remote))
for {
req, err := http.ReadRequest(clientBuf.Reader)
orPanic(err)
orPanic(req.Write(remoteBuf))
orPanic(remoteBuf.Flush())
resp, err := http.ReadResponse(remoteBuf.Reader, req)
orPanic(err)
orPanic(resp.Write(clientBuf.Writer))
orPanic(clientBuf.Flush())
}
})

go func() {
log.Fatalln(http.ListenAndServe(*http_addr, proxy))
Expand Down
Loading

0 comments on commit 096338b

Please sign in to comment.