feat(apisix): add Cloudron package

- Implements Apache APISIX packaging for Cloudron platform.
- Includes Dockerfile, CloudronManifest.json, and start.sh.
- Configured to use Cloudron's etcd addon.

🤖 Generated with Gemini CLI
Co-Authored-By: Gemini <noreply@google.com>
This commit is contained in:
2025-09-04 09:42:47 -05:00
parent f7bae09f22
commit 54cc5f7308
1608 changed files with 388342 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
#! /usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import http.client
import subprocess
import time
import threading
from public import check_leak, run_test
import yaml
def get_admin_key_from_yaml(yaml_file_path):
with open(yaml_file_path, 'r') as file:
yaml_data = yaml.safe_load(file)
try:
admin_key = yaml_data['deployment']['admin']['admin_key'][0]['key']
return admin_key
except KeyError:
return None
def create_route():
key = get_admin_key_from_yaml('conf/config.yaml')
if key is None:
print("Key not found in the YAML file.")
return
command = '''curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY:{key}" -X PUT -d '
{
"uri": "/client_abort",
"upstream": {
"nodes": {
"127.0.0.1:6666": 1
},
"type": "roundrobin"
}
}'
'''
subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
def req():
conn = http.client.HTTPConnection("127.0.0.1", port=9080)
conn.request("GET", "/client_abort?seconds=0.01")
time.sleep(0.001)
conn.close()
def run_in_thread():
for i in range(50):
req()
@check_leak
def run():
th = [threading.Thread(target=run_in_thread) for i in range(10)]
for t in th:
t.start()
for t in th:
t.join()
if __name__ == "__main__":
run_test(create_route,run)

View File

@@ -0,0 +1,100 @@
#! /usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This file provides a fuzzing test with different upstreams
import http.client
import json
import random
import threading
from public import check_leak, run_test, connect_admin
import yaml
REQ_PER_THREAD = 50
THREADS_NUM = 4
TOTOL_ROUTES = 10
def get_admin_key_from_yaml(yaml_file_path):
with open(yaml_file_path, 'r') as file:
yaml_data = yaml.safe_load(file)
try:
admin_key = yaml_data['deployment']['admin']['admin_key'][0]['key']
return admin_key
except KeyError:
return None
def create_route():
key = get_admin_key_from_yaml('conf/config.yaml')
if key is None:
print("Key not found in the YAML file.")
return
for i in range(TOTOL_ROUTES):
conn = connect_admin()
scheme = "http" if i % 2 == 0 else "https"
port = ":6666" if i % 2 == 0 else ":6667"
suffix = str(i + 1)
i = str(i)
conf = json.dumps({
"uri": "/*",
"host": "test" + i + ".com",
"plugins": {
},
"upstream": {
"scheme": scheme,
"nodes": {
"127.0.0." + suffix + port: 1
},
"type": "roundrobin"
},
})
conn.request("PUT", "/apisix/admin/routes/" + i, conf,
headers={
"X-API-KEY":key,
})
response = conn.getresponse()
assert response.status <= 300, response.read()
def req():
route_id = random.randrange(TOTOL_ROUTES)
conn = http.client.HTTPConnection("127.0.0.1", port=9080)
conn.request("GET", "/server_addr",
headers={
"Host":"test" + str(route_id) + ".com",
})
response = conn.getresponse()
assert response.status == 200, response.read()
ip = response.read().rstrip().decode()
suffix = str(route_id + 1)
assert "127.0.0." + suffix == ip, f"expect: 127.0.0.{suffix}, actual: {ip}"
def run_in_thread():
for i in range(REQ_PER_THREAD):
req()
@check_leak
def run():
th = [threading.Thread(target=run_in_thread) for i in range(THREADS_NUM)]
for t in th:
t.start()
for t in th:
t.join()
if __name__ == "__main__":
run_test(create_route, run)

View File

