Skip to content

Commit 627b42f

Browse files
Handle SIGINFO. Try kill -s INFO <pid>. (abhinavsingh#1024)
* Handle `SIGINFO`. Try `kill -s INFO <pid>`. Also remove dirty hack added in flags to incorporate `--basic-auth` flag. Add `__pycache__` to ignore list. Disable http proxy during acceptor benchmark. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * not on windows * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * no cover * # pylint: disable=E1101 * Curl retry on error and check_output 2 minute timeout * check output timeout None * Update `faulthandler_timeout` to 2 minutes * Disable `test_circular_imports`, `isort` integration now works * Fix curl flags * Revert back to older flags * SIGINFO attribute might not even exist Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 85ad44b commit 627b42f

File tree

9 files changed

+59
-41
lines changed

9 files changed

+59
-41
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
.tox
1111
.python-version
1212

13+
__pycache__
14+
1315
coverage.xml
1416
proxy.py.iml
1517

benchmark/_proxy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
backlog=65536,
2323
open_file_limit=65536,
2424
enable_web_server=True,
25-
disable_proxy_server=False,
25+
disable_proxy_server=True,
2626
num_acceptors=10,
2727
local_executor=1,
2828
log_file='/dev/null',

proxy/common/flag.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,17 +98,13 @@ def initialize(
9898
print(PY2_DEPRECATION_MESSAGE)
9999
sys.exit(1)
100100

101-
# Dirty hack to always discover --basic-auth flag
102-
# defined by proxy auth plugin.
103-
in_args = input_args + ['--plugin', PLUGIN_PROXY_AUTH]
104-
105101
# Discover flags from requested plugin.
106102
# This will also surface external plugin flags
107103
# under --help.
108-
Plugins.discover(in_args)
104+
Plugins.discover(input_args)
109105

110106
# Parse flags
111-
args = flags.parse_args(in_args)
107+
args = flags.parse_args(input_args)
112108

113109
# Print version and exit
114110
if args.version:

proxy/http/proxy/auth.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,7 @@
1818
from ...http import httpHeaders
1919
from ..exception import ProxyAuthenticationFailed
2020
from ...http.proxy import HttpProxyBasePlugin
21-
from ...common.flag import flags
2221
from ...http.parser import HttpParser
23-
from ...common.constants import DEFAULT_BASIC_AUTH
24-
25-
26-
flags.add_argument(
27-
'--basic-auth',
28-
type=str,
29-
default=DEFAULT_BASIC_AUTH,
30-
help='Default: No authentication. Specify colon separated user:password '
31-
'to enable basic authentication.',
32-
)
3322

3423

3524
class AuthPlugin(HttpProxyBasePlugin):

proxy/proxy.py

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import os
1212
import sys
1313
import time
14+
import pprint
1415
import signal
1516
import logging
1617
from typing import Any, List, Optional
@@ -23,9 +24,9 @@
2324
from .core.acceptor import Listener, AcceptorPool
2425
from .common.constants import (
2526
IS_WINDOWS, DEFAULT_PLUGINS, DEFAULT_VERSION, DEFAULT_LOG_FILE,
26-
DEFAULT_PID_FILE, DEFAULT_LOG_LEVEL, DEFAULT_LOG_FORMAT,
27-
DEFAULT_WORK_KLASS, DEFAULT_OPEN_FILE_LIMIT, DEFAULT_ENABLE_DASHBOARD,
28-
DEFAULT_ENABLE_SSH_TUNNEL,
27+
DEFAULT_PID_FILE, DEFAULT_LOG_LEVEL, DEFAULT_BASIC_AUTH,
28+
DEFAULT_LOG_FORMAT, DEFAULT_WORK_KLASS, DEFAULT_OPEN_FILE_LIMIT,
29+
DEFAULT_ENABLE_DASHBOARD, DEFAULT_ENABLE_SSH_TUNNEL,
2930
)
3031

3132

@@ -40,7 +41,6 @@
4041
help='Prints proxy.py version.',
4142
)
4243

43-
# TODO: Convert me into 1-letter choices
4444
# TODO: Add --verbose option which also
4545
# starts to log traffic flowing between
4646
# clients and upstream servers.
@@ -98,6 +98,16 @@
9898
help='Default: False. Enables proxy.py dashboard.',
9999
)
100100

