[tor-commits] [meek/master] Add some proxy support functions.
dcf at torproject.org
dcf at torproject.org
Wed May 28 07:03:21 UTC 2014
commit daab1193f4234bd23e26f7a525356b67630c6ba2
Author: David Fifield <david at 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)
+ }
+ }
+}
More information about the tor-commits
mailing list