commit 8aad9f71207cd878a55f3e4046b9716386858025 Author: David Fifield david@bamsoftware.com Date: Sat Mar 30 13:29:22 2019 -0600
Refactoring WebExtension native component.
The native component actually doesn't need to introspect the objects it passes to the browser, except for the "error" property of a response when it wants to report its own error. --- webextension/native/main.go | 58 +++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 36 deletions(-)
diff --git a/webextension/native/main.go b/webextension/native/main.go index 3f4ec3a..d889e9c 100644 --- a/webextension/native/main.go +++ b/webextension/native/main.go @@ -36,7 +36,7 @@ const ( roundTripTimeout = 120 * time.Second
// Self-defense against a malfunctioning meek-client. We'll refuse to - // read encoded responses that are longer than this. + // read encoded requests that are longer than this. maxRequestSpecLength = 1000000
// Self-defense against a malfunctioning browser. We'll refuse to @@ -52,32 +52,16 @@ const ( // inFromBrowserLoop receives a webExtensionRoundTripResponse from the browser, // it is tagged with the same ID as the corresponding request. inFromBrowserLoop // looks up the matching channel and sends the response over it. -var requestResponseMap = make(map[string]chan<- *responseSpec) +var requestResponseMap = make(map[string]chan<- responseSpec) var requestResponseMapLock sync.Mutex
// A specification of an HTTP request, as received via the socket from // "meek-client --helper". -type requestSpec struct { - Method string `json:"method,omitempty"` - URL string `json:"url,omitempty"` - Header map[string]string `json:"header,omitempty"` - Body []byte `json:"body,omitempty"` - Proxy *proxySpec `json:"proxy,omitempty"` -} - -type proxySpec struct { - Type string `json:"type"` - Host string `json:"host"` - Port int `json:"port"` -} +type requestSpec interface{}
// A specification of an HTTP request or an error, as sent via the socket to // "meek-client --helper". -type responseSpec struct { - Error string `json:"error,omitempty"` - Status int `json:"status,omitempty"` - Body []byte `json:"body,omitempty"` -} +type responseSpec interface{}
// A "roundtrip" command sent out to the browser over the stdout stream. It // encapsulates a requestSpec as received from the socket, plus @@ -87,17 +71,17 @@ type responseSpec struct { // command:"roundtrip" is to disambiguate with the other command we may send, // "report-address". type webExtensionRoundTripRequest struct { - Command string `json:"command"` // "roundtrip" - ID string `json:"id"` - Request *requestSpec `json:"request"` + Command string `json:"command"` // "roundtrip" + ID string `json:"id"` + Request requestSpec `json:"request"` }
// A message received from the the browser over the stdin stream. It // encapsulates a responseSpec along with the ID of the webExtensionResponse // that resulted in this response. type webExtensionRoundTripResponse struct { - ID string `json:"id"` - Response *responseSpec `json:"response"` + ID string `json:"id"` + Response responseSpec `json:"response"` }
// Read a requestSpec (receive from "meek-client --helper"). @@ -106,7 +90,7 @@ type webExtensionRoundTripResponse struct { // protocol: a 4-byte length, followed by a JSON object of that length. The only // difference is the byte order of the length: meek-client's is big-endian, // while WebExtension's is native-endian. -func readRequestSpec(r io.Reader) (*requestSpec, error) { +func readRequestSpec(r io.Reader) (requestSpec, error) { var length uint32 err := binary.Read(r, binary.BigEndian, &length) if err != nil { @@ -132,7 +116,7 @@ func readRequestSpec(r io.Reader) (*requestSpec, error) { }
// Write a responseSpec (send to "meek-client --helper"). -func writeResponseSpec(w io.Writer, spec *responseSpec) error { +func writeResponseSpec(w io.Writer, spec responseSpec) error { encodedSpec, err := json.Marshal(spec) if err != nil { panic(err) @@ -148,11 +132,7 @@ func writeResponseSpec(w io.Writer, spec *responseSpec) error { }
_, err = w.Write(encodedSpec) - if err != nil { - return err - } - - return nil + return err }
// Receive a WebExtension message. @@ -195,7 +175,7 @@ func sendWebExtensionMessage(w io.Writer, message []byte) error { // browser. Wait for the browser to send back a webExtensionRoundTripResponse // (which actually happens in inFromBrowserLoop--that function uses the ID to // find this goroutine again). Return a responseSpec object or an error. -func roundTrip(conn net.Conn, outToBrowserChan chan<- []byte) (*responseSpec, error) { +func roundTrip(conn net.Conn, outToBrowserChan chan<- []byte) (responseSpec, error) { err := conn.SetReadDeadline(time.Now().Add(localReadTimeout)) if err != nil { return nil, err @@ -216,7 +196,7 @@ func roundTrip(conn net.Conn, outToBrowserChan chan<- []byte) (*responseSpec, er // This is the channel over which inFromBrowserLoop will send the // response. Register it in requestResponseMap to enable // inFromBrowserLoop to match the corresponding response to it. - responseSpecChan := make(chan *responseSpec) + responseSpecChan := make(chan responseSpec) requestResponseMapLock.Lock() requestResponseMap[id] = responseSpecChan requestResponseMapLock.Unlock() @@ -235,7 +215,7 @@ func roundTrip(conn net.Conn, outToBrowserChan chan<- []byte) (*responseSpec, er // Now wait for the browser to send the response back to us. // inFromBrowserLoop will find the proper channel by looking up the ID // in requestResponseMap. - var resp *responseSpec + var resp responseSpec timeout := time.NewTimer(roundTripTimeout) select { case resp = <-responseSpecChan: @@ -251,6 +231,12 @@ func roundTrip(conn net.Conn, outToBrowserChan chan<- []byte) (*responseSpec, er return resp, err }
+// This is a responseSpec for errors that originate inside this program, as +// opposed to being relayed from the browser. +type errorResponseSpec struct { + Error string `json:"error"` +} + // Handle a socket connection, which is used for one request–response roundtrip // through the browser. Delegates the real work to roundTrip, which reads the // requestSpec from the socket and sends it through the browser. Here, we wrap @@ -261,7 +247,7 @@ func handleConn(conn net.Conn, outToBrowserChan chan<- []byte) error {
resp, err := roundTrip(conn, outToBrowserChan) if err != nil { - resp = &responseSpec{Error: err.Error()} + resp = &errorResponseSpec{Error: err.Error()} }
// Encode the response send it back out over the socket.
tor-commits@lists.torproject.org