From 131e9366ac7890373c194718b4687e67ff61cfe5 Mon Sep 17 00:00:00 2001 From: Abhinav Singh Date: Fri, 15 Nov 2019 14:47:50 -0800 Subject: [PATCH] Move plugin_examples/ as proxy.plugin and update readme (#179) * Update dev guide * Move plugin_examples/ as proxy.plugin * Update proxy.plugin ref path in readme * Remove unnecessary port flag * Remove plugin_examples from github workflows * dashboard folder is a npm package not python package anymore * Plugins can now be tried using Docker image --- .github/workflows/test-library.yml | 4 +- Dockerfile | 3 +- Makefile | 5 +- README.md | 73 ++++++++-------- dashboard/__init__.py | 10 --- plugin_examples/README.md | 1 - plugin_examples/__init__.py | 10 --- plugin_examples/setup.py | 87 ------------------- proxy/common/flags.py | 2 +- proxy/plugin/__init__.py | 29 +++++++ .../plugin}/cache_responses.py | 6 +- .../plugin}/filter_by_upstream.py | 8 +- .../plugin}/man_in_the_middle.py | 8 +- .../plugin}/mock_rest_api.py | 8 +- .../plugin}/modify_post_data.py | 8 +- .../plugin}/redirect_to_custom_server.py | 6 +- .../plugin}/shortlink.py | 10 +-- .../plugin}/web_server_route.py | 10 +-- setup.py | 9 +- tests/http/test_http_proxy_examples.py | 11 ++- tests/http/utils.py | 22 ++--- 21 files changed, 125 insertions(+), 205 deletions(-) delete mode 100644 dashboard/__init__.py delete mode 100644 plugin_examples/README.md delete mode 100644 plugin_examples/__init__.py delete mode 100644 plugin_examples/setup.py create mode 100644 proxy/plugin/__init__.py rename {plugin_examples => proxy/plugin}/cache_responses.py (92%) rename {plugin_examples => proxy/plugin}/filter_by_upstream.py (86%) rename {plugin_examples => proxy/plugin}/man_in_the_middle.py (83%) rename {plugin_examples => proxy/plugin}/mock_rest_api.py (92%) rename {plugin_examples => proxy/plugin}/modify_post_data.py (89%) rename {plugin_examples => proxy/plugin}/redirect_to_custom_server.py (91%) rename {plugin_examples => proxy/plugin}/shortlink.py (91%) rename {plugin_examples => proxy/plugin}/web_server_route.py (84%) diff --git a/.github/workflows/test-library.yml b/.github/workflows/test-library.yml index f81f718f..6b957fc2 100644 --- a/.github/workflows/test-library.yml +++ b/.github/workflows/test-library.yml @@ -25,8 +25,8 @@ jobs: pip install -r requirements-testing.txt - name: Quality Check run: | - flake8 --ignore=W504 --max-line-length=127 proxy/ tests/ benchmark/ plugin_examples/ setup.py - mypy --strict --ignore-missing-imports proxy/ tests/ benchmark/ plugin_examples/ setup.py + flake8 --ignore=W504 --max-line-length=127 proxy/ tests/ benchmark/ setup.py + mypy --strict --ignore-missing-imports proxy/ tests/ benchmark/ setup.py - name: Run Tests run: pytest --cov=proxy tests/ - name: Upload coverage to Codecov diff --git a/Dockerfile b/Dockerfile index 3b94c1de..520ba988 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,5 +21,4 @@ COPY --from=builder /deps /usr/local EXPOSE 8899/tcp ENTRYPOINT [ "proxy" ] -CMD [ "--hostname=0.0.0.0", \ - "--port=8899" ] +CMD [ "--hostname=0.0.0.0" ] diff --git a/Makefile b/Makefile index 9bf47dcd..5f0ac041 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,6 @@ autopep8: autopep8 --recursive --in-place --aggressive proxy/*.py autopep8 --recursive --in-place --aggressive proxy/*/*.py autopep8 --recursive --in-place --aggressive tests/*.py - autopep8 --recursive --in-place --aggressive plugin_examples/*.py autopep8 --recursive --in-place --aggressive benchmark/*.py autopep8 --recursive --in-place --aggressive setup.py @@ -59,8 +58,8 @@ lib-clean: rm -rf .hypothesis lib-lint: - flake8 --ignore=W504 --max-line-length=127 proxy/ tests/ benchmark/ plugin_examples/ setup.py - mypy --strict --ignore-missing-imports proxy/ tests/ benchmark/ plugin_examples/ setup.py + flake8 --ignore=W504 --max-line-length=127 proxy/ tests/ benchmark/ setup.py + mypy --strict --ignore-missing-imports proxy/ tests/ benchmark/ setup.py lib-test: lib-lint python -m unittest discover diff --git a/README.md b/README.md index a944fc02..b96c7136 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,10 @@ Table of Contents * [Everything is a plugin](#everything-is-a-plugin) * [Internal Architecture](#internal-architecture) * [Internal Documentation](#internal-documentation) - * [Sending a Pull Request](#sending-a-pull-request) + * [Development Guide](#development-guide) + * [Setup Local Environment](#setup-local-environment) + * [Setup pre-commit hook](#setup-pre-commit-hook) + * [Sending a Pull Request](#sending-a-pull-request) * [Utilities](#utilities) * [TCP](#tcp-sockets) * [new_socket_connection](#new_socket_connection) @@ -120,8 +123,8 @@ Features - No external dependency other than standard Python library - Programmable - Optionally enable builtin Web Server - - Customize proxy and http routing via [plugins](https://github.com/abhinavsingh/proxy.py/blob/develop/plugin_examples) - - Enable plugin using command line option e.g. `--plugins plugin_examples/cache_responses.CacheResponsesPlugin` + - Customize proxy and http routing via [plugins](https://github.com/abhinavsingh/proxy.py/tree/develop/proxy/plugin) + - Enable plugin using command line option e.g. `--plugins proxy.plugin.CacheResponsesPlugin` - Plugin API is currently in development phase, expect breaking changes. - Realtime Dashboard - Optionally enable bundled dashboard. @@ -300,10 +303,12 @@ For example, to check `proxy.py` version within Docker image: Plugin Examples =============== -See [plugin_examples](https://github.com/abhinavsingh/proxy.py/tree/develop/plugin_examples) for full code. - -All the examples below also works with `https` traffic but require additional flags and certificate generation. -See [TLS Interception](#tls-interception). +- See [plugin](https://github.com/abhinavsingh/proxy.py/tree/develop/proxy/plugin) module for full code. +- All the bundled plugin examples also works with `https` traffic + - Require additional flags and certificate generation + - See [TLS Interception](#tls-interception). +- Plugin examples are also bundled with Docker image. + - See [Customize startup flags](#customize-startup-flags) to try plugins with Docker image. ## ShortLinkPlugin @@ -313,7 +318,7 @@ Start `proxy.py` as: ``` $ proxy \ - --plugins plugin_examples/shortlink.ShortLinkPlugin + --plugins proxy.plugin.ShortLinkPlugin ``` Now you can speed up your daily browsing experience by visiting your @@ -342,7 +347,7 @@ Start `proxy.py` as: ``` $ proxy \ - --plugins plugin_examples/modify_post_data.ModifyPostDataPlugin + --plugins proxy.plugin.ModifyPostDataPlugin ``` By default plugin replaces POST body content with hardcoded `b'{"key": "modified"}'` @@ -396,7 +401,7 @@ Start `proxy.py` as: ``` $ proxy \ - --plugins plugin_examples/mock_rest_api.ProposedRestApiPlugin + --plugins proxy.plugin.ProposedRestApiPlugin ``` Verify mock API response using `curl -x localhost:8899 http://api.example.com/v1/users/` @@ -428,7 +433,7 @@ Start `proxy.py` and enable inbuilt web server: ``` $ proxy \ --enable-web-server \ - --plugins plugin_examples/redirect_to_custom_server.RedirectToCustomServerPlugin + --plugins proxy.plugin.RedirectToCustomServerPlugin ``` Verify using `curl -v -x localhost:8899 http://google.com` @@ -461,7 +466,7 @@ Start `proxy.py` as: ``` $ proxy \ - --plugins plugin_examples/filter_by_upstream.FilterByUpstreamHostPlugin + --plugins proxy.plugin.FilterByUpstreamHostPlugin ``` Verify using `curl -v -x localhost:8899 http://google.com`: @@ -494,7 +499,7 @@ Start `proxy.py` as: ``` $ proxy \ - --plugins plugin_examples/cache_responses.CacheResponsesPlugin + --plugins proxy.plugin.CacheResponsesPlugin ``` Verify using `curl -v -x localhost:8899 http://httpbin.org/get`: @@ -570,7 +575,7 @@ Start `proxy.py` as: ``` $ proxy \ - --plugins plugin_examples/man_in_the_middle.ManInTheMiddlePlugin + --plugins proxy.plugin.ManInTheMiddlePlugin ``` Verify using `curl -v -x localhost:8899 http://google.com`: @@ -652,7 +657,7 @@ response from the server. Start `proxy.py` as: ``` $ proxy \ - --plugins plugin_examples/cache_responses.CacheResponsesPlugin \ + --plugins proxy.plugin.CacheResponsesPlugin \ --ca-key-file ca-key.pem \ --ca-cert-file ca-cert.pem \ --ca-signing-key-file ca-signing-key.pem @@ -861,10 +866,6 @@ class TestProxyPyEmbedded(unittest.TestCase): Plugin Developer and Contributor Guide ====================================== -Contributors must start `proxy.py` from source to verify and develop new features / fixes. - -See [Run proxy.py from command line using repo source](#from-command-line-using-repo-source) for details. - ## Everything is a plugin As you might have guessed by now, in `proxy.py` everything is a plugin. @@ -912,25 +913,25 @@ and invoke `HttpProxyBasePlugin` lifecycle hooks. Workers are responsible for accepting new client connections and starting `HttpProtocolHandler` thread. -## Sending a Pull Request +## Development Guide -Install dependencies for local development testing: +#### Setup Local Environment -`$ pip install -r requirements-testing.txt` +Contributors must start `proxy.py` from source to verify and develop new features / fixes. +See [Run proxy.py from command line using repo source](#from-command-line-using-repo-source) for details. -Every pull request goes through set of tests which must pass: +#### Setup pre-commit hook -- `mypy`: Run `make lint` locally for compliance check. - Fix all warnings and errors before sending out a PR. +1. `cd /path/to/proxy.py` +2. `ln -s $(PWD)/git-pre-commit .git/hooks/pre-commit` -- `coverage`: Run `make coverage` locally for coverage report. - Its ideal to add tests for any critical change. Depending upon - the change, it's ok if test coverage falls by `<0.5%`. +Pre-commit hook ensures lint checking and library tests passes. -- `formatting`: Run `make autopep8` locally to format the code in-place. - `autopep8` is run with `--aggresive` flag. Sometimes it _may_ result in - weird formatting. But let's stick to one consistent formatting tool. - I am open to flag changes for `autopep8`. +#### Sending a Pull Request + +Every pull request is tested using GitHub actions. +See [GitHub workflow](https://github.com/abhinavsingh/proxy.py/tree/develop/.github/workflows) +for list of tests. ## Utilities @@ -1051,12 +1052,10 @@ Make sure plugin modules are discoverable by adding them to `PYTHONPATH`. Examp ...[redacted]... - Loaded plugin my_app.proxyPlugin ``` -or, make sure to pass fully-qualified path as parameter, e.g. +OR, simply pass fully-qualified path as parameter, e.g. `proxy --plugins /path/to/my/app/my_app.proxyPlugin` -Note that `pip install proxy.py` don't ship [plugin_examples](https://github.com/abhinavsingh/proxy.py/blob/develop/plugin_examples). - ## Unable to connect with proxy.py from remote host Make sure `proxy.py` is listening on correct network interface. @@ -1108,7 +1107,6 @@ Now `proxy.py` logs can be browsed using without any socket leaks. 1. Make use of `--open-file-limit` flag to customize `ulimit -n`. - - To set a value upper than the hard limit, run as root. 2. Make sure to adjust `--backlog` flag for higher concurrency. If nothing helps, [open an issue](https://github.com/abhinavsingh/proxy.py/issues/new) @@ -1131,7 +1129,7 @@ usage: proxy [-h] [--backlog BACKLOG] [--basic-auth BASIC_AUTH] [--client-recvbuf-size CLIENT_RECVBUF_SIZE] [--devtools-ws-path DEVTOOLS_WS_PATH] [--disable-headers DISABLE_HEADERS] [--disable-http-proxy] - [--enable-devtools] [--enable-events] + [--enable-dashboard] [--enable-devtools] [--enable-events] [--enable-static-server] [--enable-web-server] [--hostname HOSTNAME] [--key-file KEY_FILE] [--log-level LOG_LEVEL] [--log-file LOG_FILE] @@ -1186,6 +1184,7 @@ optional arguments: server. --disable-http-proxy Default: False. Whether to disable proxy.HttpProxyPlugin. + --enable-dashboard Default: False. Enables proxy.py dashboard. --enable-devtools Default: False. Enables integration with Chrome Devtool Frontend. Also see --devtools-ws-path. --enable-events Default: False. Enables core to dispatch lifecycle diff --git a/dashboard/__init__.py b/dashboard/__init__.py deleted file mode 100644 index 87af9183..00000000 --- a/dashboard/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -""" - proxy.py - ~~~~~~~~ - ⚡⚡⚡ Fast, Lightweight, Programmable, TLS interception capable - proxy server for Application debugging, testing and development. - - :copyright: (c) 2013-present by Abhinav Singh and contributors. - :license: BSD, see LICENSE for more details. -""" diff --git a/plugin_examples/README.md b/plugin_examples/README.md deleted file mode 100644 index 34f725ca..00000000 --- a/plugin_examples/README.md +++ /dev/null @@ -1 +0,0 @@ -# Proxy.py Plugins diff --git a/plugin_examples/__init__.py b/plugin_examples/__init__.py deleted file mode 100644 index 87af9183..00000000 --- a/plugin_examples/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -""" - proxy.py - ~~~~~~~~ - ⚡⚡⚡ Fast, Lightweight, Programmable, TLS interception capable - proxy server for Application debugging, testing and development. - - :copyright: (c) 2013-present by Abhinav Singh and contributors. - :license: BSD, see LICENSE for more details. -""" diff --git a/plugin_examples/setup.py b/plugin_examples/setup.py deleted file mode 100644 index 5e23a56e..00000000 --- a/plugin_examples/setup.py +++ /dev/null @@ -1,87 +0,0 @@ -# -*- coding: utf-8 -*- -""" - proxy.py - ~~~~~~~~ - ⚡⚡⚡ Fast, Lightweight, Programmable, TLS interception capable - proxy server for Application debugging, testing and development. - - :copyright: (c) 2013-present by Abhinav Singh and contributors. - :license: BSD, see LICENSE for more details. -""" -from setuptools import setup, find_packages - -VERSION = (0, 1, 0) -__version__ = '.'.join(map(str, VERSION[0:3])) -__description__ = '⚡⚡⚡ Fast, Lightweight, Programmable Proxy Server in a single Python file.' -__author__ = 'Abhinav Singh' -__author_email__ = 'mailsforabhinav@gmail.com' -__homepage__ = 'https://github.com/abhinavsingh/proxy.py' -__download_url__ = '%s/archive/master.zip' % __homepage__ -__license__ = 'BSD' - -setup( - name='proxy.py-plugins', - version=__version__, - author=__author__, - author_email=__author_email__, - url=__homepage__, - description=__description__, - long_description=open('README.md').read().strip(), - long_description_content_type='text/markdown', - download_url=__download_url__, - license=__license__, - packages=find_packages(), - install_requires=['proxy.py'], - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Environment :: No Input/Output (Daemon)', - 'Environment :: Web Environment', - 'Environment :: MacOS X', - 'Environment :: Plugins', - 'Environment :: Win32 (MS Windows)', - 'Framework :: Robot Framework', - 'Framework :: Robot Framework :: Library', - 'Intended Audience :: Developers', - 'Intended Audience :: Education', - 'Intended Audience :: End Users/Desktop', - 'Intended Audience :: System Administrators', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: BSD License', - 'Natural Language :: English', - 'Operating System :: MacOS', - 'Operating System :: MacOS :: MacOS 9', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: POSIX', - 'Operating System :: POSIX :: Linux', - 'Operating System :: Unix', - 'Operating System :: Microsoft', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: Microsoft :: Windows :: Windows 10', - 'Operating System :: Android', - 'Operating System :: OS Independent', - 'Programming Language :: Python :: Implementation', - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Topic :: Internet', - 'Topic :: Internet :: Proxy Servers', - 'Topic :: Internet :: WWW/HTTP', - 'Topic :: Internet :: WWW/HTTP :: Browsers', - 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', - 'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries', - 'Topic :: Internet :: WWW/HTTP :: HTTP Servers', - 'Topic :: Scientific/Engineering :: Information Analysis', - 'Topic :: Software Development :: Debuggers', - 'Topic :: Software Development :: Libraries :: Python Modules', - 'Topic :: System :: Monitoring', - 'Topic :: System :: Networking', - 'Topic :: System :: Networking :: Firewalls', - 'Topic :: System :: Networking :: Monitoring', - 'Topic :: Utilities', - 'Typing :: Typed', - ], -) diff --git a/proxy/common/flags.py b/proxy/common/flags.py index 7b12411d..1041e893 100644 --- a/proxy/common/flags.py +++ b/proxy/common/flags.py @@ -251,7 +251,7 @@ class Flags: args.enable_events)), plugins=Flags.load_plugins( bytes_( - '%s%s' % + '%s,%s' % (text_(COMMA).join(collections.OrderedDict(default_plugins).keys()), opts.get('plugins', args.plugins)))), pid_file=cast(Optional[str], opts.get('pid_file', args.pid_file))) diff --git a/proxy/plugin/__init__.py b/proxy/plugin/__init__.py new file mode 100644 index 00000000..1a88565c --- /dev/null +++ b/proxy/plugin/__init__.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +""" + proxy.py + ~~~~~~~~ + ⚡⚡⚡ Fast, Lightweight, Programmable, TLS interception capable + proxy server for Application debugging, testing and development. + + :copyright: (c) 2013-present by Abhinav Singh and contributors. + :license: BSD, see LICENSE for more details. +""" +from .cache_responses import CacheResponsesPlugin +from .filter_by_upstream import FilterByUpstreamHostPlugin +from .man_in_the_middle import ManInTheMiddlePlugin +from .mock_rest_api import ProposedRestApiPlugin +from .modify_post_data import ModifyPostDataPlugin +from .redirect_to_custom_server import RedirectToCustomServerPlugin +from .shortlink import ShortLinkPlugin +from .web_server_route import WebServerPlugin + +__all__ = [ + 'CacheResponsesPlugin', + 'FilterByUpstreamHostPlugin', + 'ManInTheMiddlePlugin', + 'ProposedRestApiPlugin', + 'ModifyPostDataPlugin', + 'RedirectToCustomServerPlugin', + 'ShortLinkPlugin', + 'WebServerPlugin', +] diff --git a/plugin_examples/cache_responses.py b/proxy/plugin/cache_responses.py similarity index 92% rename from plugin_examples/cache_responses.py rename to proxy/plugin/cache_responses.py index 63e5c61b..d09cd1fa 100644 --- a/plugin_examples/cache_responses.py +++ b/proxy/plugin/cache_responses.py @@ -14,9 +14,9 @@ import time import logging from typing import Optional, BinaryIO, Any -from proxy.http.parser import HttpParser -from proxy.http.proxy import HttpProxyBasePlugin -from proxy.common.utils import text_ +from ..common.utils import text_ +from ..http.parser import HttpParser +from ..http.proxy import HttpProxyBasePlugin logger = logging.getLogger(__name__) diff --git a/plugin_examples/filter_by_upstream.py b/proxy/plugin/filter_by_upstream.py similarity index 86% rename from plugin_examples/filter_by_upstream.py rename to proxy/plugin/filter_by_upstream.py index 5dbe0fd7..0cbe01c0 100644 --- a/plugin_examples/filter_by_upstream.py +++ b/proxy/plugin/filter_by_upstream.py @@ -10,10 +10,10 @@ """ from typing import Optional -from proxy.http.proxy import HttpProxyBasePlugin -from proxy.http.exception import HttpRequestRejected -from proxy.http.parser import HttpParser -from proxy.http.codes import httpStatusCodes +from ..http.exception import HttpRequestRejected +from ..http.parser import HttpParser +from ..http.codes import httpStatusCodes +from ..http.proxy import HttpProxyBasePlugin class FilterByUpstreamHostPlugin(HttpProxyBasePlugin): diff --git a/plugin_examples/man_in_the_middle.py b/proxy/plugin/man_in_the_middle.py similarity index 83% rename from plugin_examples/man_in_the_middle.py rename to proxy/plugin/man_in_the_middle.py index f083ce89..ec00fe46 100644 --- a/plugin_examples/man_in_the_middle.py +++ b/proxy/plugin/man_in_the_middle.py @@ -10,10 +10,10 @@ """ from typing import Optional -from proxy.http.proxy import HttpProxyBasePlugin -from proxy.http.parser import HttpParser -from proxy.http.codes import httpStatusCodes -from proxy.common.utils import build_http_response +from ..common.utils import build_http_response +from ..http.parser import HttpParser +from ..http.codes import httpStatusCodes +from ..http.proxy import HttpProxyBasePlugin class ManInTheMiddlePlugin(HttpProxyBasePlugin): diff --git a/plugin_examples/mock_rest_api.py b/proxy/plugin/mock_rest_api.py similarity index 92% rename from plugin_examples/mock_rest_api.py rename to proxy/plugin/mock_rest_api.py index 2eab7f15..234c7c0f 100644 --- a/plugin_examples/mock_rest_api.py +++ b/proxy/plugin/mock_rest_api.py @@ -11,10 +11,10 @@ import json from typing import Optional -from proxy.http.parser import HttpParser -from proxy.http.proxy import HttpProxyBasePlugin -from proxy.http.codes import httpStatusCodes -from proxy.common.utils import bytes_, build_http_response, text_ +from ..common.utils import bytes_, build_http_response, text_ +from ..http.parser import HttpParser +from ..http.proxy import HttpProxyBasePlugin +from ..http.codes import httpStatusCodes class ProposedRestApiPlugin(HttpProxyBasePlugin): diff --git a/plugin_examples/modify_post_data.py b/proxy/plugin/modify_post_data.py similarity index 89% rename from plugin_examples/modify_post_data.py rename to proxy/plugin/modify_post_data.py index 324742ec..9b46f385 100644 --- a/plugin_examples/modify_post_data.py +++ b/proxy/plugin/modify_post_data.py @@ -10,10 +10,10 @@ """ from typing import Optional -from proxy.http.parser import HttpParser -from proxy.http.proxy import HttpProxyBasePlugin -from proxy.http.methods import httpMethods -from proxy.common.utils import bytes_ +from ..common.utils import bytes_ +from ..http.parser import HttpParser +from ..http.proxy import HttpProxyBasePlugin +from ..http.methods import httpMethods class ModifyPostDataPlugin(HttpProxyBasePlugin): diff --git a/plugin_examples/redirect_to_custom_server.py b/proxy/plugin/redirect_to_custom_server.py similarity index 91% rename from plugin_examples/redirect_to_custom_server.py rename to proxy/plugin/redirect_to_custom_server.py index d93a2d85..7de29295 100644 --- a/plugin_examples/redirect_to_custom_server.py +++ b/proxy/plugin/redirect_to_custom_server.py @@ -11,9 +11,9 @@ from urllib import parse as urlparse from typing import Optional -from proxy.http.proxy import HttpProxyBasePlugin -from proxy.http.parser import HttpParser -from proxy.http.methods import httpMethods +from ..http.proxy import HttpProxyBasePlugin +from ..http.parser import HttpParser +from ..http.methods import httpMethods class RedirectToCustomServerPlugin(HttpProxyBasePlugin): diff --git a/plugin_examples/shortlink.py b/proxy/plugin/shortlink.py similarity index 91% rename from plugin_examples/shortlink.py rename to proxy/plugin/shortlink.py index 70d5b270..d5fead85 100644 --- a/plugin_examples/shortlink.py +++ b/proxy/plugin/shortlink.py @@ -10,11 +10,11 @@ """ from typing import Optional -from proxy.http.proxy import HttpProxyBasePlugin -from proxy.http.parser import HttpParser -from proxy.http.codes import httpStatusCodes -from proxy.common.constants import DOT, SLASH -from proxy.common.utils import build_http_response +from ..common.constants import DOT, SLASH +from ..common.utils import build_http_response +from ..http.parser import HttpParser +from ..http.codes import httpStatusCodes +from ..http.proxy import HttpProxyBasePlugin class ShortLinkPlugin(HttpProxyBasePlugin): diff --git a/plugin_examples/web_server_route.py b/proxy/plugin/web_server_route.py similarity index 84% rename from plugin_examples/web_server_route.py rename to proxy/plugin/web_server_route.py index ffb4aa65..476221be 100644 --- a/plugin_examples/web_server_route.py +++ b/proxy/plugin/web_server_route.py @@ -11,11 +11,11 @@ import logging from typing import List, Tuple -from proxy.http.server import HttpWebServerBasePlugin, httpProtocolTypes -from proxy.http.websocket import WebsocketFrame -from proxy.http.parser import HttpParser -from proxy.http.codes import httpStatusCodes -from proxy.common.utils import build_http_response +from ..common.utils import build_http_response +from ..http.parser import HttpParser +from ..http.codes import httpStatusCodes +from ..http.websocket import WebsocketFrame +from ..http.server import HttpWebServerBasePlugin, httpProtocolTypes logger = logging.getLogger(__name__) diff --git a/setup.py b/setup.py index 5adf6d64..4bc8620f 100644 --- a/setup.py +++ b/setup.py @@ -30,7 +30,14 @@ setup( long_description_content_type='text/markdown', download_url=__download_url__, license=__license__, - packages=['proxy', 'proxy.common', 'proxy.core', 'proxy.http'], + packages=[ + 'proxy', + 'proxy.common', + 'proxy.core', + 'proxy.dashboard', + 'proxy.http', + 'proxy.plugin' + ], install_requires=open('requirements.txt', 'r').read().strip().split(), entry_points={ 'console_scripts': [ diff --git a/tests/http/test_http_proxy_examples.py b/tests/http/test_http_proxy_examples.py index b90eba24..994e9059 100644 --- a/tests/http/test_http_proxy_examples.py +++ b/tests/http/test_http_proxy_examples.py @@ -22,8 +22,7 @@ from proxy.common.utils import build_http_request, bytes_, build_http_response from proxy.common.constants import PROXY_AGENT_HEADER_VALUE from proxy.http.codes import httpStatusCodes -from plugin_examples import mock_rest_api -from plugin_examples import redirect_to_custom_server +from proxy.plugin import ProposedRestApiPlugin, RedirectToCustomServerPlugin from .utils import get_plugin_by_test_name @@ -97,9 +96,9 @@ class TestHttpProxyPluginExamples(unittest.TestCase): path = b'/v1/users/' self._conn.recv.return_value = build_http_request( b'GET', b'http://%s%s' % ( - mock_rest_api.ProposedRestApiPlugin.API_SERVER, path), + ProposedRestApiPlugin.API_SERVER, path), headers={ - b'Host': mock_rest_api.ProposedRestApiPlugin.API_SERVER, + b'Host': ProposedRestApiPlugin.API_SERVER, } ) self.mock_selector.return_value.select.side_effect = [ @@ -118,7 +117,7 @@ class TestHttpProxyPluginExamples(unittest.TestCase): headers={b'Content-Type': b'application/json'}, body=bytes_( json.dumps( - mock_rest_api.ProposedRestApiPlugin.REST_API_SPEC[path])) + ProposedRestApiPlugin.REST_API_SPEC[path])) )) @mock.patch('proxy.http.proxy.TcpServerConnection') @@ -140,7 +139,7 @@ class TestHttpProxyPluginExamples(unittest.TestCase): self.protocol_handler.run_once() upstream = urlparse.urlsplit( - redirect_to_custom_server.RedirectToCustomServerPlugin.UPSTREAM_SERVER) + RedirectToCustomServerPlugin.UPSTREAM_SERVER) mock_server_conn.assert_called_with('localhost', 8899) mock_server_conn.return_value.queue.assert_called_with( build_http_request( diff --git a/tests/http/utils.py b/tests/http/utils.py index ccd578af..3d0e3f95 100644 --- a/tests/http/utils.py +++ b/tests/http/utils.py @@ -1,26 +1,22 @@ from typing import Type from proxy.http.proxy import HttpProxyBasePlugin -from plugin_examples import modify_post_data -from plugin_examples import mock_rest_api -from plugin_examples import redirect_to_custom_server -from plugin_examples import filter_by_upstream -from plugin_examples import cache_responses -from plugin_examples import man_in_the_middle +from proxy.plugin import ModifyPostDataPlugin, ProposedRestApiPlugin, RedirectToCustomServerPlugin, \ + FilterByUpstreamHostPlugin, CacheResponsesPlugin, ManInTheMiddlePlugin def get_plugin_by_test_name(test_name: str) -> Type[HttpProxyBasePlugin]: - plugin: Type[HttpProxyBasePlugin] = modify_post_data.ModifyPostDataPlugin + plugin: Type[HttpProxyBasePlugin] = ModifyPostDataPlugin if test_name == 'test_modify_post_data_plugin': - plugin = modify_post_data.ModifyPostDataPlugin + plugin = ModifyPostDataPlugin elif test_name == 'test_proposed_rest_api_plugin': - plugin = mock_rest_api.ProposedRestApiPlugin + plugin = ProposedRestApiPlugin elif test_name == 'test_redirect_to_custom_server_plugin': - plugin = redirect_to_custom_server.RedirectToCustomServerPlugin + plugin = RedirectToCustomServerPlugin elif test_name == 'test_filter_by_upstream_host_plugin': - plugin = filter_by_upstream.FilterByUpstreamHostPlugin + plugin = FilterByUpstreamHostPlugin elif test_name == 'test_cache_responses_plugin': - plugin = cache_responses.CacheResponsesPlugin + plugin = CacheResponsesPlugin elif test_name == 'test_man_in_the_middle_plugin': - plugin = man_in_the_middle.ManInTheMiddlePlugin + plugin = ManInTheMiddlePlugin return plugin