Skip to content

Instantly share code, notes, and snippets.

@mattn
Created August 27, 2013 02:12
Show Gist options
  • Save mattn/6348935 to your computer and use it in GitHub Desktop.
Save mattn/6348935 to your computer and use it in GitHub Desktop.
package main
import (
"bufio"
"errors"
"io"
"log"
"net"
"net/http"
"net/url"
"os"
"strings"
)
func dial(proxy string, host string) (conn net.Conn, err error) {
conn, err = net.Dial("tcp", proxy)
if err != nil {
return
}
req := &http.Request{
Method: "CONNECT",
URL: &url.URL{Path: host},
Host: host,
Header: make(http.Header),
}
req.Write(conn)
var resp *http.Response
resp, err = http.ReadResponse(bufio.NewReader(conn), req)
if err != nil {
return
}
if resp.StatusCode != 200 {
err = errors.New(resp.Status)
return
}
return
}
func relay(in io.Reader, out io.Writer, quit chan bool) (err error) {
var n int
b := make([]byte, 4096)
for {
n, err = in.Read(b)
if err != nil {
break
}
_, err = out.Write(b[:n])
if err != nil {
break
}
}
quit <- true
return
}
func main() {
proxy := os.Getenv("HTTP_PROXY")
host := ""
for _, arg := range os.Args[1:] {
if strings.HasPrefix(arg, "-proxy=") {
proxy = arg[7:]
} else {
host = arg
}
}
if host == "" {
log.Fatal("Usage: " + os.Args[0] + " [hostname:port]")
}
conn, err := dial(proxy, host)
if err != nil {
log.Fatal(err)
}
quit := make(chan bool)
go relay(conn, os.Stdout, quit)
go relay(os.Stdin, conn, quit)
<-quit
conn.Close()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment