[tor-commits] [meek/master] Make requests through the browser extension.

dcf at torproject.org dcf at torproject.org
Wed Apr 9 05:56:56 UTC 2014


commit 7f449eaa782be553a0be98ef5e6956c8d6d1ffc3
Author: David Fifield <david at bamsoftware.com>
Date:   Tue Mar 18 10:31:07 2014 -0700

    Make requests through the browser extension.
---
 meek-client/meek-client.go |   91 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 90 insertions(+), 1 deletion(-)

diff --git a/meek-client/meek-client.go b/meek-client/meek-client.go
index 94314cf..cfb475f 100644
--- a/meek-client/meek-client.go
+++ b/meek-client/meek-client.go
@@ -4,10 +4,13 @@ import (
 	"bytes"
 	"crypto/rand"
 	"encoding/base64"
+	"encoding/binary"
+	"encoding/json"
 	"errors"
 	"flag"
 	"fmt"
 	"io"
+	"io/ioutil"
 	"log"
 	"net"
 	"net/http"
@@ -26,6 +29,7 @@ const maxPayloadLength = 0x10000
 const initPollInterval = 100 * time.Millisecond
 const maxPollInterval = 5 * time.Second
 const pollIntervalMultiplier = 1.5
+const maxHelperResponseLength = 10000000
 
 var ptInfo pt.ClientInfo
 
@@ -75,8 +79,93 @@ func roundTrip(buf []byte, info *RequestInfo) (*http.Response, error) {
 	return tr.RoundTrip(req)
 }
 
+type JSONRequest struct {
+	Method string            `json:"method,omitempty"`
+	URL    string            `json:"url,omitempty"`
+	Header map[string]string `json:"header,omitempty"`
+	Body   []byte            `json:"body,omitempty"`
+}
+
+type JSONResponse struct {
+	Error  string `json:"error,omitempty"`
+	Status int    `json:"status"`
+	Body   []byte `json:"body"`
+}
+
+// Ask a locally running browser extension to make the request for us.
+func roundTripWithHelper(buf []byte, info *RequestInfo) (*http.Response, error) {
+	s, err := net.Dial("tcp", "127.0.0.1:7000")
+	if err != nil {
+		return nil, err
+	}
+	defer s.Close()
+
+	// Encode our JSON.
+	req := JSONRequest{
+		Method: "POST",
+		URL:    info.URL.String(),
+		Header: make(map[string]string),
+		Body:   buf,
+	}
+	req.Header["X-Session-Id"] = info.SessionID
+	if info.Host != "" {
+		req.Header["Host"] = info.Host
+	}
+	encReq, err := json.Marshal(&req)
+	if err != nil {
+		return nil, err
+	}
+	// log.Printf("encoded %s", encReq)
+
+	// Send the request.
+	err = binary.Write(s, binary.BigEndian, uint32(len(encReq)))
+	if err != nil {
+		return nil, err
+	}
+	_, err = s.Write(encReq)
+	if err != nil {
+		return nil, err
+	}
+
+	// Read the response.
+	var length uint32
+	err = binary.Read(s, binary.BigEndian, &length)
+	if err != nil {
+		return nil, err
+	}
+	if length > maxHelperResponseLength {
+		return nil, errors.New(fmt.Sprintf("helper's returned data is too big (%d > %d)",
+			length, maxHelperResponseLength))
+	}
+	encResp := make([]byte, length)
+	_, err = io.ReadFull(s, encResp)
+	if err != nil {
+		return nil, err
+	}
+	// log.Printf("received %s", encResp)
+
+	// Decode their JSON.
+	var jsonResp JSONResponse
+	err = json.Unmarshal(encResp, &jsonResp)
+	if err != nil {
+		return nil, err
+	}
+	if jsonResp.Error != "" {
+		return nil, errors.New(fmt.Sprintf("helper returned error: %s", jsonResp.Error))
+	}
+
+	// Mock up an HTTP response.
+	resp := http.Response{
+		Status:        http.StatusText(jsonResp.Status),
+		StatusCode:    jsonResp.Status,
+		Body:          ioutil.NopCloser(bytes.NewReader(jsonResp.Body)),
+		ContentLength: int64(len(jsonResp.Body)),
+	}
+	return &resp, nil
+}
+
 func sendRecv(buf []byte, conn net.Conn, info *RequestInfo) (int64, error) {
-	resp, err := roundTrip(buf, info)
+	resp, err := roundTripWithHelper(buf, info)
 	if err != nil {
 		return 0, err
 	}





More information about the tor-commits mailing list