commit daab1193f4234bd23e26f7a525356b67630c6ba2
Author: David Fifield <da...@bamsoftware.com>
Date:   Sat May 24 20:25:49 2014 -0700

    Add some proxy support functions.
    
    These are candidates to move to goptlib for proposal 232 support.
    
    I assumed that you should be able to give a proxy host as a domain name,
    but it turns out that proposal 232 doesn't actually say that
    (https://trac.torproject.org/projects/tor/ticket/12125#comment:3). Some
    of the tests use IP addresses and some use host names.
---
 meek-client/proxy.go      |   53 ++++++++++++++++++++++++++++++++++
 meek-client/proxy_test.go |   69 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 122 insertions(+)

diff --git a/meek-client/proxy.go b/meek-client/proxy.go
new file mode 100644
index 0000000..56717a3
--- /dev/null
+++ b/meek-client/proxy.go
@@ -0,0 +1,53 @@
+package main
+
+import (
+       "errors"
+       "fmt"
+       "net/url"
+       "os"
+)
+
+import "git.torproject.org/pluggable-transports/goptlib.git"
+
+// The code in this file has to do with configuring an upstream proxy, whether
+// through the command line or the managed interface of proposal 232
+// (TOR_PT_PROXY).
+//
+// 
https://gitweb.torproject.org/torspec.git/blob/HEAD:/proposals/232-pluggable-transports-through-proxy.txt
+
+// Get the upstream proxy URL. Returns nil if no proxy is requested. The
+// function ensures that the Scheme and Host fields are set; i.e., that the URL
+// is absolute. This function reads the environment variable TOR_PT_PROXY.
+//
+// This function doesn't check that the scheme is one of Tor's supported proxy
+// schemes; that is, one of "http", "socks5", or "socks4a". The caller must be
+// able to handle any returned scheme (which may be by calling PtProxyError if
+// it doesn't know how to handle the scheme).
+func PtGetProxyURL() (*url.URL, error) {
+       rawurl := os.Getenv("TOR_PT_PROXY")
+       if rawurl == "" {
+               return nil, nil
+       }
+       u, err := url.Parse(rawurl)
+       if err != nil {
+               return nil, err
+       }
+       if u.Scheme == "" {
+               return nil, errors.New("missing scheme")
+       }
+       if u.Host == "" {
+               return nil, errors.New("missing host")
+       }
+       return u, nil
+}
+
+// Emit a PROXY-ERROR line with explanation text.
+func PtProxyError(msg string) {
+       fmt.Fprintf(pt.Stdout, "PROXY-ERROR %s\n", msg)
+}
+
+// Emit a PROXY DONE line. Call this after parsing the return value of
+// PtGetProxyURL.
+func PtProxyDone() {
+       fmt.Fprintf(pt.Stdout, "PROXY DONE\n")
+}
diff --git a/meek-client/proxy_test.go b/meek-client/proxy_test.go
new file mode 100644
index 0000000..9565101
--- /dev/null
+++ b/meek-client/proxy_test.go
@@ -0,0 +1,69 @@
+package main
+
+import (
+       "os"
+       "testing"
+)
+
+func TestGetProxyURL(t *testing.T) {
+       badTests := [...]string{
+               "bogus",
+               "http:",
+               "://127.0.0.1",
+               "//127.0.0.1",
+               "http:127.0.0.1",
+               "://[::1]",
+               "//[::1]",
+               "http:[::1]",
+               "://localhost",
+               "//localhost",
+               "http:localhost",
+       }
+       goodTests := [...]struct {
+               input, expected string
+       }{
+               {"http://127.0.0.1";, "http://127.0.0.1"},
+               {"http://127.0.0.1:8080";, "http://127.0.0.1:8080"},
+               {"http://127.0.0.1:8080/";, "http://127.0.0.1:8080/"},
+               {"http://127.0.0.1:8080/path";, "http://127.0.0.1:8080/path"},
+               {"http://[::1]";, "http://[::1]"},
+               {"http://[::1]:8080";, "http://[::1]:8080"},
+               {"http://[::1]:8080/";, "http://[::1]:8080/"},
+               {"http://[::1]:8080/path";, "http://[::1]:8080/path"},
+               {"http://localhost";, "http://localhost"},
+               {"http://localhost:8080";, "http://localhost:8080"},
+               {"http://localhost:8080/";, "http://localhost:8080/"},
+               {"http://localhost:8080/path";, "http://localhost:8080/path"},
+               {"http://user@localhost:8080";, "http://user@localhost:8080"},
+               {"http://user:password@localhost:8080";, 
"http://user:password@localhost:8080"},
+               {"unknown://localhost/whatever", 
"unknown://localhost/whatever"},
+       }
+
+       os.Clearenv()
+       u, err := PtGetProxyURL()
+       if err != nil {
+               t.Errorf("empty environment unexpectedly returned an error: 
%s", err)
+       }
+       if u != nil {
+               t.Errorf("empty environment returned %q", u)
+       }
+
+       for _, input := range badTests {
+               os.Setenv("TOR_PT_PROXY", input)
+               u, err = PtGetProxyURL()
+               if err == nil {
+                       t.Errorf("TOR_PT_PROXY=%q unexpectedly succeeded and 
returned %q", input, u)
+               }
+       }
+
+       for _, test := range goodTests {
+               os.Setenv("TOR_PT_PROXY", test.input)
+               u, err := PtGetProxyURL()
+               if err != nil {
+                       t.Errorf("TOR_PT_PROXY=%q unexpectedly returned an 
error: %s", test.input, err)
+               }
+               if u == nil || u.String() != test.expected {
+                       t.Errorf("TOR_PT_PROXY=%q → %q (expected %q)", 
test.input, u, test.expected)
+               }
+       }
+}



_______________________________________________
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits

Reply via email to