http_test.go 8.5 KB

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