Example #1
0
func TestFirstHandlerMatches(t *testing.T) {
	client, proxy, l := oneShotProxy(t)
	defer l.Close()

	proxy.OnRequest().DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
		return nil, goproxy.TextResponse(req, "koko")
	})
	proxy.OnRequest().DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
		panic("should never get here, previous response is no null")
		return nil, nil
	})
	if resp := string(getOrFail(srv.URL+"/", client, t)); resp != "koko" {
		t.Error("should return always koko and not", resp)
	}
}
Example #2
0
func TestMitmIsFiltered(t *testing.T) {
	client, proxy, l := oneShotProxy(t)
	defer l.Close()

	//proxy.Verbose = true
	proxy.OnRequest(goproxy.ReqHostIs(https.Listener.Addr().String())).HandleConnect(goproxy.AlwaysMitm)
	proxy.OnRequest(goproxy.UrlIs("/momo")).DoFunc(func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
		return nil, goproxy.TextResponse(req, "koko")
	})

	if resp := string(getOrFail(https.URL+"/momo", client, t)); resp != "koko" {
		t.Error("Proxy should capture /momo to be koko and not", resp)
	}

	if resp := string(getOrFail(https.URL+"/bobo", client, t)); resp != "bobo" {
		t.Error("But still /bobo should be bobo and not", resp)
	}
}
Example #3
0
func main() {
	verbose := flag.Bool("v", false, "should every proxy request be logged to stdout")
	addr := flag.String("addr", ":8080", "proxy listen address")
	java := flag.String("javapath", "java", "where the Java executable is located")
	yuicompressor := flag.String("yuicompressor", "", "where the yuicompressor is located, assumed to be in CWD")
	yuicompressordir := flag.String("yuicompressordir", ".", "a folder to search yuicompressor in, will be ignored if yuicompressor is set")
	flag.Parse()
	if *yuicompressor == "" {
		files, err := ioutil.ReadDir(*yuicompressordir)
		if err != nil {
			log.Fatal("Cannot find yuicompressor jar")
		}
		for _, file := range files {
			if strings.HasPrefix(file.Name(), "yuicompressor") && strings.HasSuffix(file.Name(), ".jar") {
				c := path.Join(*yuicompressordir, file.Name())
				yuicompressor = &c
				break
			}
		}
	}
	if *yuicompressor == "" {
		log.Fatal("Can't find yuicompressor jar, searched yuicompressor*.jar in dir ", *yuicompressordir)
	}
	if _, err := os.Stat(*yuicompressor); os.IsNotExist(err) {
		log.Fatal("Can't find yuicompressor jar specified ", *yuicompressor)
	}
	proxy := goproxy.NewProxyHttpServer()
	proxy.Verbose = *verbose
	proxy.OnResponse().DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
		contentType := resp.Header.Get("Content-Type")
		if contentType == "application/javascript" || contentType == "application/x-javascript" {
			// in real code, response should be streamed as well
			var err error
			cmd := exec.Command(*java, "-jar", *yuicompressor, "--type", "js")
			cmd.Stdin = resp.Body
			resp.Body, err = cmd.StdoutPipe()
			if err != nil {
				ctx.Warnf("Cannot minify content in %v: %v", ctx.Req.URL, err)
				return goproxy.TextResponse(ctx.Req, "Error getting stdout pipe")
			}
			stderr, err := cmd.StderrPipe()
			if err != nil {
				ctx.Logf("Error obtaining stderr from yuicompress: %s", err)
				return goproxy.TextResponse(ctx.Req, "Error getting stderr pipe")
			}
			if err := cmd.Start(); err != nil {
				ctx.Warnf("Cannot minify content in %v: %v", ctx.Req.URL, err)
			}
			go func() {
				defer stderr.Close()
				const kb = 1024
				msg, err := ioutil.ReadAll(&io.LimitedReader{stderr, 50 * kb})
				if len(msg) != 0 {
					ctx.Logf("Error executing yuicompress: %s", string(msg))
				}
				if err != nil {
					ctx.Logf("Error reading stderr from yuicompress: %s", string(msg))
				}
			}()
		}
		return resp
	})
	log.Fatal(http.ListenAndServe(*addr, proxy))
}
Example #4
0
func TestHttpsMitmURLRewrite(t *testing.T) {
	scheme := "https"

	testCases := []struct {
		Host      string
		RawPath   string
		AddOpaque bool
	}{
		{
			Host:      "example.com",
			RawPath:   "/blah/v1/data/realtime",
			AddOpaque: true,
		},
		{
			Host:    "example.com:443",
			RawPath: "/blah/v1/data/realtime?encodedURL=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile",
		},
		{
			Host:    "example.com:443",
			RawPath: "/blah/v1/data/realtime?unencodedURL=https://www.googleapis.com/auth/userinfo.profile",
		},
	}

	for _, tc := range testCases {
		proxy := goproxy.NewProxyHttpServer()
		proxy.OnRequest().HandleConnect(goproxy.AlwaysMitm)

		proxy.OnRequest(goproxy.DstHostIs(tc.Host)).DoFunc(
			func(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
				return nil, goproxy.TextResponse(req, "Dummy response")
			})

		client, s := oneShotProxy(proxy, t)
		defer s.Close()

		fullURL := scheme + "://" + tc.Host + tc.RawPath
		req, err := http.NewRequest("GET", fullURL, nil)
		if err != nil {
			t.Fatal(err)
		}

		if tc.AddOpaque {
			req.URL.Scheme = scheme
			req.URL.Opaque = "//" + tc.Host + tc.RawPath
		}

		resp, err := client.Do(req)

		if err != nil {
			t.Fatal(err)
		}

		b, err := ioutil.ReadAll(resp.Body)
		defer resp.Body.Close()
		if err != nil {
			t.Fatal(err)
		}

		body := string(b)
		if body != "Dummy response" {
			t.Errorf("Expected proxy to return dummy body content but got %s", body)
		}

		if resp.StatusCode != http.StatusAccepted {
			t.Errorf("Expected status: %d, got: %d", http.StatusAccepted, resp.StatusCode)
		}
	}
}