github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/testing/scenarios/http_test.go (about)

     1  package scenarios
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/rand"
     6  	"io"
     7  	"io/ioutil"
     8  	"net/http"
     9  	"net/url"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/google/go-cmp/cmp"
    14  
    15  	"v2ray.com/core"
    16  	"v2ray.com/core/app/proxyman"
    17  	"v2ray.com/core/common"
    18  	"v2ray.com/core/common/buf"
    19  	"v2ray.com/core/common/net"
    20  	"v2ray.com/core/common/serial"
    21  	"v2ray.com/core/proxy/freedom"
    22  	v2http "v2ray.com/core/proxy/http"
    23  	v2httptest "v2ray.com/core/testing/servers/http"
    24  	"v2ray.com/core/testing/servers/tcp"
    25  )
    26  
    27  func TestHttpConformance(t *testing.T) {
    28  	httpServerPort := tcp.PickPort()
    29  	httpServer := &v2httptest.Server{
    30  		Port:        httpServerPort,
    31  		PathHandler: make(map[string]http.HandlerFunc),
    32  	}
    33  	_, err := httpServer.Start()
    34  	common.Must(err)
    35  	defer httpServer.Close()
    36  
    37  	serverPort := tcp.PickPort()
    38  	serverConfig := &core.Config{
    39  		Inbound: []*core.InboundHandlerConfig{
    40  			{
    41  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
    42  					PortRange: net.SinglePortRange(serverPort),
    43  					Listen:    net.NewIPOrDomain(net.LocalHostIP),
    44  				}),
    45  				ProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),
    46  			},
    47  		},
    48  		Outbound: []*core.OutboundHandlerConfig{
    49  			{
    50  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
    51  			},
    52  		},
    53  	}
    54  
    55  	servers, err := InitializeServerConfigs(serverConfig)
    56  	common.Must(err)
    57  	defer CloseAllServers(servers)
    58  
    59  	{
    60  		transport := &http.Transport{
    61  			Proxy: func(req *http.Request) (*url.URL, error) {
    62  				return url.Parse("http://127.0.0.1:" + serverPort.String())
    63  			},
    64  		}
    65  
    66  		client := &http.Client{
    67  			Transport: transport,
    68  		}
    69  
    70  		resp, err := client.Get("http://127.0.0.1:" + httpServerPort.String())
    71  		common.Must(err)
    72  		if resp.StatusCode != 200 {
    73  			t.Fatal("status: ", resp.StatusCode)
    74  		}
    75  
    76  		content, err := ioutil.ReadAll(resp.Body)
    77  		common.Must(err)
    78  		if string(content) != "Home" {
    79  			t.Fatal("body: ", string(content))
    80  		}
    81  	}
    82  }
    83  
    84  func TestHttpError(t *testing.T) {
    85  	tcpServer := tcp.Server{
    86  		MsgProcessor: func(msg []byte) []byte {
    87  			return []byte{}
    88  		},
    89  	}
    90  	dest, err := tcpServer.Start()
    91  	common.Must(err)
    92  	defer tcpServer.Close()
    93  
    94  	time.AfterFunc(time.Second*2, func() {
    95  		tcpServer.ShouldClose = true
    96  	})
    97  
    98  	serverPort := tcp.PickPort()
    99  	serverConfig := &core.Config{
   100  		Inbound: []*core.InboundHandlerConfig{
   101  			{
   102  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   103  					PortRange: net.SinglePortRange(serverPort),
   104  					Listen:    net.NewIPOrDomain(net.LocalHostIP),
   105  				}),
   106  				ProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),
   107  			},
   108  		},
   109  		Outbound: []*core.OutboundHandlerConfig{
   110  			{
   111  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
   112  			},
   113  		},
   114  	}
   115  
   116  	servers, err := InitializeServerConfigs(serverConfig)
   117  	common.Must(err)
   118  	defer CloseAllServers(servers)
   119  
   120  	{
   121  		transport := &http.Transport{
   122  			Proxy: func(req *http.Request) (*url.URL, error) {
   123  				return url.Parse("http://127.0.0.1:" + serverPort.String())
   124  			},
   125  		}
   126  
   127  		client := &http.Client{
   128  			Transport: transport,
   129  		}
   130  
   131  		resp, err := client.Get("http://127.0.0.1:" + dest.Port.String())
   132  		common.Must(err)
   133  		if resp.StatusCode != 503 {
   134  			t.Error("status: ", resp.StatusCode)
   135  		}
   136  	}
   137  }
   138  
   139  func TestHttpConnectMethod(t *testing.T) {
   140  	tcpServer := tcp.Server{
   141  		MsgProcessor: xor,
   142  	}
   143  	dest, err := tcpServer.Start()
   144  	common.Must(err)
   145  	defer tcpServer.Close()
   146  
   147  	serverPort := tcp.PickPort()
   148  	serverConfig := &core.Config{
   149  		Inbound: []*core.InboundHandlerConfig{
   150  			{
   151  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   152  					PortRange: net.SinglePortRange(serverPort),
   153  					Listen:    net.NewIPOrDomain(net.LocalHostIP),
   154  				}),
   155  				ProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),
   156  			},
   157  		},
   158  		Outbound: []*core.OutboundHandlerConfig{
   159  			{
   160  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
   161  			},
   162  		},
   163  	}
   164  
   165  	servers, err := InitializeServerConfigs(serverConfig)
   166  	common.Must(err)
   167  	defer CloseAllServers(servers)
   168  
   169  	{
   170  		transport := &http.Transport{
   171  			Proxy: func(req *http.Request) (*url.URL, error) {
   172  				return url.Parse("http://127.0.0.1:" + serverPort.String())
   173  			},
   174  		}
   175  
   176  		client := &http.Client{
   177  			Transport: transport,
   178  		}
   179  
   180  		payload := make([]byte, 1024*64)
   181  		common.Must2(rand.Read(payload))
   182  		req, err := http.NewRequest("Connect", "http://"+dest.NetAddr()+"/", bytes.NewReader(payload))
   183  		req.Header.Set("X-a", "b")
   184  		req.Header.Set("X-b", "d")
   185  		common.Must(err)
   186  
   187  		resp, err := client.Do(req)
   188  		common.Must(err)
   189  		if resp.StatusCode != 200 {
   190  			t.Fatal("status: ", resp.StatusCode)
   191  		}
   192  
   193  		content := make([]byte, len(payload))
   194  		common.Must2(io.ReadFull(resp.Body, content))
   195  		if r := cmp.Diff(content, xor(payload)); r != "" {
   196  			t.Fatal(r)
   197  		}
   198  	}
   199  }
   200  
   201  func TestHttpPost(t *testing.T) {
   202  	httpServerPort := tcp.PickPort()
   203  	httpServer := &v2httptest.Server{
   204  		Port: httpServerPort,
   205  		PathHandler: map[string]http.HandlerFunc{
   206  			"/testpost": func(w http.ResponseWriter, r *http.Request) {
   207  				payload, err := buf.ReadAllToBytes(r.Body)
   208  				r.Body.Close()
   209  
   210  				if err != nil {
   211  					w.WriteHeader(500)
   212  					w.Write([]byte("Unable to read all payload"))
   213  					return
   214  				}
   215  				payload = xor(payload)
   216  				w.Write(payload)
   217  			},
   218  		},
   219  	}
   220  
   221  	_, err := httpServer.Start()
   222  	common.Must(err)
   223  	defer httpServer.Close()
   224  
   225  	serverPort := tcp.PickPort()
   226  	serverConfig := &core.Config{
   227  		Inbound: []*core.InboundHandlerConfig{
   228  			{
   229  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   230  					PortRange: net.SinglePortRange(serverPort),
   231  					Listen:    net.NewIPOrDomain(net.LocalHostIP),
   232  				}),
   233  				ProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),
   234  			},
   235  		},
   236  		Outbound: []*core.OutboundHandlerConfig{
   237  			{
   238  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
   239  			},
   240  		},
   241  	}
   242  
   243  	servers, err := InitializeServerConfigs(serverConfig)
   244  	common.Must(err)
   245  	defer CloseAllServers(servers)
   246  
   247  	{
   248  		transport := &http.Transport{
   249  			Proxy: func(req *http.Request) (*url.URL, error) {
   250  				return url.Parse("http://127.0.0.1:" + serverPort.String())
   251  			},
   252  		}
   253  
   254  		client := &http.Client{
   255  			Transport: transport,
   256  		}
   257  
   258  		payload := make([]byte, 1024*64)
   259  		common.Must2(rand.Read(payload))
   260  
   261  		resp, err := client.Post("http://127.0.0.1:"+httpServerPort.String()+"/testpost", "application/x-www-form-urlencoded", bytes.NewReader(payload))
   262  		common.Must(err)
   263  		if resp.StatusCode != 200 {
   264  			t.Fatal("status: ", resp.StatusCode)
   265  		}
   266  
   267  		content, err := ioutil.ReadAll(resp.Body)
   268  		common.Must(err)
   269  		if r := cmp.Diff(content, xor(payload)); r != "" {
   270  			t.Fatal(r)
   271  		}
   272  	}
   273  }
   274  
   275  func setProxyBasicAuth(req *http.Request, user, pass string) {
   276  	req.SetBasicAuth(user, pass)
   277  	req.Header.Set("Proxy-Authorization", req.Header.Get("Authorization"))
   278  	req.Header.Del("Authorization")
   279  }
   280  
   281  func TestHttpBasicAuth(t *testing.T) {
   282  	httpServerPort := tcp.PickPort()
   283  	httpServer := &v2httptest.Server{
   284  		Port:        httpServerPort,
   285  		PathHandler: make(map[string]http.HandlerFunc),
   286  	}
   287  	_, err := httpServer.Start()
   288  	common.Must(err)
   289  	defer httpServer.Close()
   290  
   291  	serverPort := tcp.PickPort()
   292  	serverConfig := &core.Config{
   293  		Inbound: []*core.InboundHandlerConfig{
   294  			{
   295  				ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
   296  					PortRange: net.SinglePortRange(serverPort),
   297  					Listen:    net.NewIPOrDomain(net.LocalHostIP),
   298  				}),
   299  				ProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{
   300  					Accounts: map[string]string{
   301  						"a": "b",
   302  					},
   303  				}),
   304  			},
   305  		},
   306  		Outbound: []*core.OutboundHandlerConfig{
   307  			{
   308  				ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
   309  			},
   310  		},
   311  	}
   312  
   313  	servers, err := InitializeServerConfigs(serverConfig)
   314  	common.Must(err)
   315  	defer CloseAllServers(servers)
   316  
   317  	{
   318  		transport := &http.Transport{
   319  			Proxy: func(req *http.Request) (*url.URL, error) {
   320  				return url.Parse("http://127.0.0.1:" + serverPort.String())
   321  			},
   322  		}
   323  
   324  		client := &http.Client{
   325  			Transport: transport,
   326  		}
   327  
   328  		{
   329  			resp, err := client.Get("http://127.0.0.1:" + httpServerPort.String())
   330  			common.Must(err)
   331  			if resp.StatusCode != 407 {
   332  				t.Fatal("status: ", resp.StatusCode)
   333  			}
   334  		}
   335  
   336  		{
   337  			req, err := http.NewRequest("GET", "http://127.0.0.1:"+httpServerPort.String(), nil)
   338  			common.Must(err)
   339  
   340  			setProxyBasicAuth(req, "a", "c")
   341  			resp, err := client.Do(req)
   342  			common.Must(err)
   343  			if resp.StatusCode != 407 {
   344  				t.Fatal("status: ", resp.StatusCode)
   345  			}
   346  		}
   347  
   348  		{
   349  			req, err := http.NewRequest("GET", "http://127.0.0.1:"+httpServerPort.String(), nil)
   350  			common.Must(err)
   351  
   352  			setProxyBasicAuth(req, "a", "b")
   353  			resp, err := client.Do(req)
   354  			common.Must(err)
   355  			if resp.StatusCode != 200 {
   356  				t.Fatal("status: ", resp.StatusCode)
   357  			}
   358  
   359  			content, err := ioutil.ReadAll(resp.Body)
   360  			common.Must(err)
   361  			if string(content) != "Home" {
   362  				t.Fatal("body: ", string(content))
   363  			}
   364  		}
   365  	}
   366  }