http_test.go 8.6 KB

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