1*1274Szelenkov@nginx.comimport re 2*1274Szelenkov@nginx.comimport time 3*1274Szelenkov@nginx.comimport socket 4*1274Szelenkov@nginx.comimport unittest 5*1274Szelenkov@nginx.comfrom unit.applications.lang.python import TestApplicationPython 6*1274Szelenkov@nginx.com 7*1274Szelenkov@nginx.com 8*1274Szelenkov@nginx.comclass TestProxy(TestApplicationPython): 9*1274Szelenkov@nginx.com prerequisites = {'modules': ['python']} 10*1274Szelenkov@nginx.com 11*1274Szelenkov@nginx.com SERVER_PORT = 7999 12*1274Szelenkov@nginx.com 13*1274Szelenkov@nginx.com def run_server(self): 14*1274Szelenkov@nginx.com sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 15*1274Szelenkov@nginx.com sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 16*1274Szelenkov@nginx.com 17*1274Szelenkov@nginx.com server_address = ('', self.SERVER_PORT) 18*1274Szelenkov@nginx.com sock.bind(server_address) 19*1274Szelenkov@nginx.com sock.listen(5) 20*1274Szelenkov@nginx.com 21*1274Szelenkov@nginx.com def recvall(sock): 22*1274Szelenkov@nginx.com buff_size = 4096 23*1274Szelenkov@nginx.com data = b'' 24*1274Szelenkov@nginx.com while True: 25*1274Szelenkov@nginx.com part = sock.recv(buff_size) 26*1274Szelenkov@nginx.com data += part 27*1274Szelenkov@nginx.com if len(part) < buff_size: 28*1274Szelenkov@nginx.com break 29*1274Szelenkov@nginx.com return data 30*1274Szelenkov@nginx.com 31*1274Szelenkov@nginx.com req = b"""HTTP/1.1 200 OK 32*1274Szelenkov@nginx.comContent-Length: 10 33*1274Szelenkov@nginx.com 34*1274Szelenkov@nginx.com""" 35*1274Szelenkov@nginx.com 36*1274Szelenkov@nginx.com while True: 37*1274Szelenkov@nginx.com connection, client_address = sock.accept() 38*1274Szelenkov@nginx.com 39*1274Szelenkov@nginx.com data = recvall(connection).decode() 40*1274Szelenkov@nginx.com 41*1274Szelenkov@nginx.com to_send = req 42*1274Szelenkov@nginx.com 43*1274Szelenkov@nginx.com m = re.search('X-Len: (\d+)', data) 44*1274Szelenkov@nginx.com if m: 45*1274Szelenkov@nginx.com to_send += b'X' * int(m.group(1)) 46*1274Szelenkov@nginx.com 47*1274Szelenkov@nginx.com connection.sendall(to_send) 48*1274Szelenkov@nginx.com 49*1274Szelenkov@nginx.com connection.close() 50*1274Szelenkov@nginx.com 51*1274Szelenkov@nginx.com def get_http10(self, *args, **kwargs): 52*1274Szelenkov@nginx.com return self.get(*args, http_10=True, **kwargs) 53*1274Szelenkov@nginx.com 54*1274Szelenkov@nginx.com def post_http10(self, *args, **kwargs): 55*1274Szelenkov@nginx.com return self.post(*args, http_10=True, **kwargs) 56*1274Szelenkov@nginx.com 57*1274Szelenkov@nginx.com def setUp(self): 58*1274Szelenkov@nginx.com super().setUp() 59*1274Szelenkov@nginx.com 60*1274Szelenkov@nginx.com self.run_process(self.run_server) 61*1274Szelenkov@nginx.com self.waitforsocket(self.SERVER_PORT) 62*1274Szelenkov@nginx.com 63*1274Szelenkov@nginx.com self.assertIn( 64*1274Szelenkov@nginx.com 'success', 65*1274Szelenkov@nginx.com self.conf( 66*1274Szelenkov@nginx.com { 67*1274Szelenkov@nginx.com "listeners": { 68*1274Szelenkov@nginx.com "*:7080": {"pass": "routes"}, 69*1274Szelenkov@nginx.com "*:7081": {"pass": "applications/mirror"}, 70*1274Szelenkov@nginx.com }, 71*1274Szelenkov@nginx.com "routes": [{"action": {"proxy": "http://127.0.0.1:7081"}}], 72*1274Szelenkov@nginx.com "applications": { 73*1274Szelenkov@nginx.com "mirror": { 74*1274Szelenkov@nginx.com "type": "python", 75*1274Szelenkov@nginx.com "processes": {"spare": 0}, 76*1274Szelenkov@nginx.com "path": self.current_dir + "/python/mirror", 77*1274Szelenkov@nginx.com "working_directory": self.current_dir 78*1274Szelenkov@nginx.com + "/python/mirror", 79*1274Szelenkov@nginx.com "module": "wsgi", 80*1274Szelenkov@nginx.com }, 81*1274Szelenkov@nginx.com "custom_header": { 82*1274Szelenkov@nginx.com "type": "python", 83*1274Szelenkov@nginx.com "processes": {"spare": 0}, 84*1274Szelenkov@nginx.com "path": self.current_dir + "/python/custom_header", 85*1274Szelenkov@nginx.com "working_directory": self.current_dir 86*1274Szelenkov@nginx.com + "/python/custom_header", 87*1274Szelenkov@nginx.com "module": "wsgi", 88*1274Szelenkov@nginx.com }, 89*1274Szelenkov@nginx.com "delayed": { 90*1274Szelenkov@nginx.com "type": "python", 91*1274Szelenkov@nginx.com "processes": {"spare": 0}, 92*1274Szelenkov@nginx.com "path": self.current_dir + "/python/delayed", 93*1274Szelenkov@nginx.com "working_directory": self.current_dir 94*1274Szelenkov@nginx.com + "/python/delayed", 95*1274Szelenkov@nginx.com "module": "wsgi", 96*1274Szelenkov@nginx.com }, 97*1274Szelenkov@nginx.com }, 98*1274Szelenkov@nginx.com } 99*1274Szelenkov@nginx.com ), 100*1274Szelenkov@nginx.com 'proxy initial configuration', 101*1274Szelenkov@nginx.com ) 102*1274Szelenkov@nginx.com 103*1274Szelenkov@nginx.com def test_proxy_http10(self): 104*1274Szelenkov@nginx.com for _ in range(10): 105*1274Szelenkov@nginx.com self.assertEqual(self.get_http10()['status'], 200, 'status') 106*1274Szelenkov@nginx.com 107*1274Szelenkov@nginx.com def test_proxy_chain(self): 108*1274Szelenkov@nginx.com self.assertIn( 109*1274Szelenkov@nginx.com 'success', 110*1274Szelenkov@nginx.com self.conf( 111*1274Szelenkov@nginx.com { 112*1274Szelenkov@nginx.com "listeners": { 113*1274Szelenkov@nginx.com "*:7080": {"pass": "routes/first"}, 114*1274Szelenkov@nginx.com "*:7081": {"pass": "routes/second"}, 115*1274Szelenkov@nginx.com "*:7082": {"pass": "routes/third"}, 116*1274Szelenkov@nginx.com "*:7083": {"pass": "routes/fourth"}, 117*1274Szelenkov@nginx.com "*:7084": {"pass": "routes/fifth"}, 118*1274Szelenkov@nginx.com "*:7085": {"pass": "applications/mirror"}, 119*1274Szelenkov@nginx.com }, 120*1274Szelenkov@nginx.com "routes": { 121*1274Szelenkov@nginx.com "first": [ 122*1274Szelenkov@nginx.com {"action": {"proxy": "http://127.0.0.1:7081"}} 123*1274Szelenkov@nginx.com ], 124*1274Szelenkov@nginx.com "second": [ 125*1274Szelenkov@nginx.com {"action": {"proxy": "http://127.0.0.1:7082"}} 126*1274Szelenkov@nginx.com ], 127*1274Szelenkov@nginx.com "third": [ 128*1274Szelenkov@nginx.com {"action": {"proxy": "http://127.0.0.1:7083"}} 129*1274Szelenkov@nginx.com ], 130*1274Szelenkov@nginx.com "fourth": [ 131*1274Szelenkov@nginx.com {"action": {"proxy": "http://127.0.0.1:7084"}} 132*1274Szelenkov@nginx.com ], 133*1274Szelenkov@nginx.com "fifth": [ 134*1274Szelenkov@nginx.com {"action": {"proxy": "http://127.0.0.1:7085"}} 135*1274Szelenkov@nginx.com ], 136*1274Szelenkov@nginx.com }, 137*1274Szelenkov@nginx.com "applications": { 138*1274Szelenkov@nginx.com "mirror": { 139*1274Szelenkov@nginx.com "type": "python", 140*1274Szelenkov@nginx.com "processes": {"spare": 0}, 141*1274Szelenkov@nginx.com "path": self.current_dir + "/python/mirror", 142*1274Szelenkov@nginx.com "working_directory": self.current_dir 143*1274Szelenkov@nginx.com + "/python/mirror", 144*1274Szelenkov@nginx.com "module": "wsgi", 145*1274Szelenkov@nginx.com } 146*1274Szelenkov@nginx.com }, 147*1274Szelenkov@nginx.com } 148*1274Szelenkov@nginx.com ), 149*1274Szelenkov@nginx.com 'proxy chain configuration', 150*1274Szelenkov@nginx.com ) 151*1274Szelenkov@nginx.com 152*1274Szelenkov@nginx.com self.assertEqual(self.get_http10()['status'], 200, 'status') 153*1274Szelenkov@nginx.com 154*1274Szelenkov@nginx.com def test_proxy_body(self): 155*1274Szelenkov@nginx.com payload = '0123456789' 156*1274Szelenkov@nginx.com for _ in range(10): 157*1274Szelenkov@nginx.com resp = self.post_http10(body=payload) 158*1274Szelenkov@nginx.com 159*1274Szelenkov@nginx.com self.assertEqual(resp['status'], 200, 'status') 160*1274Szelenkov@nginx.com self.assertEqual(resp['body'], payload, 'body') 161*1274Szelenkov@nginx.com 162*1274Szelenkov@nginx.com payload = 'X' * 4096 163*1274Szelenkov@nginx.com for _ in range(10): 164*1274Szelenkov@nginx.com resp = self.post_http10(body=payload) 165*1274Szelenkov@nginx.com 166*1274Szelenkov@nginx.com self.assertEqual(resp['status'], 200, 'status') 167*1274Szelenkov@nginx.com self.assertEqual(resp['body'], payload, 'body') 168*1274Szelenkov@nginx.com 169*1274Szelenkov@nginx.com payload = 'X' * 4097 170*1274Szelenkov@nginx.com for _ in range(10): 171*1274Szelenkov@nginx.com resp = self.post_http10(body=payload) 172*1274Szelenkov@nginx.com 173*1274Szelenkov@nginx.com self.assertEqual(resp['status'], 200, 'status') 174*1274Szelenkov@nginx.com self.assertEqual(resp['body'], payload, 'body') 175*1274Szelenkov@nginx.com 176*1274Szelenkov@nginx.com payload = 'X' * 4096 * 256 177*1274Szelenkov@nginx.com for _ in range(10): 178*1274Szelenkov@nginx.com resp = self.post_http10(body=payload, read_buffer_size=4096 * 128) 179*1274Szelenkov@nginx.com 180*1274Szelenkov@nginx.com self.assertEqual(resp['status'], 200, 'status') 181*1274Szelenkov@nginx.com self.assertEqual(resp['body'], payload, 'body') 182*1274Szelenkov@nginx.com 183*1274Szelenkov@nginx.com payload = 'X' * 4096 * 257 184*1274Szelenkov@nginx.com for _ in range(10): 185*1274Szelenkov@nginx.com resp = self.post_http10(body=payload, read_buffer_size=4096 * 128) 186*1274Szelenkov@nginx.com 187*1274Szelenkov@nginx.com self.assertEqual(resp['status'], 200, 'status') 188*1274Szelenkov@nginx.com self.assertEqual(resp['body'], payload, 'body') 189*1274Szelenkov@nginx.com 190*1274Szelenkov@nginx.com def test_proxy_parallel(self): 191*1274Szelenkov@nginx.com payload = 'X' * 4096 * 257 192*1274Szelenkov@nginx.com buff_size = 4096 * 258 193*1274Szelenkov@nginx.com 194*1274Szelenkov@nginx.com socks = [] 195*1274Szelenkov@nginx.com for i in range(10): 196*1274Szelenkov@nginx.com _, sock = self.post_http10( 197*1274Szelenkov@nginx.com body=payload + str(i), 198*1274Szelenkov@nginx.com start=True, 199*1274Szelenkov@nginx.com no_recv=True, 200*1274Szelenkov@nginx.com read_buffer_size=buff_size, 201*1274Szelenkov@nginx.com ) 202*1274Szelenkov@nginx.com socks.append(sock) 203*1274Szelenkov@nginx.com 204*1274Szelenkov@nginx.com for i in range(10): 205*1274Szelenkov@nginx.com resp = self.recvall(socks[i], buff_size=buff_size).decode() 206*1274Szelenkov@nginx.com socks[i].close() 207*1274Szelenkov@nginx.com 208*1274Szelenkov@nginx.com resp = self._resp_to_dict(resp) 209*1274Szelenkov@nginx.com 210*1274Szelenkov@nginx.com self.assertEqual(resp['status'], 200, 'status') 211*1274Szelenkov@nginx.com self.assertEqual(resp['body'], payload + str(i), 'body') 212*1274Szelenkov@nginx.com 213*1274Szelenkov@nginx.com def test_proxy_header(self): 214*1274Szelenkov@nginx.com self.assertIn( 215*1274Szelenkov@nginx.com 'success', 216*1274Szelenkov@nginx.com self.conf( 217*1274Szelenkov@nginx.com {"pass": "applications/custom_header"}, 'listeners/*:7081' 218*1274Szelenkov@nginx.com ), 219*1274Szelenkov@nginx.com 'custom_header configure', 220*1274Szelenkov@nginx.com ) 221*1274Szelenkov@nginx.com 222*1274Szelenkov@nginx.com header_value = 'blah' 223*1274Szelenkov@nginx.com self.assertEqual( 224*1274Szelenkov@nginx.com self.get_http10( 225*1274Szelenkov@nginx.com headers={'Host': 'localhost', 'Custom-Header': header_value} 226*1274Szelenkov@nginx.com )['headers']['Custom-Header'], 227*1274Szelenkov@nginx.com header_value, 228*1274Szelenkov@nginx.com 'custom header', 229*1274Szelenkov@nginx.com ) 230*1274Szelenkov@nginx.com 231*1274Szelenkov@nginx.com header_value = '(),/:;<=>?@[\]{}\t !#$%&\'*+-.^_`|~' 232*1274Szelenkov@nginx.com self.assertEqual( 233*1274Szelenkov@nginx.com self.get_http10( 234*1274Szelenkov@nginx.com headers={'Host': 'localhost', 'Custom-Header': header_value} 235*1274Szelenkov@nginx.com )['headers']['Custom-Header'], 236*1274Szelenkov@nginx.com header_value, 237*1274Szelenkov@nginx.com 'custom header 2', 238*1274Szelenkov@nginx.com ) 239*1274Szelenkov@nginx.com 240*1274Szelenkov@nginx.com header_value = 'X' * 4096 241*1274Szelenkov@nginx.com self.assertEqual( 242*1274Szelenkov@nginx.com self.get_http10( 243*1274Szelenkov@nginx.com headers={'Host': 'localhost', 'Custom-Header': header_value} 244*1274Szelenkov@nginx.com )['headers']['Custom-Header'], 245*1274Szelenkov@nginx.com header_value, 246*1274Szelenkov@nginx.com 'custom header 3', 247*1274Szelenkov@nginx.com ) 248*1274Szelenkov@nginx.com 249*1274Szelenkov@nginx.com header_value = 'X' * 8191 250*1274Szelenkov@nginx.com self.assertEqual( 251*1274Szelenkov@nginx.com self.get_http10( 252*1274Szelenkov@nginx.com headers={'Host': 'localhost', 'Custom-Header': header_value} 253*1274Szelenkov@nginx.com )['headers']['Custom-Header'], 254*1274Szelenkov@nginx.com header_value, 255*1274Szelenkov@nginx.com 'custom header 4', 256*1274Szelenkov@nginx.com ) 257*1274Szelenkov@nginx.com 258*1274Szelenkov@nginx.com header_value = 'X' * 8192 259*1274Szelenkov@nginx.com self.assertEqual( 260*1274Szelenkov@nginx.com self.get_http10( 261*1274Szelenkov@nginx.com headers={'Host': 'localhost', 'Custom-Header': header_value} 262*1274Szelenkov@nginx.com )['status'], 263*1274Szelenkov@nginx.com 431, 264*1274Szelenkov@nginx.com 'custom header 5', 265*1274Szelenkov@nginx.com ) 266*1274Szelenkov@nginx.com 267*1274Szelenkov@nginx.com def test_proxy_fragmented(self): 268*1274Szelenkov@nginx.com _, sock = self.http( 269*1274Szelenkov@nginx.com b"""GET / HTT""", raw=True, start=True, no_recv=True 270*1274Szelenkov@nginx.com ) 271*1274Szelenkov@nginx.com 272*1274Szelenkov@nginx.com time.sleep(1) 273*1274Szelenkov@nginx.com 274*1274Szelenkov@nginx.com sock.sendall("P/1.0\r\nHost: localhos".encode()) 275*1274Szelenkov@nginx.com 276*1274Szelenkov@nginx.com time.sleep(1) 277*1274Szelenkov@nginx.com 278*1274Szelenkov@nginx.com sock.sendall("t\r\n\r\n".encode()) 279*1274Szelenkov@nginx.com 280*1274Szelenkov@nginx.com self.assertRegex( 281*1274Szelenkov@nginx.com self.recvall(sock).decode(), '200 OK', 'fragmented send' 282*1274Szelenkov@nginx.com ) 283*1274Szelenkov@nginx.com sock.close() 284*1274Szelenkov@nginx.com 285*1274Szelenkov@nginx.com def test_proxy_fragmented_close(self): 286*1274Szelenkov@nginx.com _, sock = self.http( 287*1274Szelenkov@nginx.com b"""GET / HTT""", raw=True, start=True, no_recv=True 288*1274Szelenkov@nginx.com ) 289*1274Szelenkov@nginx.com 290*1274Szelenkov@nginx.com time.sleep(1) 291*1274Szelenkov@nginx.com 292*1274Szelenkov@nginx.com sock.sendall("P/1.0\r\nHo".encode()) 293*1274Szelenkov@nginx.com 294*1274Szelenkov@nginx.com sock.close() 295*1274Szelenkov@nginx.com 296*1274Szelenkov@nginx.com def test_proxy_fragmented_body(self): 297*1274Szelenkov@nginx.com _, sock = self.http( 298*1274Szelenkov@nginx.com b"""GET / HTT""", raw=True, start=True, no_recv=True 299*1274Szelenkov@nginx.com ) 300*1274Szelenkov@nginx.com 301*1274Szelenkov@nginx.com time.sleep(1) 302*1274Szelenkov@nginx.com 303*1274Szelenkov@nginx.com sock.sendall("P/1.0\r\nHost: localhost\r\n".encode()) 304*1274Szelenkov@nginx.com sock.sendall("Content-Length: 30000\r\n".encode()) 305*1274Szelenkov@nginx.com 306*1274Szelenkov@nginx.com time.sleep(1) 307*1274Szelenkov@nginx.com 308*1274Szelenkov@nginx.com sock.sendall("\r\n".encode()) 309*1274Szelenkov@nginx.com sock.sendall(("X" * 10000).encode()) 310*1274Szelenkov@nginx.com 311*1274Szelenkov@nginx.com time.sleep(1) 312*1274Szelenkov@nginx.com 313*1274Szelenkov@nginx.com sock.sendall(("X" * 10000).encode()) 314*1274Szelenkov@nginx.com 315*1274Szelenkov@nginx.com time.sleep(1) 316*1274Szelenkov@nginx.com 317*1274Szelenkov@nginx.com sock.sendall(("X" * 10000).encode()) 318*1274Szelenkov@nginx.com 319*1274Szelenkov@nginx.com resp = self._resp_to_dict(self.recvall(sock).decode()) 320*1274Szelenkov@nginx.com sock.close() 321*1274Szelenkov@nginx.com 322*1274Szelenkov@nginx.com self.assertEqual(resp['status'], 200, 'status') 323*1274Szelenkov@nginx.com self.assertEqual(resp['body'], "X" * 30000, 'body') 324*1274Szelenkov@nginx.com 325*1274Szelenkov@nginx.com def test_proxy_fragmented_body_close(self): 326*1274Szelenkov@nginx.com _, sock = self.http( 327*1274Szelenkov@nginx.com b"""GET / HTT""", raw=True, start=True, no_recv=True 328*1274Szelenkov@nginx.com ) 329*1274Szelenkov@nginx.com 330*1274Szelenkov@nginx.com time.sleep(1) 331*1274Szelenkov@nginx.com 332*1274Szelenkov@nginx.com sock.sendall("P/1.0\r\nHost: localhost\r\n".encode()) 333*1274Szelenkov@nginx.com sock.sendall("Content-Length: 30000\r\n".encode()) 334*1274Szelenkov@nginx.com 335*1274Szelenkov@nginx.com time.sleep(1) 336*1274Szelenkov@nginx.com 337*1274Szelenkov@nginx.com sock.sendall("\r\n".encode()) 338*1274Szelenkov@nginx.com sock.sendall(("X" * 10000).encode()) 339*1274Szelenkov@nginx.com 340*1274Szelenkov@nginx.com sock.close() 341*1274Szelenkov@nginx.com 342*1274Szelenkov@nginx.com def test_proxy_nowhere(self): 343*1274Szelenkov@nginx.com self.assertIn( 344*1274Szelenkov@nginx.com 'success', 345*1274Szelenkov@nginx.com self.conf( 346*1274Szelenkov@nginx.com [{"action": {"proxy": "http://127.0.0.1:7082"}}], 'routes' 347*1274Szelenkov@nginx.com ), 348*1274Szelenkov@nginx.com 'proxy path changed', 349*1274Szelenkov@nginx.com ) 350*1274Szelenkov@nginx.com 351*1274Szelenkov@nginx.com self.assertEqual(self.get_http10()['status'], 502, 'status') 352*1274Szelenkov@nginx.com 353*1274Szelenkov@nginx.com def test_proxy_ipv6(self): 354*1274Szelenkov@nginx.com self.assertIn( 355*1274Szelenkov@nginx.com 'success', 356*1274Szelenkov@nginx.com self.conf( 357*1274Szelenkov@nginx.com { 358*1274Szelenkov@nginx.com "*:7080": {"pass": "routes"}, 359*1274Szelenkov@nginx.com "[::1]:7081": {'application': 'mirror'}, 360*1274Szelenkov@nginx.com }, 361*1274Szelenkov@nginx.com 'listeners', 362*1274Szelenkov@nginx.com ), 363*1274Szelenkov@nginx.com 'add ipv6 listener configure', 364*1274Szelenkov@nginx.com ) 365*1274Szelenkov@nginx.com 366*1274Szelenkov@nginx.com self.assertIn( 367*1274Szelenkov@nginx.com 'success', 368*1274Szelenkov@nginx.com self.conf([{"action": {"proxy": "http://[::1]:7081"}}], 'routes'), 369*1274Szelenkov@nginx.com 'proxy ipv6 configure', 370*1274Szelenkov@nginx.com ) 371*1274Szelenkov@nginx.com 372*1274Szelenkov@nginx.com self.assertEqual(self.get_http10()['status'], 200, 'status') 373*1274Szelenkov@nginx.com 374*1274Szelenkov@nginx.com def test_proxy_unix(self): 375*1274Szelenkov@nginx.com addr = self.testdir + '/sock' 376*1274Szelenkov@nginx.com 377*1274Szelenkov@nginx.com self.assertIn( 378*1274Szelenkov@nginx.com 'success', 379*1274Szelenkov@nginx.com self.conf( 380*1274Szelenkov@nginx.com { 381*1274Szelenkov@nginx.com "*:7080": {"pass": "routes"}, 382*1274Szelenkov@nginx.com "unix:" + addr: {'application': 'mirror'}, 383*1274Szelenkov@nginx.com }, 384*1274Szelenkov@nginx.com 'listeners', 385*1274Szelenkov@nginx.com ), 386*1274Szelenkov@nginx.com 'add unix listener configure', 387*1274Szelenkov@nginx.com ) 388*1274Szelenkov@nginx.com 389*1274Szelenkov@nginx.com self.assertIn( 390*1274Szelenkov@nginx.com 'success', 391*1274Szelenkov@nginx.com self.conf( 392*1274Szelenkov@nginx.com [{"action": {"proxy": 'http://unix:' + addr}}], 'routes' 393*1274Szelenkov@nginx.com ), 394*1274Szelenkov@nginx.com 'proxy unix configure', 395*1274Szelenkov@nginx.com ) 396*1274Szelenkov@nginx.com 397*1274Szelenkov@nginx.com self.assertEqual(self.get_http10()['status'], 200, 'status') 398*1274Szelenkov@nginx.com 399*1274Szelenkov@nginx.com def test_proxy_delayed(self): 400*1274Szelenkov@nginx.com self.assertIn( 401*1274Szelenkov@nginx.com 'success', 402*1274Szelenkov@nginx.com self.conf( 403*1274Szelenkov@nginx.com {"pass": "applications/delayed"}, 'listeners/*:7081' 404*1274Szelenkov@nginx.com ), 405*1274Szelenkov@nginx.com 'delayed configure', 406*1274Szelenkov@nginx.com ) 407*1274Szelenkov@nginx.com 408*1274Szelenkov@nginx.com body = '0123456789' * 1000 409*1274Szelenkov@nginx.com resp = self.post_http10( 410*1274Szelenkov@nginx.com headers={ 411*1274Szelenkov@nginx.com 'Host': 'localhost', 412*1274Szelenkov@nginx.com 'Content-Type': 'text/html', 413*1274Szelenkov@nginx.com 'Content-Length': str(len(body)), 414*1274Szelenkov@nginx.com 'X-Parts': '2', 415*1274Szelenkov@nginx.com 'X-Delay': '1', 416*1274Szelenkov@nginx.com }, 417*1274Szelenkov@nginx.com body=body, 418*1274Szelenkov@nginx.com ) 419*1274Szelenkov@nginx.com 420*1274Szelenkov@nginx.com self.assertEqual(resp['status'], 200, 'status') 421*1274Szelenkov@nginx.com self.assertEqual(resp['body'], body, 'body') 422*1274Szelenkov@nginx.com 423*1274Szelenkov@nginx.com resp = self.post_http10( 424*1274Szelenkov@nginx.com headers={ 425*1274Szelenkov@nginx.com 'Host': 'localhost', 426*1274Szelenkov@nginx.com 'Content-Type': 'text/html', 427*1274Szelenkov@nginx.com 'Content-Length': str(len(body)), 428*1274Szelenkov@nginx.com 'X-Parts': '2', 429*1274Szelenkov@nginx.com 'X-Delay': '1', 430*1274Szelenkov@nginx.com }, 431*1274Szelenkov@nginx.com body=body, 432*1274Szelenkov@nginx.com ) 433*1274Szelenkov@nginx.com 434*1274Szelenkov@nginx.com self.assertEqual(resp['status'], 200, 'status') 435*1274Szelenkov@nginx.com self.assertEqual(resp['body'], body, 'body') 436*1274Szelenkov@nginx.com 437*1274Szelenkov@nginx.com def test_proxy_delayed_close(self): 438*1274Szelenkov@nginx.com self.assertIn( 439*1274Szelenkov@nginx.com 'success', 440*1274Szelenkov@nginx.com self.conf( 441*1274Szelenkov@nginx.com {"pass": "applications/delayed"}, 'listeners/*:7081' 442*1274Szelenkov@nginx.com ), 443*1274Szelenkov@nginx.com 'delayed configure', 444*1274Szelenkov@nginx.com ) 445*1274Szelenkov@nginx.com 446*1274Szelenkov@nginx.com _, sock = self.post_http10( 447*1274Szelenkov@nginx.com headers={ 448*1274Szelenkov@nginx.com 'Host': 'localhost', 449*1274Szelenkov@nginx.com 'Content-Type': 'text/html', 450*1274Szelenkov@nginx.com 'Content-Length': '10000', 451*1274Szelenkov@nginx.com 'X-Parts': '3', 452*1274Szelenkov@nginx.com 'X-Delay': '1', 453*1274Szelenkov@nginx.com }, 454*1274Szelenkov@nginx.com body='0123456789' * 1000, 455*1274Szelenkov@nginx.com start=True, 456*1274Szelenkov@nginx.com no_recv=True, 457*1274Szelenkov@nginx.com ) 458*1274Szelenkov@nginx.com 459*1274Szelenkov@nginx.com self.assertRegex( 460*1274Szelenkov@nginx.com sock.recv(100).decode(), '200 OK', 'first' 461*1274Szelenkov@nginx.com ) 462*1274Szelenkov@nginx.com sock.close() 463*1274Szelenkov@nginx.com 464*1274Szelenkov@nginx.com _, sock = self.post_http10( 465*1274Szelenkov@nginx.com headers={ 466*1274Szelenkov@nginx.com 'Host': 'localhost', 467*1274Szelenkov@nginx.com 'Content-Type': 'text/html', 468*1274Szelenkov@nginx.com 'Content-Length': '10000', 469*1274Szelenkov@nginx.com 'X-Parts': '3', 470*1274Szelenkov@nginx.com 'X-Delay': '1', 471*1274Szelenkov@nginx.com }, 472*1274Szelenkov@nginx.com body='0123456789' * 1000, 473*1274Szelenkov@nginx.com start=True, 474*1274Szelenkov@nginx.com no_recv=True, 475*1274Szelenkov@nginx.com ) 476*1274Szelenkov@nginx.com 477*1274Szelenkov@nginx.com self.assertRegex( 478*1274Szelenkov@nginx.com sock.recv(100).decode(), '200 OK', 'second' 479*1274Szelenkov@nginx.com ) 480*1274Szelenkov@nginx.com sock.close() 481*1274Szelenkov@nginx.com 482*1274Szelenkov@nginx.com @unittest.skip('not yet') 483*1274Szelenkov@nginx.com def test_proxy_content_length(self): 484*1274Szelenkov@nginx.com self.assertIn( 485*1274Szelenkov@nginx.com 'success', 486*1274Szelenkov@nginx.com self.conf( 487*1274Szelenkov@nginx.com [ 488*1274Szelenkov@nginx.com { 489*1274Szelenkov@nginx.com "action": { 490*1274Szelenkov@nginx.com "proxy": "http://127.0.0.1:" 491*1274Szelenkov@nginx.com + str(self.SERVER_PORT) 492*1274Szelenkov@nginx.com } 493*1274Szelenkov@nginx.com } 494*1274Szelenkov@nginx.com ], 495*1274Szelenkov@nginx.com 'routes', 496*1274Szelenkov@nginx.com ), 497*1274Szelenkov@nginx.com 'proxy backend configure', 498*1274Szelenkov@nginx.com ) 499*1274Szelenkov@nginx.com 500*1274Szelenkov@nginx.com resp = self.get_http10() 501*1274Szelenkov@nginx.com self.assertEqual(len(resp['body']), 0, 'body lt Content-Length 0') 502*1274Szelenkov@nginx.com 503*1274Szelenkov@nginx.com resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '5'}) 504*1274Szelenkov@nginx.com self.assertEqual(len(resp['body']), 5, 'body lt Content-Length 5') 505*1274Szelenkov@nginx.com 506*1274Szelenkov@nginx.com resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '9'}) 507*1274Szelenkov@nginx.com self.assertEqual(len(resp['body']), 9, 'body lt Content-Length 9') 508*1274Szelenkov@nginx.com 509*1274Szelenkov@nginx.com resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '11'}) 510*1274Szelenkov@nginx.com self.assertEqual(len(resp['body']), 10, 'body gt Content-Length 11') 511*1274Szelenkov@nginx.com 512*1274Szelenkov@nginx.com resp = self.get_http10(headers={'Host': 'localhost', 'X-Len': '15'}) 513*1274Szelenkov@nginx.com self.assertEqual(len(resp['body']), 10, 'body gt Content-Length 15') 514*1274Szelenkov@nginx.com 515*1274Szelenkov@nginx.com def test_proxy_invalid(self): 516*1274Szelenkov@nginx.com self.assertIn( 517*1274Szelenkov@nginx.com 'error', 518*1274Szelenkov@nginx.com self.conf([{"action": {"proxy": 'blah'}}], 'routes'), 519*1274Szelenkov@nginx.com 'proxy invalid', 520*1274Szelenkov@nginx.com ) 521*1274Szelenkov@nginx.com self.assertIn( 522*1274Szelenkov@nginx.com 'error', 523*1274Szelenkov@nginx.com self.conf([{"action": {"proxy": '/blah'}}], 'routes'), 524*1274Szelenkov@nginx.com 'proxy invalid 2', 525*1274Szelenkov@nginx.com ) 526*1274Szelenkov@nginx.com self.assertIn( 527*1274Szelenkov@nginx.com 'error', 528*1274Szelenkov@nginx.com self.conf([{"action": {"proxy": 'unix:/blah'}}], 'routes'), 529*1274Szelenkov@nginx.com 'proxy unix invalid 2', 530*1274Szelenkov@nginx.com ) 531*1274Szelenkov@nginx.com self.assertIn( 532*1274Szelenkov@nginx.com 'error', 533*1274Szelenkov@nginx.com self.conf([{"action": {"proxy": 'http://blah'}}], 'routes'), 534*1274Szelenkov@nginx.com 'proxy unix invalid 3', 535*1274Szelenkov@nginx.com ) 536*1274Szelenkov@nginx.com self.assertIn( 537*1274Szelenkov@nginx.com 'error', 538*1274Szelenkov@nginx.com self.conf([{"action": {"proxy": 'http://127.0.0.1'}}], 'routes'), 539*1274Szelenkov@nginx.com 'proxy ipv4 invalid', 540*1274Szelenkov@nginx.com ) 541*1274Szelenkov@nginx.com self.assertIn( 542*1274Szelenkov@nginx.com 'error', 543*1274Szelenkov@nginx.com self.conf([{"action": {"proxy": 'http://127.0.0.1:'}}], 'routes'), 544*1274Szelenkov@nginx.com 'proxy ipv4 invalid 2', 545*1274Szelenkov@nginx.com ) 546*1274Szelenkov@nginx.com self.assertIn( 547*1274Szelenkov@nginx.com 'error', 548*1274Szelenkov@nginx.com self.conf( 549*1274Szelenkov@nginx.com [{"action": {"proxy": 'http://127.0.0.1:blah'}}], 'routes' 550*1274Szelenkov@nginx.com ), 551*1274Szelenkov@nginx.com 'proxy ipv4 invalid 3', 552*1274Szelenkov@nginx.com ) 553*1274Szelenkov@nginx.com self.assertIn( 554*1274Szelenkov@nginx.com 'error', 555*1274Szelenkov@nginx.com self.conf( 556*1274Szelenkov@nginx.com [{"action": {"proxy": 'http://127.0.0.1:-1'}}], 'routes' 557*1274Szelenkov@nginx.com ), 558*1274Szelenkov@nginx.com 'proxy ipv4 invalid 4', 559*1274Szelenkov@nginx.com ) 560*1274Szelenkov@nginx.com self.assertIn( 561*1274Szelenkov@nginx.com 'error', 562*1274Szelenkov@nginx.com self.conf( 563*1274Szelenkov@nginx.com [{"action": {"proxy": 'http://127.0.0.1:7080b'}}], 'routes' 564*1274Szelenkov@nginx.com ), 565*1274Szelenkov@nginx.com 'proxy ipv4 invalid 5', 566*1274Szelenkov@nginx.com ) 567*1274Szelenkov@nginx.com self.assertIn( 568*1274Szelenkov@nginx.com 'error', 569*1274Szelenkov@nginx.com self.conf( 570*1274Szelenkov@nginx.com [{"action": {"proxy": 'http://[]'}}], 'routes' 571*1274Szelenkov@nginx.com ), 572*1274Szelenkov@nginx.com 'proxy ipv6 invalid', 573*1274Szelenkov@nginx.com ) 574*1274Szelenkov@nginx.com self.assertIn( 575*1274Szelenkov@nginx.com 'error', 576*1274Szelenkov@nginx.com self.conf( 577*1274Szelenkov@nginx.com [{"action": {"proxy": 'http://[]:7080'}}], 'routes' 578*1274Szelenkov@nginx.com ), 579*1274Szelenkov@nginx.com 'proxy ipv6 invalid 2', 580*1274Szelenkov@nginx.com ) 581*1274Szelenkov@nginx.com self.assertIn( 582*1274Szelenkov@nginx.com 'error', 583*1274Szelenkov@nginx.com self.conf( 584*1274Szelenkov@nginx.com [{"action": {"proxy": 'http://[:]:7080'}}], 'routes' 585*1274Szelenkov@nginx.com ), 586*1274Szelenkov@nginx.com 'proxy ipv6 invalid 3', 587*1274Szelenkov@nginx.com ) 588*1274Szelenkov@nginx.com self.assertIn( 589*1274Szelenkov@nginx.com 'error', 590*1274Szelenkov@nginx.com self.conf( 591*1274Szelenkov@nginx.com [{"action": {"proxy": 'http://[::7080'}}], 'routes' 592*1274Szelenkov@nginx.com ), 593*1274Szelenkov@nginx.com 'proxy ipv6 invalid 4', 594*1274Szelenkov@nginx.com ) 595*1274Szelenkov@nginx.com 596*1274Szelenkov@nginx.com @unittest.skip('not yet') 597*1274Szelenkov@nginx.com def test_proxy_loop(self): 598*1274Szelenkov@nginx.com self.conf( 599*1274Szelenkov@nginx.com { 600*1274Szelenkov@nginx.com "listeners": { 601*1274Szelenkov@nginx.com "*:7080": {"pass": "routes"}, 602*1274Szelenkov@nginx.com "*:7081": {"pass": "applications/mirror"}, 603*1274Szelenkov@nginx.com "*:7082": {"pass": "routes"}, 604*1274Szelenkov@nginx.com }, 605*1274Szelenkov@nginx.com "routes": [{"action": {"proxy": "http://127.0.0.1:7082"}}], 606*1274Szelenkov@nginx.com "applications": { 607*1274Szelenkov@nginx.com "mirror": { 608*1274Szelenkov@nginx.com "type": "python", 609*1274Szelenkov@nginx.com "processes": {"spare": 0}, 610*1274Szelenkov@nginx.com "path": self.current_dir + "/python/mirror", 611*1274Szelenkov@nginx.com "working_directory": self.current_dir 612*1274Szelenkov@nginx.com + "/python/mirror", 613*1274Szelenkov@nginx.com "module": "wsgi", 614*1274Szelenkov@nginx.com }, 615*1274Szelenkov@nginx.com }, 616*1274Szelenkov@nginx.com } 617*1274Szelenkov@nginx.com ) 618*1274Szelenkov@nginx.com 619*1274Szelenkov@nginx.com self.get_http10(no_recv=True) 620*1274Szelenkov@nginx.com 621*1274Szelenkov@nginx.comif __name__ == '__main__': 622*1274Szelenkov@nginx.com TestProxy.main() 623