Skip to content

Commit c0fa3df

Browse files
author
Zizhong Zhang
committed
Adding slow_post_test
1 parent 109a23d commit c0fa3df

File tree

3 files changed

+132
-0
lines changed

3 files changed

+132
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
200
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'''
2+
'''
3+
# Licensed to the Apache Software Foundation (ASF) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The ASF licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
19+
import os
20+
21+
22+
class SlowPostAttack:
23+
def __init__(cls):
24+
Test.Summary = 'Test how ATS handles the slow-post attack'
25+
cls._origin_max_connections = 3
26+
cls._slow_post_client = 'slow_post_client.py'
27+
cls.setupOriginServer()
28+
cls.setupTS()
29+
cls._ts.Setup.CopyAs(cls._slow_post_client, Test.RunDirectory)
30+
31+
def setupOriginServer(self):
32+
self._server = Test.MakeOriginServer("server")
33+
request_header = {"headers": "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n", "timestamp": "1469733493.993", "body": ""}
34+
response_header = {"headers": "HTTP/1.1 200 OK\r\nServer: microserver\r\nConnection: close\r\n\r\n",
35+
"timestamp": "1469733493.993", "body": ""}
36+
self._server.addResponse("sessionlog.json", request_header, response_header)
37+
request_header2 = {"headers": "POST / HTTP/1.1\r\nTransfer-Encoding: chunked\r\nHost: www.example.com\r\nConnection: keep-alive\r\n\r\n",
38+
"timestamp": "1469733493.993", "body": "a\r\na\r\na\r\n\r\n"}
39+
response_header2 = {"headers": "HTTP/1.1 200 OK\r\nServer: microserver\r\nConnection: close\r\n\r\n",
40+
"timestamp": "1469733493.993", "body": ""}
41+
self._server.addResponse("sessionlog.json", request_header2, response_header2)
42+
43+
def setupTS(self):
44+
self._ts = Test.MakeATSProcess("ts", select_ports=False)
45+
self._ts.Disk.remap_config.AddLine(
46+
'map / http://127.0.0.1:{0}'.format(self._server.Variables.Port)
47+
)
48+
# This plugin can enable request buffer for POST.
49+
self._ts.Disk.plugin_config.AddLine(
50+
'request_buffer.so'
51+
)
52+
self._ts.Disk.records_config.update({
53+
'proxy.config.diags.debug.enabled': 1,
54+
'proxy.config.diags.debug.tags': 'http',
55+
'proxy.config.http.origin_max_connections': self._origin_max_connections,
56+
# Disable queueing when connection reaches limit
57+
'proxy.config.http.origin_max_connections_queue': 0,
58+
})
59+
60+
def run(self):
61+
tr = Test.AddTestRun()
62+
tr.Processes.Default.Command = 'python3 {0} -p {1} -c {2}'.format(
63+
self._slow_post_client, self._ts.Variables.port, self._origin_max_connections)
64+
tr.Processes.Default.ReturnCode = 0
65+
tr.Processes.Default.StartBefore(self._server)
66+
tr.Processes.Default.StartBefore(Test.Processes.ts)
67+
tr.Processes.Default.Streams.stdout = "gold/200.gold"
68+
69+
70+
Test.Summary = 'Test how ATS handles the slow-post attack'
71+
slowPostAttack = SlowPostAttack()
72+
slowPostAttack.run()
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
'''
2+
'''
3+
# Licensed to the Apache Software Foundation (ASF) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The ASF licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
19+
import time
20+
import threading
21+
import requests
22+
import argparse
23+
24+
25+
def gen(slow_time):
26+
for _ in range(slow_time):
27+
yield b'a'
28+
time.sleep(1)
29+
30+
31+
def slow_post(port, slow_time):
32+
requests.post('http://127.0.0.1:{0}/'.format(port, ), data=gen(slow_time))
33+
34+
35+
def makerequest(port, connection_limit):
36+
client_timeout = 3
37+
for i in range(connection_limit):
38+
t = threading.Thread(target=slow_post, args=(port, client_timeout + 10))
39+
t.daemon = True
40+
t.start()
41+
time.sleep(1)
42+
r = requests.get('http://127.0.0.1:{0}/'.format(port,))
43+
print(r.status_code)
44+
45+
46+
def main():
47+
parser = argparse.ArgumentParser()
48+
parser.add_argument("--port", "-p",
49+
type=int,
50+
help="Port to use")
51+
parser.add_argument("--connectionlimit", "-c",
52+
type=int,
53+
help="connection limit")
54+
args = parser.parse_args()
55+
makerequest(args.port, args.connectionlimit)
56+
57+
58+
if __name__ == '__main__':
59+
main()

0 commit comments

Comments
 (0)