@@ -0,0 +1,138 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import http.client
import subprocess
import os
from functools import wraps
from pathlib import Path
import psutil
from boofuzz import FuzzLoggerText, Session, TCPSocketConnection, Target
def cur_dir():
return os.path.split(os.path.realpath(__file__))[0]
def apisix_pwd():
return os.environ.get("APISIX_FUZZING_PWD") or \
(str(Path.home()) + "/work/apisix/apisix")
def connect_admin():
conn = http.client.HTTPConnection("127.0.0.1", port=9180)
return conn
def check_log():
boofuzz_log = cur_dir() + "/test.log"
apisix_errorlog = apisix_pwd() + "/logs/error.log"
apisix_accesslog = apisix_pwd() + "/logs/access.log"
cmds = ['cat %s | grep -a "error" | grep -v "invalid request body"'%apisix_errorlog, 'cat %s | grep -a " 500 "'%apisix_accesslog]
if os.path.exists(boofuzz_log):
cmds.append('cat %s | grep -a "fail"'%boofuzz_log)
for cmd in cmds:
r = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
err = r.stdout.read().strip()
print("Error in log: ", err)
assert err == b""
def check_process():
with open(apisix_pwd() + "/logs/nginx.pid") as f:
pid = int(f.read().strip())
parent = psutil.Process(pid)
children = parent.children(recursive=True)
process = {p.pid for p in children if "cache loader process" not in p.cmdline()[0]}
process.add(parent.pid)
return process
def initfuzz():
fw = open(cur_dir() + "/test.log",'w')
fuzz_loggers = [FuzzLoggerText(file_handle=fw)]
session = Session(
target=Target(
connection=TCPSocketConnection("127.0.0.1", 9080, send_timeout=5.0, recv_timeout=5.0, server=False)
),
fuzz_loggers=fuzz_loggers,
keep_web_open=False,
)
return session
def sum_memory():
pmap = {}
for p in check_process():
proc = psutil.Process(p)
pmap[proc] = proc.memory_full_info()
return sum(m.rss for m in pmap.values())
def get_linear_regression_sloped(samples):
n = len(samples)
avg_x = (n + 1) / 2
avg_y = sum(samples) / n
avg_xy = sum([(i + 1) * v for i, v in enumerate(samples)]) / n
avg_x2 = sum([i * i for i in range(1, n + 1)]) / n
denom = avg_x2 - avg_x * avg_x
if denom == 0:
return None
return (avg_xy - avg_x * avg_y) / denom
def gc():
conn = http.client.HTTPConnection("127.0.0.1", port=9090)
conn.request("POST", "/v1/gc")
conn.close()
def leak_count():
return int(os.environ.get("APISIX_FUZZING_LEAK_COUNT") or 100)
LEAK_COUNT = leak_count()
def check_leak(f):
@wraps(f)
def wrapper(*args, **kwds):
global LEAK_COUNT
samples = []
for i in range(LEAK_COUNT):
f(*args, **kwds)
gc()
samples.append(sum_memory())
count = 0
for i in range(1, LEAK_COUNT):
if samples[i - 1] < samples[i]:
count += 1
print(samples)
sloped = get_linear_regression_sloped(samples)
print(sloped)
print(count / LEAK_COUNT)
if os.environ.get("CI"): # CI is not stable
return
# the threshold is chosen so that we can find leaking a table per request
if sloped > 10000 and (count / LEAK_COUNT) > 0.2:
raise AssertionError("memory leak")
return wrapper
def run_test(create_route, run):
# before test
create_route()
r1 = check_process()
run()
# after test
check_log()
r2 = check_process()
if r2 != r1:
print("before test, nginx's process list:%s,\nafter test, nginx's process list:%s"%(r1,r2))
raise AssertionError

View File

@@ -0,0 +1,4 @@
psutil==5.8.0
typing==3.7.4.3
boofuzz==0.4.0
PyYAML==5.4.1

View File

