Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Octocat-spinner-32 examples fixes #43, Hijack method to hijack CONNECT requests April 09, 2014
Octocat-spinner-32 ext authorization support on CONNECT December 25, 2013
Octocat-spinner-32 regretable Add missing NewRegretableReaderCloserSize February 07, 2013
Octocat-spinner-32 test_data move test data to its own dir March 26, 2012
Octocat-spinner-32 transport added error assignment on while writing to network September 19, 2013
Octocat-spinner-32 .gitignore .gitignore, ./all.bash more organized March 29, 2012
Octocat-spinner-32 LICENSE by @ancientlore email request, adding LICENSE file April 06, 2013
Octocat-spinner-32 README.md fixes #43, Hijack method to hijack CONNECT requests April 09, 2014
Octocat-spinner-32 actions.go gofmt November 14, 2013
Octocat-spinner-32 all.bash move regret buffer to package, improve January 23, 2013
Octocat-spinner-32 ca.pem signer functions to generate real verifiable certificates July 22, 2013
Octocat-spinner-32 certs.go adapt tests to new signHost, test didn't work since e3c34 October 09, 2013
Octocat-spinner-32 chunked.go gofmt November 14, 2013
Octocat-spinner-32 counterecryptor.go gofmt November 14, 2013
Octocat-spinner-32 counterecryptor_test.go gofmt November 14, 2013
Octocat-spinner-32 ctx.go Merge remote-tracking branch 'origin/customtransport' into master March 23, 2014
Octocat-spinner-32 dispatcher.go fixes #43, Hijack method to hijack CONNECT requests April 09, 2014
Octocat-spinner-32 doc.go Updated reference to the new examples February 28, 2014
Octocat-spinner-32 https.go better logging for copyAndClose, on CONNECT accept April 18, 2014
Octocat-spinner-32 key.pem signer functions to generate real verifiable certificates July 22, 2013
Octocat-spinner-32 proxy.go better logging for copyAndClose, on CONNECT accept April 18, 2014
Octocat-spinner-32 proxy_test.go fixes #44, add HTTP MITM to support curl -p April 16, 2014
Octocat-spinner-32 responses.go gofmt June 22, 2012
Octocat-spinner-32 signer.go gofmt November 14, 2013
Octocat-spinner-32 signer_test.go gofmt November 14, 2013
README.md

Introduction

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

It supports regular HTTP proxy, HTTPS through CONNECT, and "hijacking" HTTPS connection using "Man in the Middle" style attack.

The intent of the proxy, is to be usable with reasonable amount of traffic yet, customizable and programable.

The proxy itself is simply a net/http handler.

In order to use goproxy, one should set his browser to use goproxy as an HTTP proxy. Here is how you do that in Chrome and in Firefox.

For example, the URL you should use as proxy when running ./bin/basic is localhost:8080, as this is the default binding for the basic proxy.

Why not Fiddler2?

Fiddler is an excellent software with similar intent. However, Fiddler is not as customable as goproxy intend to be. The main difference is, Fiddler is not intended to be used as a real proxy.

A possible use case that suits goproxy but not Fiddler, is, gathering statisitics on page load times for a certain website over a week. With goproxy you could ask all your users to set their proxy to a dedicated machine running a goproxy server. Fiddler is a GUI app not designed to be ran like a server for multiple users.

A taste of goproxy

To get a taste of goproxy, a basic HTTP/HTTPS transparent proxy

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

func main() {
    proxy := goproxy.NewProxyHttpServer()
    proxy.Verbose = true
    log.Fatal(http.ListenAndServe(":8080", proxy))
}

This line will add X-GoProxy: yxorPoG-X header to all requests sent through the proxy

proxy.OnRequest().DoFunc(
    func(r *http.Request,ctx *goproxy.ProxyCtx)(*http.Request,*http.Response) {
        r.Header.Set("X-GoProxy","yxorPoG-X")
        return r,nil
    }
)

DoFunc will process all incoming requests to the proxy. It will add a header to the request and return it. The proxy will send the modified request.

Note that we returned nil value as the response. Have we returned a response, goproxy would have discarded the request and sent the new response to the client.

In order to refuse connections to reddit at work time

proxy.OnRequest(goproxy.DstHostIs("www.reddit.com")).DoFunc(
    func(r *http.Request,ctx *goproxy.ProxyCtx)(*http.Request,*http.Response) {
        if h,_,_ := time.Now().Clock(); h >= 8 && h <= 17 {
            return r,goproxy.NewResponse(r,
                    goproxy.ContentTypeText,http.StatusForbidden,
                    "Don't waste your time!")
        }
        return r,nil
})

DstHostIs returns a ReqCondition, that is a function receiving a Request and returning a boolean we will only process requests that matches the condition. DstHostIs("www.reddit.com") will return a ReqCondition accepting only requests directed to "www.reddit.com".

DoFunc will recieve a function that will preprocess the request. We can change the request, or return a response. If the time is between 8:00am and 17:00pm, we will neglect the request, and return a precanned text response saying "do not waste your time".

See additional examples in the examples directory.

What's New

  1. Ability to Hijack CONNECT requests. See the eavesdropper example

License

I put the software temporarily under the Go-compatible BSD license, if this prevents someone from using the software, do let mee know and I'll consider changing it.

At any rate, user feedback is very important for me, so I'll be delighted to know if you're using this package.

Beta Software

I've received a positive feedback from a few people who use goproxy in production settings. I believe it is good enough for usage.

I'll try to keep reasonable backwards compatability. In case of a major API change, I'll change the import path.

Something went wrong with that request. Please try again.