move some stuff to common

This commit is contained in:
idk
2019-02-26 22:36:26 -05:00
parent 8ecbe5f112
commit f2c56fe622
6 changed files with 168 additions and 123 deletions

View File

@ -15,8 +15,9 @@ win64:
GOOS=windows GOARCH=amd64 go build \
$(GO_COMPILER_OPTS) \
-buildmode=exe \
-o ./httproxy.exe \
-o ./httpproxy.exe \
./windows/main.go
@echo "built"
win32:
GOOS=windows GOARCH=386 go build \
@ -24,6 +25,7 @@ win32:
-buildmode=exe \
-o ./httpproxy.exe \
./windows/main.go
@echo "built"
lin: lin64 lin32
@ -32,6 +34,7 @@ lin64:
$(GO_COMPILER_OPTS) \
-o ./httpproxy-64 \
./httpproxy/main.go
@echo "built"
lin32:
GOOS=linux GOARCH=386 go build \
@ -39,6 +42,7 @@ lin32:
-buildmode=exe \
-o ./httpproxy-32 \
./httpproxy/main.go
@echo "built"
linarm: linarm32 linarm64
@ -48,6 +52,7 @@ linarm64:
-buildmode=exe \
-o ./httpproxy-arm64 \
./httpproxy/main.go
@echo "built"
linarm32:
GOOS=linux GOARCH=arm go build \
@ -55,6 +60,7 @@ linarm32:
-buildmode=exe \
-o ./httpproxy-arm32 \
./httpproxy/main.go
@echo "built"
mac: mac32 mac64
@ -64,12 +70,14 @@ mac64:
$(GO_COMPILER_OPTS) \
-o ./httpproxy-64.app \
./httpproxy/main.go
@echo "built"
mac32:
GOOS=darwin GOARCH=amd64 go build \
$(GO_COMPILER_OPTS) \
-o ./httpproxy-32.app \
./httpproxy/main.go
@echo "built"
vet:
go vet ./*.go
@ -77,4 +85,4 @@ vet:
go vet ./windows/*.go
clean:
rm -f httpproxy-*
rm -f httpproxy-* *.exe *.log

View File

@ -1,6 +1,8 @@
i2phttpproxy
============
**This is *way* more useful than it is tested. Please be careful.**
This is a very simple standalone HTTP Proxy for i2p based on the SAM Bridge. It
has a few advantages in certain situations, especially for adapting applications
that speak HTTP to the i2p network. It allows applications to start their own
@ -15,6 +17,9 @@ multiple clients at the same time. It might be more-or-less OK as part of an
inproxy but you should only use it for one client at a time. A multi-client
solution will also be available soon([eeProxy](https://github.com/eyedeekay/eeProxy)).
This is not something you should use without understanding. It is also not
terribly hard to understand.
Features: Done
--------------
@ -22,3 +27,8 @@ Features: Done
* CONNECT support
* "New Ident" signaling interface(Unix-only for now)(I guess I might have done
for Windows too now but I haven't tried it out yet).
Features: Planned
-----------------
* Outproxy Support

45
common/common.go Normal file
View File

@ -0,0 +1,45 @@
package proxycommon
import (
"io"
"log"
"net/http"
)
var hopHeaders = []string{
"Accept-Language",
"Connection",
"Keep-Alive",
"Proxy-Authenticate",
"Proxy-Authorization",
"Proxy-Connection",
"Te", // canonicalized version of "TE"
"Trailers",
"Transfer-Encoding",
"Upgrade",
"X-Forwarded-For",
}
func Transfer(destination io.WriteCloser, source io.ReadCloser) {
defer destination.Close()
defer source.Close()
log.Println("connecting connection")
io.Copy(destination, source)
}
func DelHopHeaders(header http.Header) {
for _, h := range hopHeaders {
header.Del(h)
}
if header.Get("User-Agent") != "MYOB/6.66 (AN/ON)" {
header.Set("User-Agent", "MYOB/6.66 (AN/ON)")
}
}
func CopyHeader(dst, src http.Header) {
for k, vv := range src {
for _, v := range vv {
dst.Add(k, v)
}
}
}

View File

@ -11,7 +11,8 @@ import (
)
import (
. "github.com/eyedeekay/httptunnel"
//. "github.com/eyedeekay/httptunnel"
. ".."
"github.com/eyedeekay/littleboss"
)
@ -30,10 +31,13 @@ var (
inboundVariance = flag.Int("in-variance", 0, "Inbound Backup Count(default 3)")
outboundVariance = flag.Int("out-variance", 0, "Inbound Backup Count(default 3)")
dontPublishLease = flag.Bool("no-publish", true, "Don't publish the leaseset(Client mode)")
//encryptLease = flag.Bool("encrypt-lease", true, "Encrypt the leaseset(")
reduceIdle = flag.Bool("reduce-idle", false, "Reduce tunnels on extended idle time")
reduceIdleTime = flag.Int("reduce-idle-time", 2000000, "Reduce tunnels after time(Ms)")
reduceIdleQuantity = flag.Int("reduce-idle-tunnels", 1, "Reduce tunnels to this level")
encryptLease = flag.Bool("encrypt-lease", false, "Encrypt the leaseset(default false, inert)")
reduceIdle = flag.Bool("reduce-idle", false, "Reduce tunnels on extended idle time")
closeIdle = flag.Bool("close-idle", false, "Close tunnels on extended idle time")
closeIdleTime = flag.Int("close-idle-time", 3000000, "Reduce tunnels after time(Ms)")
useCompression = flag.Bool("use-compression", true, "Enable gzip compression")
reduceIdleTime = flag.Int("reduce-idle-time", 2000000, "Reduce tunnels after time(Ms)")
reduceIdleQuantity = flag.Int("reduce-idle-tunnels", 1, "Reduce tunnels to this level")
)
var addr string
@ -54,7 +58,7 @@ func proxyMain(ctx context.Context, ln net.Listener, cln net.Listener) {
srv := &http.Server{
ReadTimeout: 600 * time.Second,
WriteTimeout: 600 * time.Second,
Addr: addr,
Addr: ln.Addr().String(),
}
var err error
srv.Handler, err = NewHttpProxy(
@ -71,17 +75,20 @@ func proxyMain(ctx context.Context, ln net.Listener, cln net.Listener) {
SetOutVariance(*outboundVariance),
SetUnpublished(*dontPublishLease),
SetReduceIdle(*reduceIdle),
SetCompression(*useCompression),
SetReduceIdleTime(uint(*reduceIdleTime)),
SetReduceIdleQuantity(uint(*reduceIdleQuantity)),
SetCloseIdle(*closeIdle),
SetCloseIdleTime(uint(*closeIdleTime)),
)
if err != nil {
log.Fatal(err)
}
ctrlsrv := &http.Server{
ReadTimeout: 600 * time.Second,
WriteTimeout: 600 * time.Second,
Addr: addr,
ReadHeaderTimeout: 600 * time.Second,
WriteTimeout: 600 * time.Second,
Addr: cln.Addr().String(),
}
ctrlsrv.Handler, err = NewSAMHTTPController(profiles, nil)

View File

@ -25,7 +25,7 @@ func SetAddr(s ...string) func(*SAMHTTPProxy) error {
}
return fmt.Errorf("Invalid port; non-number")
}
return fmt.Errorf("Invalid address; use host:port %s", split)
return fmt.Errorf("Invalid address; use host:port %s ", split)
} else if len(s) == 2 {
if i, err := strconv.Atoi(s[1]); err == nil {
if i < 65536 {
@ -238,6 +238,25 @@ func SetCompression(b bool) func(*SAMHTTPProxy) error {
}
}
//SetCloseIdle enables debugging messages
func SetCloseIdle(b bool) func(*SAMHTTPProxy) error {
return func(c *SAMHTTPProxy) error {
c.closeIdle = b
return nil
}
}
//SetCloseIdleTime sets time to wait before the tunnel quantity is reduced
func SetCloseIdleTime(u uint) func(*SAMHTTPProxy) error {
return func(c *SAMHTTPProxy) error {
if u > 300000 {
c.closeIdleTime = u
return nil
}
return fmt.Errorf("Invalid reduce idle time %v", u)
}
}
//return the inbound length as a string.
func (c *SAMHTTPProxy) inlength() string {
return fmt.Sprintf("inbound.length=%d", c.inLength)
@ -307,9 +326,20 @@ func (c *SAMHTTPProxy) reduceidlecount() string {
return fmt.Sprintf("i2cp.reduceIdleQuantity=%d", c.reduceIdleQuantity)
}
func (c *SAMHTTPProxy) compresion() string {
func (c *SAMHTTPProxy) usecompresion() string {
if c.compression {
return "i2cp.gzip=true"
}
return "i2cp.gzip=false"
}
func (c *SAMHTTPProxy) closeonidle() string {
if c.reduceIdle {
return "i2cp.closeOnIdle=true"
}
return "i2cp.closeOnIdle=false"
}
func (c *SAMHTTPProxy) closeidletime() string {
return fmt.Sprintf("i2cp.closeIdleTime=%d", c.reduceIdleTime)
}

View File

@ -1,7 +1,7 @@
package i2phttpproxy
import (
"crypto/tls"
//"crypto/tls"
"io"
"log"
"net/http"
@ -11,18 +11,14 @@ import (
import (
"github.com/eyedeekay/goSam"
"github.com/eyedeekay/sam3"
"github.com/eyedeekay/httptunnel/common"
)
type SAMHTTPProxy struct {
gosam *goSam.Client
Client *http.Client
samcon *sam3.SAM
keys sam3.I2PKeys
stream *sam3.StreamSession
SamHost string
SamPort string
TunName string
inLength uint
outLength uint
inVariance int
@ -36,36 +32,15 @@ type SAMHTTPProxy struct {
reduceIdle bool
reduceIdleTime uint
reduceIdleQuantity uint
closeIdle bool
closeIdleTime uint
compression bool
useOutProxy bool
debug bool
}
func copyHeader(dst, src http.Header) {
for k, vv := range src {
for _, v := range vv {
dst.Add(k, v)
}
}
}
var hopHeaders = []string{
"Proxy-Authenticate",
"Proxy-Authorization",
"Proxy-Connection",
"X-Forwarded-For",
"Accept-Language",
}
func delHopHeaders(header http.Header) {
for _, h := range hopHeaders {
header.Del(h)
}
if header.Get("User-Agent") != "MYOB/6.66 (AN/ON)" {
header.Set("User-Agent", "MYOB/6.66 (AN/ON)")
}
}
func (p *SAMHTTPProxy) freshClient() *http.Client {
return &http.Client{
Transport: &http.Transport{
@ -76,38 +51,65 @@ func (p *SAMHTTPProxy) freshClient() *http.Client {
ResponseHeaderTimeout: time.Second * 600,
ExpectContinueTimeout: time.Second * 600,
IdleConnTimeout: time.Second * 600,
TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper),
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
//TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper),
//TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
CheckRedirect: nil,
Timeout: time.Second * 600,
CheckRedirect: nil,
}
}
func (p *SAMHTTPProxy) ServeHTTP(wr http.ResponseWriter, req *http.Request) {
log.Println(req.RemoteAddr, " ", req.Method, " ", req.URL)
if req.URL.Scheme != "http" && req.URL.Scheme != "https" && !strings.HasSuffix(req.URL.Host, ".i2p") {
msg := "unsupported protocal scheme " + req.URL.Scheme
if req.URL.Scheme != "http" && req.URL.Scheme != "https" {
if !(req.Method == http.MethodConnect) {
msg := "Unsupported protocol scheme " + req.URL.Scheme
http.Error(wr, msg, http.StatusBadRequest)
log.Println(msg)
return
}
}
log.Println(req.URL.Host)
if !strings.HasSuffix(req.URL.Host, ".i2p") {
msg := "Unsupported host " + req.URL.Host
http.Error(wr, msg, http.StatusBadRequest)
log.Println(msg)
return
}
if req.Method == http.MethodConnect {
log.Println("Connecting tunnel")
p.connect(wr, req)
return
} else {
req.RequestURI = ""
delHopHeaders(req.Header)
p.get(wr, req)
return
}
}
func (p *SAMHTTPProxy) get(wr http.ResponseWriter, req *http.Request) {
req.RequestURI = ""
proxycommon.DelHopHeaders(req.Header)
resp, err := p.Client.Do(req)
if err != nil {
msg := "Proxy Error " + err.Error()
http.Error(wr, msg, http.StatusBadRequest)
log.Println(msg)
return
}
defer resp.Body.Close()
proxycommon.CopyHeader(wr.Header(), resp.Header)
wr.WriteHeader(resp.StatusCode)
io.Copy(wr, resp.Body)
}
func (p *SAMHTTPProxy) connect(wr http.ResponseWriter, req *http.Request) {
dest_conn, err := p.stream.Dial("tcp", req.Host)
log.Println("CONNECT via i2p to", req.URL.Host)
dest_conn, err := p.gosam.Dial("tcp", req.URL.Host)
if err != nil {
http.Error(wr, err.Error(), http.StatusServiceUnavailable)
return
@ -121,67 +123,32 @@ func (p *SAMHTTPProxy) connect(wr http.ResponseWriter, req *http.Request) {
client_conn, _, err := hijacker.Hijack()
if err != nil {
http.Error(wr, err.Error(), http.StatusServiceUnavailable)
}
go transfer(dest_conn, client_conn)
go transfer(client_conn, dest_conn)
}
func transfer(destination io.WriteCloser, source io.ReadCloser) {
defer destination.Close()
defer source.Close()
io.Copy(destination, source)
}
func (p *SAMHTTPProxy) get(wr http.ResponseWriter, req *http.Request) {
Client := p.freshClient()
resp, err := Client.Do(req)
if err != nil {
log.Println("ServeHTTP:", err)
return
}
defer resp.Body.Close()
wr.WriteHeader(resp.StatusCode)
io.Copy(wr, resp.Body)
}
func (p *SAMHTTPProxy) sam3Args() []string {
return []string{
p.inlength(),
p.outlength(),
p.invariance(),
p.outvariance(),
p.inquantity(),
p.outquantity(),
p.inbackups(),
p.outbackups(),
p.dontpublishlease(),
p.encryptlease(),
p.reduceonidle(),
p.reduceidletime(),
p.reduceidlecount(),
"i2cp.gzip=true",
}
go proxycommon.Transfer(dest_conn, client_conn)
go proxycommon.Transfer(client_conn, dest_conn)
}
func NewHttpProxy(opts ...func(*SAMHTTPProxy) error) (*SAMHTTPProxy, error) {
var handler SAMHTTPProxy
handler.SamHost = "127.0.0.1"
handler.SamPort = "7656"
handler.TunName = "sam-http-proxy"
handler.inLength = 2
handler.outLength = 2
handler.inVariance = 0
handler.outVariance = 0
handler.inQuantity = 1
handler.outQuantity = 1
handler.inQuantity = 2
handler.outQuantity = 2
handler.inBackups = 1
handler.outBackups = 1
handler.dontPublishLease = true
handler.encryptLease = false
handler.reduceIdle = false
handler.reduceIdleTime = 2000000
handler.closeIdleTime = 3000000
handler.reduceIdleQuantity = 1
handler.useOutProxy = false
handler.compression = true
for _, o := range opts {
if err := o(&handler); err != nil {
return nil, err
@ -201,36 +168,14 @@ func NewHttpProxy(opts ...func(*SAMHTTPProxy) error) (*SAMHTTPProxy, error) {
goSam.SetReduceIdle(handler.reduceIdle),
goSam.SetReduceIdleTime(handler.reduceIdleTime),
goSam.SetReduceIdleQuantity(handler.reduceIdleQuantity),
goSam.SetCloseIdle(handler.closeIdle),
goSam.SetCloseIdleTime(handler.closeIdleTime),
goSam.SetCompression(handler.compression),
goSam.SetDebug(handler.debug),
)
if err != nil {
return nil, err
}
handler.samcon, err = sam3.NewSAM(handler.SamHost + ":" + handler.SamPort)
if err != nil {
return nil, err
}
handler.keys, err = handler.samcon.NewKeys()
if err != nil {
return nil, err
}
handler.stream, err = handler.samcon.NewStreamSession("sam-http-connector", handler.keys, handler.sam3Args())
if err != nil {
return nil, err
}
handler.Client = &http.Client{
Transport: &http.Transport{
Dial: handler.gosam.Dial,
MaxIdleConns: 0,
MaxIdleConnsPerHost: 3,
DisableKeepAlives: false,
ResponseHeaderTimeout: time.Second * 600,
ExpectContinueTimeout: time.Second * 600,
IdleConnTimeout: time.Second * 600,
TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper),
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
CheckRedirect: nil,
Timeout: time.Second * 600,
}
handler.Client = handler.freshClient()
return &handler, nil
}