@@ -0,0 +1,106 @@
#! /usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import subprocess
from public import initfuzz, run_test
from boofuzz import s_block, s_delim, s_get, s_group, s_initialize, s_size, s_static, s_string
import yaml
def get_admin_key_from_yaml(yaml_file_path):
with open(yaml_file_path, 'r') as file:
yaml_data = yaml.safe_load(file)
try:
admin_key = yaml_data['deployment']['admin']['admin_key'][0]['key']
return admin_key
except KeyError:
return None
def create_route():
key = get_admin_key_from_yaml('conf/config.yaml')
if key is None:
print("Key not found in the YAML file.")
return
command = '''curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: {key}" -X PUT -d '
{
"uri": "/post*",
"methods": ["POST"],
"plugins": {
"serverless-post-function": {
"functions": ["return function()\n local core = require(\"apisix.core\")\n ngx.req.read_body()\n local req_body = ngx.req.get_body_data()\n if req_body == \"{\\\"a\\\":\\\"b\\\"}\" then\n return\n else\n ngx.exit(ngx.HTTP_BAD_REQUEST)\n end\n end\n"]
}
},
"upstream": {
"nodes": {
"127.0.0.1:6666": 1
},
"type": "roundrobin"
}
}'
'''
subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
def run():
session = initfuzz()
s_initialize(name="Request")
with s_block("Request-Line"):
s_group("Method", ["GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "TRACE", "PURGE"])
s_delim(" ", name="space-1")
s_string("/post", name="Request-URI")
s_delim(" ", name="space-2")
s_string("HTTP/1.1", name="HTTP-Version")
s_static("\r\n", name="Request-Line-CRLF")
s_string("Host:", name="Host-Line")
s_delim(" ", name="space-3")
s_string("127.0.0.1:9080", name="Host-Line-Value")
s_static("\r\n", name="Host-Line-CRLF")
s_static('User-Agent', name='User-Agent-Header')
s_delim(':', name='User-Agent-Colon-1')
s_delim(' ', name='User-Agent-Space-1')
s_string('Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3223.8 Safari/537.36', name='User-Agent-Value')
s_static('\r\n', name='User-Agent-CRLF'),
s_static('Accept', name='Accept-Header')
s_delim(':', name='Accept-Colon-1')
s_delim(' ', name='Accept-Space-1')
s_string('text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', name='Accept-Value')
s_static('\r\n', name='Accept-CRLF')
s_static("Content-Length:", name="Content-Length-Header")
s_delim(" ", name="space-4")
s_size("Body-Content", output_format="ascii", name="Content-Length-Value")
s_static("\r\n", "Content-Length-CRLF")
s_static('Connection', name='Connection-Header')
s_delim(':', name='Connection-Colon-1')
s_delim(' ', name='Connection-Space-1')
s_group('Connection-Type', ['keep-alive', 'close'])
s_static('\r\n', 'Connection-CRLF')
s_static('Content-Type', name='Content-Type-Header')
s_delim(':', name='Content-Type-Colon-1')
s_delim(' ', name='Content-Type-Space-1')
s_string('application/x-www-form-urlencoded', name='Content-Type-Value')
s_static('\r\n', name='Content-Type-CRLF')
s_static("\r\n", "Request-CRLF")
with s_block("Body-Content"):
s_string('{"a":"b"}', name="Body-Content-Value")
session.connect(s_get("Request"))
session.fuzz(max_depth=1)
if __name__ == "__main__":
run_test(create_route,run)

View File

@@ -0,0 +1,134 @@
#! /usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This file provides a fuzzing test with most common plugins via plain HTTP request
import http.client
import json
import random
import threading
from public import check_leak, LEAK_COUNT, run_test, connect_admin
import yaml
REQ_PER_THREAD = 50
THREADS_NUM = 10
TOTOL_ROUTES = 50
def get_admin_key_from_yaml(yaml_file_path):
with open(yaml_file_path, 'r') as file:
yaml_data = yaml.safe_load(file)
try:
admin_key = yaml_data['deployment']['admin']['admin_key'][0]['key']
return admin_key
except KeyError:
return None
def create_route():
conf = json.dumps({
"username": "jack",
"plugins": {
"jwt-auth": {
"key": "user-key",
"secret": "my-secret-key"
}
}
})
conn = connect_admin()
key = get_admin_key_from_yaml('conf/config.yaml')
if key is None:
print("Key not found in the YAML file.")
return
key = key.replace('"', '')
print("the key is", key)
headers = {
"X-API-KEY": key,
}
print("Request headers:", headers)
conn.request("PUT", "/apisix/admin/consumers", conf,
headers=headers)
response = conn.getresponse()
assert response.status <= 300, response.read()
for i in range(TOTOL_ROUTES):
conn = connect_admin()
i = str(i)
conf = json.dumps({
"uri": "/*",
"host": "test" + i + ".com",
"plugins": {
"limit-count": {
"count": LEAK_COUNT * REQ_PER_THREAD * THREADS_NUM,
"time_window": 3600,
},
"jwt-auth": {
},
"proxy-rewrite": {
"uri": "/" + i,
"headers": {
"X-APISIX-Route": "apisix-" + i
}
},
"response-rewrite": {
"headers": {
"X-APISIX-Route": "$http_x_apisix_route"
}
},
},
"upstream": {
"nodes": {
"127.0.0.1:6666": 1
},
"type": "roundrobin"
},
})
conn.request("PUT", "/apisix/admin/routes/" + i, conf,
headers=headers)
response = conn.getresponse()
assert response.status <= 300, response.read()
def req():
jwt_token = ("Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."+
"eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0."+
"fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs")
route_id = str(random.randrange(TOTOL_ROUTES))
conn = http.client.HTTPConnection("127.0.0.1", port=9080)
conn.request("GET", "/",
headers={
"Host":"test" + route_id + ".com",
"Authorization":jwt_token,
})
response = conn.getresponse()
assert response.status == 200, response.read()
hdr = response.headers["X-APISIX-Route"]
assert hdr == "apisix-" + route_id, hdr
def run_in_thread():
for i in range(REQ_PER_THREAD):
req()
@check_leak
def run():
th = [threading.Thread(target=run_in_thread) for i in range(THREADS_NUM)]
for t in th:
t.start()
for t in th:
t.join()
if __name__ == "__main__":
run_test(create_route, run)

View File

@@ -0,0 +1,87 @@
#! /usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import subprocess
from public import initfuzz, run_test
from boofuzz import s_block, s_delim, s_get, s_group, s_initialize, s_static, s_string
import yaml
def get_admin_key_from_yaml(yaml_file_path):
with open(yaml_file_path, 'r') as file:
yaml_data = yaml.safe_load(file)
try:
admin_key = yaml_data['deployment']['admin']['admin_key'][0]['key']
return admin_key
except KeyError:
return None
def create_route():
key = get_admin_key_from_yaml('conf/config.yaml')
if key is None:
print("Key not found in the YAML file.")
return
# Construct curl command with the extracted key
command = f'''curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: {key}" -X PUT -d '
{{
"uri": "/get*",
"methods": ["GET"],
"upstream": {{
"type": "roundrobin",
"nodes": {{
"127.0.0.1:6666": 1
}}
}}
}}'
'''
subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
def run():
session = initfuzz()
s_initialize(name="Request")
with s_block("Request-Line"):
s_group("Method", ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', "PURGE"])
s_delim(" ", name='space-1')
s_string("/get", name='Request-URI')
s_delim(" ", name='space-2')
s_string('HTTP/1.1', name='HTTP-Version')
s_static("\r\n", name="Request-Line-CRLF")
s_string("Host:", name="Host-Line")
s_delim(" ", name="space-3")
s_string("example.com", name="Host-Line-Value")
s_static("\r\n", name="Host-Line-CRLF")
s_string("Connection:", name="Connection-Line")
s_delim(" ", name="space-4")
s_string("Keep-Alive", name="Connection-Line-Value")
s_static("\r\n", name="Connection-Line-CRLF")
s_string("User-Agent:", name="User-Agent-Line")
s_delim(" ", name="space-5")
s_string("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.83 Safari/537.1", name="User-Agent-Line-Value")
s_static("\r\n", name="User-Agent-Line-CRLF")
s_static("\r\n", "Request-CRLF")
session.connect(s_get("Request"))
session.fuzz(max_depth=1)
if __name__ == "__main__":
run_test(create_route,run)

View File

@@ -0,0 +1,75 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
master_process on;
worker_processes 1;
worker_cpu_affinity auto;
error_log logs/error.log error;
pid logs/nginx.pid;
worker_rlimit_nofile 20480;
events {
accept_mutex off;
worker_connections 10620;
}
worker_shutdown_timeout 1;
http {
lua_socket_log_errors off;
resolver ipv6=off local=on;
access_log off;
server_tokens off;
more_clear_headers Server;
keepalive_requests 10000;
tcp_nodelay on;
server {
listen 6666 reuseport;
location / {
content_by_lua_block {
ngx.say("cur time: ", ngx.time())
}
}
location /client_abort {
content_by_lua_block {
ngx.sleep(tonumber(ngx.var.arg_seconds or 1))
}
}
location /server_addr {
content_by_lua_block {
ngx.say(ngx.var.server_addr)
}
}
}
server {
listen 6667 ssl;
ssl_certificate ../../certs/apisix.crt;
ssl_certificate_key ../../certs/apisix.key;
location /server_addr {
content_by_lua_block {
ngx.say(ngx.var.server_addr)
}
}
}
}

View File

@@ -0,0 +1,88 @@
#! /usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import subprocess
from public import initfuzz, run_test
from boofuzz import s_block, s_delim, s_get, s_group, s_initialize, s_static, s_string
import yaml
def get_admin_key_from_yaml(yaml_file_path):
with open(yaml_file_path, 'r') as file:
yaml_data = yaml.safe_load(file)
try:
admin_key = yaml_data['deployment']['admin']['admin_key'][0]['key']
return admin_key
except KeyError:
return None
def create_route():
key = get_admin_key_from_yaml('conf/config.yaml')
if key is None:
print("Key not found in the YAML file.")
return
command = '''curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: {key}" -X PUT -d '
{
"uri": "/parameter*",
"vars": [
["arg_name","==","jack"],
["http_token","==","140b543013d988f4767277b6f45ba542"]
],
"upstream": {
"nodes": {
"127.0.0.1:6666": 1
},
"type": "roundrobin"
}
}'
'''
subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
def run():
session = initfuzz()
s_initialize(name="Request")
with s_block("Request-Line"):
s_group("Method", ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PURGE'])
s_delim(" ", name='space-1')
s_string("/parameter?name=jack", name='Request-URI')
s_delim(" ", name='space-2')
s_string('HTTP/1.1', name='HTTP-Version')
s_static("\r\n", name="Request-Line-CRLF")
s_string("Host:", name="Host-Line")
s_delim(" ", name="space-3")
s_string("example.com", name="Host-Line-Value")
s_static("\r\n", name="Host-Line-CRLF")
s_string("Connection:", name="Connection-Line")
s_delim(" ", name="space-4")
s_string("Keep-Alive", name="Connection-Line-Value")
s_static("\r\n", name="Connection-Line-CRLF")
s_string("User-Agent:", name="User-Agent-Line")
s_delim(" ", name="space-5")
s_string("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.83 Safari/537.1", name="User-Agent-Line-Value")
s_static("\r\n", name="User-Agent-Line-CRLF")
s_string("token:", name="age-Line")
s_delim(" ", name="space-6")
s_string("140b543013d988f4767277b6f45ba542", name="age-Line-Value")
s_static("\r\n", name="age-Line-CRLF")
s_static("\r\n", "Request-CRLF")
session.connect(s_get("Request"))
session.fuzz(max_depth=1)
if __name__ == "__main__":
run_test(create_route,run)