Skip to content

Commit a8e3966

Browse files
Put core flags where they belong (#702)
* Move flags to where they belong * Move `get_default_plugins` within FlagParser as it depends upon args TODO: We need plugin dependency system * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 7a415dc commit a8e3966

File tree

11 files changed

+206
-123
lines changed

11 files changed

+206
-123
lines changed

README.md

Lines changed: 88 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1870,70 +1870,125 @@ for list of tests.
18701870

18711871
```console
18721872
proxy -h
1873-
usage: proxy [-h] [--threadless] [--backlog BACKLOG] [--enable-events] [--hostname HOSTNAME] [--port PORT] [--num-workers NUM_WORKERS] [--client-recvbuf-size CLIENT_RECVBUF_SIZE] [--key-file KEY_FILE]
1874-
[--timeout TIMEOUT] [--pid-file PID_FILE] [--version] [--disable-http-proxy] [--enable-dashboard] [--enable-devtools] [--enable-static-server] [--enable-web-server] [--log-level LOG_LEVEL]
1875-
[--log-file LOG_FILE] [--log-format LOG_FORMAT] [--open-file-limit OPEN_FILE_LIMIT] [--plugins PLUGINS] [--ca-key-file CA_KEY_FILE] [--ca-cert-dir CA_CERT_DIR] [--ca-cert-file CA_CERT_FILE]
1876-
[--ca-file CA_FILE] [--ca-signing-key-file CA_SIGNING_KEY_FILE] [--cert-file CERT_FILE] [--disable-headers DISABLE_HEADERS] [--server-recvbuf-size SERVER_RECVBUF_SIZE] [--basic-auth BASIC_AUTH]
1877-
[--cache-dir CACHE_DIR] [--static-server-dir STATIC_SERVER_DIR] [--pac-file PAC_FILE] [--pac-file-url-path PAC_FILE_URL_PATH] [--filtered-client-ips FILTERED_CLIENT_IPS]
1873+
usage: proxy [-h] [--enable-events] [--enable-conn-pool] [--threadless] [--pid-file PID_FILE]
1874+
[--backlog BACKLOG] [--hostname HOSTNAME] [--port PORT] [--num-workers NUM_WORKERS]
1875+
[--unix-socket-path UNIX_SOCKET_PATH] [--client-recvbuf-size CLIENT_RECVBUF_SIZE]
1876+
[--key-file KEY_FILE] [--timeout TIMEOUT] [--version] [--log-level LOG_LEVEL]
1877+
[--log-file LOG_FILE] [--log-format LOG_FORMAT] [--open-file-limit OPEN_FILE_LIMIT]
1878+
[--plugins PLUGINS] [--disable-http-proxy] [--ca-key-file CA_KEY_FILE]
1879+
[--ca-cert-dir CA_CERT_DIR] [--ca-cert-file CA_CERT_FILE] [--ca-file CA_FILE]
1880+
[--ca-signing-key-file CA_SIGNING_KEY_FILE] [--cert-file CERT_FILE]
1881+
[--disable-headers DISABLE_HEADERS] [--server-recvbuf-size SERVER_RECVBUF_SIZE]
1882+
[--basic-auth BASIC_AUTH] [--cache-dir CACHE_DIR]
1883+
[--filtered-upstream-hosts FILTERED_UPSTREAM_HOSTS] [--enable-web-server]
1884+
[--enable-static-server] [--static-server-dir STATIC_SERVER_DIR]
1885+
[--pac-file PAC_FILE] [--pac-file-url-path PAC_FILE_URL_PATH]
1886+
[--filtered-client-ips FILTERED_CLIENT_IPS]
1887+
[--filtered-url-regex-config FILTERED_URL_REGEX_CONFIG]
1888+
[--cloudflare-dns-mode CLOUDFLARE_DNS_MODE]
18781889

18791890
proxy.py v2.4.0
18801891

18811892
options:
18821893
-h, --help show this help message and exit
1883-
--threadless Default: False. When disabled a new thread is spawned to handle each client connection.
1894+
--enable-events Default: False. Enables core to dispatch lifecycle events. Plugins
1895+
can be used to subscribe for core events.
1896+
--enable-conn-pool Default: False. (WIP) Enable upstream connection pooling.
1897+
--threadless Default: False. When disabled a new thread is spawned to handle each
1898+
client connection.
1899+
--pid-file PID_FILE Default: None. Save parent process ID to a file.
18841900
--backlog BACKLOG Default: 100. Maximum number of pending connections to proxy server
1885-
--enable-events Default: False. Enables core to dispatch lifecycle events. Plugins can be used to subscribe for core events.
18861901
--hostname HOSTNAME Default: ::1. Server IP address.
18871902
--port PORT Default: 8899. Server port.
18881903
--num-workers NUM_WORKERS
18891904
Defaults to number of CPU cores.
1905+
--unix-socket-path UNIX_SOCKET_PATH
1906+
Default: None. Unix socket path to use. When provided --host and
1907+
--port flags are ignored
18901908
--client-recvbuf-size CLIENT_RECVBUF_SIZE
1891-
Default: 1 MB. Maximum amount of data received from the client in a single recv() operation. Bump this value for faster uploads at the expense of increased RAM.
1892-
--key-file KEY_FILE Default: None. Server key file to enable end-to-end TLS encryption with clients. If used, must also pass --cert-file.
1893-
--timeout TIMEOUT Default: 10. Number of seconds after which an inactive connection must be dropped. Inactivity is defined by no data sent or received by the client.
1894-
--pid-file PID_FILE Default: None. Save parent process ID to a file.
1909+
Default: 1 MB. Maximum amount of data received from the client in a
1910+
single recv() operation. Bump this value for faster uploads at the
1911+
expense of increased RAM.
1912+
--key-file KEY_FILE Default: None. Server key file to enable end-to-end TLS encryption
1913+
with clients. If used, must also pass --cert-file.
1914+
--timeout TIMEOUT Default: 10.0. Number of seconds after which an inactive connection
1915+
must be dropped. Inactivity is defined by no data sent or received by
1916+
the client.
18951917
--version, -v Prints proxy.py version.
1896-
--disable-http-proxy Default: False. Whether to disable proxy.HttpProxyPlugin.
1897-
--enable-dashboard Default: False. Enables proxy.py dashboard.
1898-
--enable-devtools Default: False. Enables integration with Chrome Devtool Frontend. Also see --devtools-ws-path.
1899-
--enable-static-server
1900-
Default: False. Enable inbuilt static file server. Optionally, also use --static-server-dir to serve static content from custom directory. By default, static file server serves out of
1901-
installed proxy.py python module folder.
1902-
--enable-web-server Default: False. Whether to enable proxy.HttpWebServerPlugin.
19031918
--log-level LOG_LEVEL
1904-
Valid options: DEBUG, INFO (default), WARNING, ERROR, CRITICAL. Both upper and lowercase values are allowed. You may also simply use the leading character e.g. --log-level d
1919+
Valid options: DEBUG, INFO (default), WARNING, ERROR, CRITICAL. Both
1920+
upper and lowercase values are allowed. You may also simply use the
1921+
leading character e.g. --log-level d
19051922
--log-file LOG_FILE Default: sys.stdout. Log file destination.
19061923
--log-format LOG_FORMAT
19071924
Log format for Python logger.
19081925
--open-file-limit OPEN_FILE_LIMIT
1909-
Default: 1024. Maximum number of files (TCP connections) that proxy.py can open concurrently.
1926+
Default: 1024. Maximum number of files (TCP connections) that
1927+
proxy.py can open concurrently.
19101928
--plugins PLUGINS Comma separated plugins
1929+
--disable-http-proxy Default: False. Whether to disable proxy.HttpProxyPlugin.
19111930
--ca-key-file CA_KEY_FILE
1912-
Default: None. CA key to use for signing dynamically generated HTTPS certificates. If used, must also pass --ca-cert-file and --ca-signing-key-file
1931+
Default: None. CA key to use for signing dynamically generated HTTPS
1932+
certificates. If used, must also pass --ca-cert-file and --ca-
1933+
signing-key-file
19131934
--ca-cert-dir CA_CERT_DIR
1914-
Default: ~/.proxy.py. Directory to store dynamically generated certificates. Also see --ca-key-file, --ca-cert-file and --ca-signing-key-file
1935+
Default: ~/.proxy.py. Directory to store dynamically generated
1936+
certificates. Also see --ca-key-file, --ca-cert-file and --ca-
1937+
signing-key-file
19151938
--ca-cert-file CA_CERT_FILE
1916-
Default: None. Signing certificate to use for signing dynamically generated HTTPS certificates. If used, must also pass --ca-key-file and --ca-signing-key-file
1917-
--ca-file CA_FILE Default: None. Provide path to custom CA file for peer certificate validation. Specially useful on MacOS.
1939+
Default: None. Signing certificate to use for signing dynamically
1940+
generated HTTPS certificates. If used, must also pass --ca-key-file
1941+
and --ca-signing-key-file
1942+
--ca-file CA_FILE Default:
1943+
/Users/abhinavsingh/Dev/proxy.py/venv310/lib/python3.10/site-
1944+
packages/certifi/cacert.pem. Provide path to custom CA bundle for
1945+
peer certificate verification
19181946
--ca-signing-key-file CA_SIGNING_KEY_FILE
1919-
Default: None. CA signing key to use for dynamic generation of HTTPS certificates. If used, must also pass --ca-key-file and --ca-cert-file
1947+
Default: None. CA signing key to use for dynamic generation of HTTPS
1948+
certificates. If used, must also pass --ca-key-file and --ca-cert-
1949+
file
19201950
--cert-file CERT_FILE
1921-
Default: None. Server certificate to enable end-to-end TLS encryption with clients. If used, must also pass --key-file.
1951+
Default: None. Server certificate to enable end-to-end TLS encryption
1952+
with clients. If used, must also pass --key-file.
19221953
--disable-headers DISABLE_HEADERS
1923-
Default: None. Comma separated list of headers to remove before dispatching client request to upstream server.
1954+
Default: None. Comma separated list of headers to remove before
1955+
dispatching client request to upstream server.
19241956
--server-recvbuf-size SERVER_RECVBUF_SIZE
1925-
Default: 1 MB. Maximum amount of data received from the server in a single recv() operation. Bump this value for faster downloads at the expense of increased RAM.
1957+
Default: 1 MB. Maximum amount of data received from the server in a
1958+
single recv() operation. Bump this value for faster downloads at the
1959+
expense of increased RAM.
19261960
--basic-auth BASIC_AUTH
1927-
Default: No authentication. Specify colon separated user:password to enable basic authentication.
1961+
Default: No authentication. Specify colon separated user:password to
1962+
enable basic authentication.
19281963
--cache-dir CACHE_DIR
1929-
Default: A temporary directory. Flag only applicable when cache plugin is used with on-disk storage.
1964+
Default: A temporary directory. Flag only applicable when cache
1965+
plugin is used with on-disk storage.
1966+
--filtered-upstream-hosts FILTERED_UPSTREAM_HOSTS
1967+
Default: Blocks Facebook. Comma separated list of IPv4 and IPv6
1968+
addresses.
1969+
--enable-web-server Default: False. Whether to enable proxy.HttpWebServerPlugin.
1970+
--enable-static-server
1971+
Default: False. Enable inbuilt static file server. Optionally, also
1972+
use --static-server-dir to serve static content from custom
1973+
directory. By default, static file server serves out of installed
1974+
proxy.py python module folder.
19301975
--static-server-dir STATIC_SERVER_DIR
1931-
Default: "public" folder in directory where proxy.py is placed. This option is only applicable when static server is also enabled. See --enable-static-server.
1932-
--pac-file PAC_FILE A file (Proxy Auto Configuration) or string to serve when the server receives a direct file request. Using this option enables proxy.HttpWebServerPlugin.
1976+
Default: "public" folder in directory where proxy.py is placed. This
1977+
option is only applicable when static server is also enabled. See
1978+
--enable-static-server.
1979+
--pac-file PAC_FILE A file (Proxy Auto Configuration) or string to serve when the server
1980+
receives a direct file request. Using this option enables
1981+
proxy.HttpWebServerPlugin.
19331982
--pac-file-url-path PAC_FILE_URL_PATH
19341983
Default: /. Web server path to serve the PAC file.
19351984
--filtered-client-ips FILTERED_CLIENT_IPS
1936-
Default: 127.0.0.1,::1. Comma separated list of IPv4 and IPv6 addresses.
1985+
Default: 127.0.0.1,::1. Comma separated list of IPv4 and IPv6
1986+
addresses.
1987+
--filtered-url-regex-config FILTERED_URL_REGEX_CONFIG
1988+
Default: No config. Comma separated list of IPv4 and IPv6 addresses.
1989+
--cloudflare-dns-mode CLOUDFLARE_DNS_MODE
1990+
Default: security. Either "security" (for malware protection) or
1991+
"family" (for malware and adult content protection)
19371992

19381993
Proxy.py not working? Report at: https://github.com/abhinavsingh/proxy.py/issues/new
19391994
```

examples/pubsub_eventing.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414

1515
from typing import Dict, Any
1616

17-
from proxy.core.event import EventQueue, EventSubscriber, eventNames
18-
from proxy.core.event.manager import EventManager
17+
from proxy.core.event import EventManager, EventQueue, EventSubscriber, eventNames
1918

2019
# Enable debug logging to view core event logs
2120
logging.basicConfig(level=logging.DEBUG)

proxy/common/flag.py

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,19 @@
1414
import socket
1515
import argparse
1616
import ipaddress
17+
import collections
1718
import multiprocessing
1819

1920
from typing import Optional, List, Any, cast
2021

2122
from .types import IpAddress
2223
from .utils import text_, bytes_, setup_logger, is_py2, set_open_file_limit
23-
from .utils import get_default_plugins, import_plugin, load_plugins
24+
from .utils import import_plugin, load_plugins
2425
from .constants import COMMA, DEFAULT_DATA_DIRECTORY_PATH, DEFAULT_NUM_WORKERS
2526
from .constants import DEFAULT_DEVTOOLS_WS_PATH, DEFAULT_DISABLE_HEADERS, PY2_DEPRECATION_MESSAGE
27+
from .constants import PLUGIN_DASHBOARD, PLUGIN_DEVTOOLS_PROTOCOL
28+
from .constants import PLUGIN_HTTP_PROXY, PLUGIN_INSPECT_TRAFFIC, PLUGIN_PAC_FILE
29+
from .constants import PLUGIN_WEB_SERVER, PLUGIN_PROXY_AUTH
2630

2731
from .version import __version__
2832

@@ -110,7 +114,10 @@ def initialize(
110114
set_open_file_limit(args.open_file_limit)
111115

112116
# Load plugins
113-
default_plugins = [bytes_(p) for p in get_default_plugins(args)]
117+
default_plugins = [
118+
bytes_(p)
119+
for p in FlagParser.get_default_plugins(args)
120+
]
114121
extra_plugins = [
115122
p if isinstance(p, type) else bytes_(p)
116123
for p in opts.get('plugins', args.plugins.split(text_(COMMA)))
@@ -289,5 +296,35 @@ def initialize(
289296

290297
return args
291298

299+
@staticmethod
300+
def get_default_plugins(
301+
args: argparse.Namespace,
302+
) -> List[str]:
303+
"""Prepare list of plugins to load based upon
304+
--enable-*, --disable-* and --basic-auth flags.
305+
"""
306+
default_plugins: List[str] = []
307+
if args.basic_auth is not None:
308+
default_plugins.append(PLUGIN_PROXY_AUTH)
309+
if hasattr(args, 'enable_dashboard') and args.enable_dashboard:
310+
default_plugins.append(PLUGIN_WEB_SERVER)
311+
args.enable_static_server = True
312+
default_plugins.append(PLUGIN_DASHBOARD)
313+
default_plugins.append(PLUGIN_INSPECT_TRAFFIC)
314+
args.enable_events = True
315+
args.enable_devtools = True
316+
if hasattr(args, 'enable_devtools') and args.enable_devtools:
317+
default_plugins.append(PLUGIN_DEVTOOLS_PROTOCOL)
318+
default_plugins.append(PLUGIN_WEB_SERVER)
319+
if not args.disable_http_proxy:
320+
default_plugins.append(PLUGIN_HTTP_PROXY)
321+
if args.enable_web_server or \
322+
args.pac_file is not None or \
323+
args.enable_static_server:
324+
default_plugins.append(PLUGIN_WEB_SERVER)
325+
if args.pac_file is not None:
326+
default_plugins.append(PLUGIN_PAC_FILE)
327+
return list(collections.OrderedDict.fromkeys(default_plugins).keys())
328+
292329

293330
flags = FlagParser()

proxy/common/utils.py

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,17 @@
1515
import socket
1616
import logging
1717
import inspect
18-
import argparse
1918
import importlib
2019
import functools
2120
import ipaddress
2221
import contextlib
23-
import collections
2422

2523
from types import TracebackType
2624
from typing import Optional, Dict, Any, List, Tuple, Type, Callable, Union
2725

2826
from .constants import HTTP_1_1, COLON, WHITESPACE, CRLF, DEFAULT_TIMEOUT
2927
from .constants import DEFAULT_LOG_FILE, DEFAULT_LOG_FORMAT, DEFAULT_LOG_LEVEL
30-
from .constants import DOT, PLUGIN_DASHBOARD, PLUGIN_DEVTOOLS_PROTOCOL
31-
from .constants import PLUGIN_HTTP_PROXY, PLUGIN_INSPECT_TRAFFIC, PLUGIN_PAC_FILE
32-
from .constants import PLUGIN_WEB_SERVER, PLUGIN_PROXY_AUTH
28+
from .constants import DOT
3329

3430
if os.name != 'nt':
3531
import resource
@@ -338,36 +334,6 @@ def import_plugin(plugin: Union[bytes, type]) -> Any:
338334
return (klass, module_name)
339335

340336

341-
def get_default_plugins(
342-
args: argparse.Namespace,
343-
) -> List[str]:
344-
"""Prepare list of plugins to load based upon
345-
--enable-*, --disable-* and --basic-auth flags.
346-
"""
347-
default_plugins: List[str] = []
348-
if args.basic_auth is not None:
349-
default_plugins.append(PLUGIN_PROXY_AUTH)
350-
if args.enable_dashboard:
351-
default_plugins.append(PLUGIN_WEB_SERVER)
352-
args.enable_static_server = True
353-
default_plugins.append(PLUGIN_DASHBOARD)
354-
default_plugins.append(PLUGIN_INSPECT_TRAFFIC)
355-
args.enable_events = True
356-
args.enable_devtools = True
357-
if args.enable_devtools:
358-
default_plugins.append(PLUGIN_DEVTOOLS_PROTOCOL)
359-
default_plugins.append(PLUGIN_WEB_SERVER)
360-
if not args.disable_http_proxy:
361-
default_plugins.append(PLUGIN_HTTP_PROXY)
362-
if args.enable_web_server or \
363-
args.pac_file is not None or \
364-
args.enable_static_server:
365-
default_plugins.append(PLUGIN_WEB_SERVER)
366-
if args.pac_file is not None:
367-
default_plugins.append(PLUGIN_PAC_FILE)
368-
return list(collections.OrderedDict.fromkeys(default_plugins).keys())
369-
370-
371337
def set_open_file_limit(soft_limit: int) -> None:
372338
"""Configure open file description soft limit on supported OS."""
373339
if os.name != 'nt': # resource module not available on Windows OS

proxy/core/acceptor/pool.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from ...common.flag import flags
2929
from ...common.constants import DEFAULT_BACKLOG, DEFAULT_IPV6_HOSTNAME
3030
from ...common.constants import DEFAULT_NUM_WORKERS, DEFAULT_PORT
31+
from ...common.constants import DEFAULT_PID_FILE
3132

3233
logger = logging.getLogger(__name__)
3334

@@ -36,6 +37,13 @@
3637
LOCK = multiprocessing.Lock()
3738

3839

40+
flags.add_argument(
41+
'--pid-file',
42+
type=str,
43+
default=DEFAULT_PID_FILE,
44+
help='Default: None. Save parent process ID to a file.',
45+
)
46+
3947
flags.add_argument(
4048
'--backlog',
4149
type=int,

proxy/core/event/manager.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,21 @@
1717
from .queue import EventQueue
1818
from .dispatcher import EventDispatcher
1919

20+
from ...common.flag import flags
21+
from ...common.constants import DEFAULT_ENABLE_EVENTS
22+
2023
logger = logging.getLogger(__name__)
2124

2225

26+
flags.add_argument(
27+
'--enable-events',
28+
action='store_true',
29+
default=DEFAULT_ENABLE_EVENTS,
30+
help='Default: False. Enables core to dispatch lifecycle events. '
31+
'Plugins can be used to subscribe for core events.',
32+
)
33+
34+
2335
class EventManager:
2436
"""Event manager is an encapsulation around various initialization, dispatcher
2537
start / stop API required for end-to-end eventing.

proxy/dashboard/dashboard.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414

1515
from .plugin import ProxyDashboardWebsocketPlugin
1616

17+
from ..common.flag import flags
1718
from ..common.utils import build_http_response, bytes_
19+
from ..common.constants import DEFAULT_ENABLE_DASHBOARD
1820
from ..http.server import HttpWebServerPlugin, HttpWebServerBasePlugin, httpProtocolTypes
1921
from ..http.parser import HttpParser
2022
from ..http.websocket import WebsocketFrame
@@ -23,6 +25,14 @@
2325
logger = logging.getLogger(__name__)
2426

2527

28+
flags.add_argument(
29+
'--enable-dashboard',
30+
action='store_true',
31+
default=DEFAULT_ENABLE_DASHBOARD,
32+
help='Default: False. Enables proxy.py dashboard.',
33+
)
34+
35+
2636
class ProxyDashboard(HttpWebServerBasePlugin):
2737
"""Proxy Dashboard."""
2838

0 commit comments

Comments
 (0)