Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

changes to not use headers #3071 #3073

Merged
merged 8 commits into from
Sep 1, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/github.com/getlantern/enproxy/conn_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,17 @@ func (c *conn) doRequest(proxyConn *connInfo, host string, op string, request *r
if request != nil {
body = request.body
}
req, err := c.config.NewRequest(host, "POST", body)
path := c.id + "/" + c.addr + "/" + op
req, err := c.config.NewRequest(host, path, "POST", body)
if err != nil {
err = fmt.Errorf("Unable to construct request to %s via proxy %s: %s", c.addr, host, err)
return
}
req.Header.Set(X_ENPROXY_OP, op)
//req.Header.Set(X_ENPROXY_OP, op)
// Always send our connection id
req.Header.Set(X_ENPROXY_ID, c.id)
//req.Header.Set(X_ENPROXY_ID, c.id)
// Always send the address that we're trying to reach
req.Header.Set(X_ENPROXY_DEST_ADDR, c.addr)
//req.Header.Set(X_ENPROXY_DEST_ADDR, c.addr)
req.Header.Set("Content-type", "application/octet-stream")
if request != nil && request.length > 0 {
// Force identity encoding to appeas CDNs like Fastly that can't
Expand Down
2 changes: 1 addition & 1 deletion src/github.com/getlantern/enproxy/conn_intf.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ type Config struct {
type dialFunc func(addr string) (net.Conn, error)

// newRequestFunc is a function that builds a new request to the upstream proxy
type newRequestFunc func(host string, method string, body io.Reader) (*http.Request, error)
type newRequestFunc func(host, path, method string, body io.Reader) (*http.Request, error)

// rwResponse is a response to a read or write
type rwResponse struct {
Expand Down
4 changes: 2 additions & 2 deletions src/github.com/getlantern/enproxy/conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,8 @@ func prepareConn(addr string, buffered bool, fail bool, t *testing.T, onResponse
})
}

func newRequest(host string, method string, body io.Reader) (req *http.Request, err error) {
return http.NewRequest(method, "http://"+proxyAddr, body)
func newRequest(host, path, method string, body io.Reader) (req *http.Request, err error) {
return http.NewRequest(method, "http://"+proxyAddr+"/"+path+"/", body)
}

func doRequests(conn net.Conn, t *testing.T) {
Expand Down
50 changes: 40 additions & 10 deletions src/github.com/getlantern/enproxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"net"
"net/http"
"regexp"
"strings"
"sync"
"time"
Expand All @@ -15,6 +16,10 @@ const (
DEFAULT_READ_BUFFER_SIZE = 65536
)

var (
r = regexp.MustCompile("/(.*)/(.*)/(.*)/")
)

// Proxy is the server side to an enproxy.Client. Proxy implements the
// http.Handler interface for plugging into an HTTP server, and it also
// provides a convenience ListenAndServe() function for quickly starting up
Expand Down Expand Up @@ -128,6 +133,36 @@ func (p *Proxy) Serve(l net.Listener) error {
return httpServer.Serve(l)
}

func (p *Proxy) parseRequestPath(path string) (string, string, string, error) {
log.Debugf("Path is %v", path)
strs := r.FindStringSubmatch(path)
if len(strs) < 4 {
return "", "", "", fmt.Errorf("Unexpected request path: %v", path)
}
return strs[1], strs[2], strs[3], nil
}

func (p *Proxy) parseRequestProps(req *http.Request) (string, string, string, error) {
// If it's a reasonably long path, it likely follows our new request URI format:
// /X-Enproxy-Id/X-Enproxy-Dest-Addr/X-Enproxy-Op
if len(req.URL.Path) > 5 {
return p.parseRequestPath(req.URL.Path)
}

id := req.Header.Get(X_ENPROXY_ID)
if id == "" {
return "", "", "", fmt.Errorf("No id found in header %s", X_ENPROXY_ID)
}

addr := req.Header.Get(X_ENPROXY_DEST_ADDR)
if addr == "" {
return "", "", "", fmt.Errorf("No address found in header %s", X_ENPROXY_DEST_ADDR)
}

op := req.Header.Get(X_ENPROXY_OP)
return id, addr, op, nil
}

// ServeHTTP: implements the http.Handler interface
func (p *Proxy) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
resp.Header().Set("Lantern-IP", req.Header.Get("X-Forwarded-For"))
Expand All @@ -139,17 +174,13 @@ func (p *Proxy) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
return
}

id := req.Header.Get(X_ENPROXY_ID)
if id == "" {
respond(http.StatusBadRequest, resp, fmt.Sprintf("No id found in header %s", X_ENPROXY_ID))
return
}

addr := req.Header.Get(X_ENPROXY_DEST_ADDR)
if addr == "" {
respond(http.StatusBadRequest, resp, fmt.Sprintf("No address found in header %s", X_ENPROXY_DEST_ADDR))
id, addr, op, er := p.parseRequestProps(req)
if er != nil {
respond(http.StatusBadRequest, resp, er.Error())
log.Errorf("Could not parse enproxy data: %v", er)
return
}
log.Debugf("Parsed enproxy data id: %v, addr: %v, op: %v", id, addr, op)

lc, isNew, err := p.getLazyConn(id, addr, req, resp)
if err != nil {
Expand All @@ -162,7 +193,6 @@ func (p *Proxy) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
return
}

op := req.Header.Get(X_ENPROXY_OP)
if op == OP_WRITE {
p.handleWrite(resp, req, lc, connOut, isNew)
} else if op == OP_READ {
Expand Down
2 changes: 1 addition & 1 deletion src/github.com/getlantern/flashlight/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ func (cfg *Config) applyClientDefaults() {
&client.FrontedServerInfo{
Host: "nl.fallbacks.getiantem.org",
Port: 443,
PoolSize: 30,
PoolSize: 0,
MasqueradeSet: cloudflare,
MaxMasquerades: 20,
QOS: 10,
Expand Down
16 changes: 6 additions & 10 deletions src/github.com/getlantern/flashlight/geolookup/geolookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ package geolookup

import (
"fmt"
"io/ioutil"
"math"
"math/rand"
"net/http"
"net/http/httputil"
"sync"
"sync/atomic"
"time"

"github.com/getlantern/enproxy"
"github.com/getlantern/golog"

"github.com/getlantern/flashlight/pubsub"
Expand Down Expand Up @@ -104,9 +103,6 @@ func lookupIp(httpClient *http.Client) (string, string, error) {
return "", "", fmt.Errorf("Could not create request: %q", err)
}

// Enproxy returns an error if this isn't there.
req.Header.Set(enproxy.X_ENPROXY_ID, "1")

if resp, err = httpClient.Do(req); err != nil {
return "", "", fmt.Errorf("Could not get response from server: %q", err)
}
Expand All @@ -117,12 +113,12 @@ func lookupIp(httpClient *http.Client) (string, string, error) {
}()

if resp.StatusCode != http.StatusOK {
body := "body unreadable"
b, err := ioutil.ReadAll(resp.Body)
if err == nil {
body = string(b)
if full, err := httputil.DumpResponse(resp, true); err != nil {
log.Errorf("Could not read full response %v", err)
} else {
log.Errorf("Unexpected response to geo IP lookup: %v", string(full))
}
return "", "", fmt.Errorf("Unexpected response status %d: %v", resp.StatusCode, body)
return "", "", fmt.Errorf("Unexpected response status %d", resp.StatusCode)
}

ip := resp.Header.Get("Lantern-Ip")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func integrationDialer(t *testing.T, statsFunc func(success bool, domain, addr s
}

return fronted.NewDialer(fronted.Config{
Host: "fallbacks.getiantem.org",
Host: "nodifferencefordirectfronter.org",
Port: 443,
Masquerades: masquerades,
MaxMasquerades: maxMasquerades,
Expand Down
4 changes: 2 additions & 2 deletions src/github.com/getlantern/fronted/dialer.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,12 +237,12 @@ func (d *dialer) NewDirectDomainFronter() *http.Client {
func (d *dialer) enproxyConfigWith(dialProxy func(addr string) (net.Conn, error)) *enproxy.Config {
return &enproxy.Config{
DialProxy: dialProxy,
NewRequest: func(upstreamHost string, method string, body io.Reader) (req *http.Request, err error) {
NewRequest: func(upstreamHost, path, method string, body io.Reader) (req *http.Request, err error) {
if upstreamHost == "" {
// No specific host requested, use configured one
upstreamHost = d.Host
}
return http.NewRequest(method, "http://"+upstreamHost+"/", body)
return http.NewRequest(method, "http://"+upstreamHost+"/"+path+"/", body)
},
BufferRequests: d.BufferRequests,
IdleTimeout: idleTimeout, // TODO: make this configurable
Expand Down
40 changes: 39 additions & 1 deletion src/github.com/getlantern/geolookup/geolookup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,26 @@ import (
"net"
"net/http"
"testing"
"time"

"github.com/getlantern/fronted"
"github.com/getlantern/keyman"
"github.com/getlantern/testify/assert"
)

func TestCityLookup(t *testing.T) {
city, _, err := LookupIPWithClient("198.199.72.101", nil)
d := integrationDialer(t, nil)
defer func() {
if err := d.Close(); err != nil {
t.Fatalf("Unable to close dialer: %v", err)
}
}()

client := d.NewDirectDomainFronter()
city, _, err := LookupIPWithClient("198.199.72.101", client)
if assert.NoError(t, err) {
assert.Equal(t, "New York", city.City.Names["en"])

}
}

Expand All @@ -29,3 +41,29 @@ func TestNonDefaultClient(t *testing.T) {
_, _, err := LookupIPWithClient("", client)
assert.Error(t, err, "Using bad client should have resulted in error")
}

func integrationDialer(t *testing.T, statsFunc func(success bool, domain, addr string, resolutionTime, connectTime, handshakeTime time.Duration)) fronted.Dialer {
rootCAs, err := keyman.PoolContainingCerts("-----BEGIN CERTIFICATE-----\nMIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG\nA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv\nb3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw\nMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i\nYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT\naWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ\njc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp\nxy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp\n1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG\nsnUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ\nU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8\n9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E\nBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B\nAQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz\nyj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE\n38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP\nAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad\nDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME\nHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n-----END CERTIFICATE-----\n")
if err != nil {
t.Fatalf("Unable to set up cert pool")
}

maxMasquerades := 2
masquerades := make([]*fronted.Masquerade, maxMasquerades)
for i := 0; i < len(masquerades); i++ {
// Good masquerade with IP
masquerades[i] = &fronted.Masquerade{
Domain: "10minutemail.com",
IpAddress: "162.159.250.16",
}
}

return fronted.NewDialer(fronted.Config{
Host: "no_difference_with_direct_domain_fronter.org",
Port: 443,
Masquerades: masquerades,
MaxMasquerades: maxMasquerades,
RootCAs: rootCAs,
OnDialStats: statsFunc,
})
}