101+
# NOTE: Same reason as mention above.
102+
# Ideally this flag belongs to proxy auth plugin.
103+
flags.add_argument(
104+
'--basic-auth',
105+
type=str,
106+
default=DEFAULT_BASIC_AUTH,
107+
help='Default: No authentication. Specify colon separated user:password '
108+
'to enable basic authentication.',
109+
)
110+
101111
flags.add_argument(
102112
'--enable-ssh-tunnel',
103113
action='store_true',
@@ -133,6 +143,10 @@ class Proxy:
133143
Executor pool receives newly accepted work by :class:`~proxy.core.acceptor.Acceptor`
134144
and creates an instance of work class for processing the received work.
135145
146+
In ``--threadless`` mode and with ``--local-executor 0``,
147+
acceptors will start a companion thread to handle accepted
148+
client connections.
149+
136150
Optionally, Proxy class also initializes the EventManager.
137151
A multi-process safe pubsub system which can be used to build various
138152
patterns for message sharing and/or signaling.
@@ -156,18 +170,17 @@ def __exit__(self, *args: Any) -> None:
156170

157171
def setup(self) -> None:
158172
# TODO: Introduce cron feature
159-
# https://github.com/abhinavsingh/proxy.py/issues/392
173+
# https://github.com/abhinavsingh/proxy.py/discussions/808
174+
#
175+
# TODO: Introduce ability to change flags dynamically
176+
# https://github.com/abhinavsingh/proxy.py/discussions/1020
160177
#
161-
# TODO: Introduce ability to publish
162-
# adhoc events which can modify behaviour of server
163-
# at runtime. Example, updating flags, plugin
164-
# configuration etc.
178+
# TODO: Python shell within running proxy.py environment
179+
# https://github.com/abhinavsingh/proxy.py/discussions/1021
165180
#
166-
# TODO: Python shell within running proxy.py environment?
181+
# TODO: Near realtime resource / stats monitoring
182+
# https://github.com/abhinavsingh/proxy.py/discussions/1023
167183
#
168-
# TODO: Pid watcher which watches for processes started
169-
# by proxy.py core. May be alert or restart those processes
170-
# on failure.
171184
self._write_pid_file()
172185
# We setup listeners first because of flags.port override
173186
# in case of ephemeral port being used
@@ -263,10 +276,15 @@ def _delete_port_file(self) -> None:
263276
os.remove(self.flags.port_file)
264277

265278
def _register_signals(self) -> None:
266-
# TODO: Handle SIGINFO, SIGUSR1, SIGUSR2
279+
# TODO: Define SIGUSR1, SIGUSR2
267280
signal.signal(signal.SIGINT, self._handle_exit_signal)
268281
signal.signal(signal.SIGTERM, self._handle_exit_signal)
269282
if not IS_WINDOWS:
283+
if hasattr(signal, 'SIGINFO'):
284+
signal.signal( # pragma: no cover
285+
signal.SIGINFO, # pylint: disable=E1101
286+
self._handle_siginfo,
287+
)
270288
signal.signal(signal.SIGHUP, self._handle_exit_signal)
271289
# TODO: SIGQUIT is ideally meant to terminate with core dumps
272290
signal.signal(signal.SIGQUIT, self._handle_exit_signal)
@@ -276,6 +294,9 @@ def _handle_exit_signal(signum: int, _frame: Any) -> None:
276294
logger.info('Received signal %d' % signum)
277295
sys.exit(0)
278296

297+
def _handle_siginfo(self, _signum: int, _frame: Any) -> None:
298+
pprint.pprint(self.flags.__dict__) # pragma: no cover
299+
279300

280301
def sleep_loop() -> None:
281302
while True:

pytest.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ doctest_optionflags = ALLOW_UNICODE ELLIPSIS
5151
# Marks tests with an empty parameterset as xfail(run=False)
5252
empty_parameter_set_mark = xfail
5353

54-
faulthandler_timeout = 30
54+
faulthandler_timeout = 120
5555

5656
filterwarnings =
5757
error

tests/integration/test_integration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from proxy.common.constants import IS_WINDOWS
2424

2525

26-
def check_output(args: List[Any]) -> bytes:
26+
def check_output(args: List[Any]) -> bytes: # pragma: no cover
2727
args = args if not IS_WINDOWS else ['powershell'] + args
2828
return _check_output(args)
2929

tests/integration/test_integration.sh

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ if [[ -z "$PROXY_PY_PORT" ]]; then
2323
exit 1
2424
fi
2525

26+
CURL="curl -v --connect-timeout 20 --max-time 120 --retry-connrefused --retry-delay 5 --retry 3"
27+
2628
PROXY_URL="http://localhost:$PROXY_PY_PORT"
2729
TEST_URL="$PROXY_URL/http-route-example"
2830
CURL_EXTRA_FLAGS=""
@@ -50,7 +52,7 @@ while true; do
5052
done
5153

5254
# Wait for http proxy and web server to start
53-
CMD="curl -v $CURL_EXTRA_FLAGS -x $PROXY_URL $TEST_URL"
55+
CMD="$CURL $CURL_EXTRA_FLAGS -x $PROXY_URL $TEST_URL"
5456
while true; do
5557
RESPONSE=$($CMD 2> /dev/null)
5658
if [[ $? == 0 ]]; then
@@ -90,13 +92,13 @@ Disallow: /deny
9092
EOM
9193

9294
echo "[Test HTTP Request via Proxy]"
93-
CMD="curl -v $CURL_EXTRA_FLAGS -x $PROXY_URL http://httpbin.org/robots.txt"
95+
CMD="$CURL $CURL_EXTRA_FLAGS -x $PROXY_URL http://httpbin.org/robots.txt"
9496
RESPONSE=$($CMD 2> /dev/null)
9597
verify_response "$RESPONSE" "$ROBOTS_RESPONSE"
9698
VERIFIED1=$?
9799

98100
echo "[Test HTTPS Request via Proxy]"
99-
CMD="curl -v $CURL_EXTRA_FLAGS -x $PROXY_URL https://httpbin.org/robots.txt"
101+
CMD="$CURL $CURL_EXTRA_FLAGS -x $PROXY_URL https://httpbin.org/robots.txt"
100102
RESPONSE=$($CMD 2> /dev/null)
101103
verify_response "$RESPONSE" "$ROBOTS_RESPONSE"
102104
VERIFIED2=$?
@@ -105,7 +107,7 @@ if $USE_HTTPS; then
105107
VERIFIED3=0
106108
else
107109
echo "[Test Internal Web Server via Proxy]"
108-
curl -v \
110+
$CURL \
109111
$CURL_EXTRA_FLAGS \
110112
-x $PROXY_URL \
111113
"$PROXY_URL"
@@ -121,7 +123,7 @@ fi
121123
echo "[Test Download File Hash Verifies 1]"
122124
touch downloaded.hash
123125
echo "3d1921aab49d3464a712c1c1397b6babf8b461a9873268480aa8064da99441bc -" > downloaded.hash
124-
curl -vL \
126+
$CURL -L \
125127
$CURL_EXTRA_FLAGS \
126128
-o downloaded.whl \
127129
-x $PROXY_URL \
@@ -133,7 +135,7 @@ rm downloaded.whl downloaded.hash
133135
echo "[Test Download File Hash Verifies 2]"
134136
touch downloaded.hash
135137
echo "077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8 -" > downloaded.hash
136-
curl -vL \
138+
$CURL -L \
137139
$CURL_EXTRA_FLAGS \
138140
-o downloaded.whl \
139141
-x $PROXY_URL \

tests/test_circular_imports.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,15 @@ def _discover_path_importables(
8585
'import_path',
8686
_find_all_importables(proxy),
8787
)
88-
def test_no_warnings(import_path: str) -> None:
88+
# Marked as disabled_ because:
89+
# 1. This test case was added when isort integration was problematic
90+
# 2. This test case never found a real circular import scenario
91+
# 3. This test case consumes 60% of test suite runtime
92+
# 4. Kept in the repo because we might still want to enable
93+
# this in future, conditionally. Example, we can run
94+
# this only on a single OS and Python version combination
95+
# instead of running it across entire matrix.
96+
def disabled_test_no_warnings(import_path: str) -> None:
8997
"""Verify that exploding importables doesn't explode.
9098
9199
This is seeking for any import errors including ones caused

0 commit comments

Comments
 (0)