Commit Graph

189 Commits

Author SHA1 Message Date
Abhinav Singh 0c4e1cbda9
Testing support improvements (#185)
* Introduce proxy.Proxy context manager.

This is similar to already existing context manager `start` but
`proxy.Proxy` is a class with __enter__ and __exit__ methods. This
allows usage of `proxy.Proxy` both as context manager and for manually
setup and teardown of `proxy.py` during test setUpClass and
teardownClass methods.

* Gracefully shutdown threadless processes

* Update tests and add a VCR method. See #184

* Refactor routes

* Add Proxy to __all__

* Move TestCase under proxy.testing and test_embed.py under tests.embed module to avoid conflict with http module due to a http directory under proxy folder

* Add a base cache plugin class which can be customized for custom cache behaviors

* See #184. Add VCRPlugin which can be enabled within tests using a context manager, e.g. with self.vcr(): ...

* Make cache plugin pluggable + make cache storage pluggable

* Make dashboard npm module agnostic of top level directory

* Symlink dashboard public folder

* Dump devtools within dashboard public folder

* Remove unused 3rd party js
2019-11-21 21:16:01 -08:00
pyup.io bot dace059617 Update pytest from 5.2.4 to 5.3.0 (#186) 2019-11-20 10:14:35 -08:00
pyup.io bot 5ead1ef101 Update twine from 2.0.0 to 3.0.0 (#183) 2019-11-18 22:01:49 -08:00
Abhinav Singh ad42e0d74d
Doc & Banner update to match GitHub (#182)
* Update doc and banner

* Update banner to match GitHub

* Update older banners too

* Add update_desc to .gitignore

* Update banner for dashboard to match github

* also update html, js, css
2019-11-18 20:45:51 -08:00
pyup.io bot 6aed912554 Update pytest from 5.2.3 to 5.2.4 (#180) 2019-11-15 23:50:42 -08:00
Abhinav Singh bb7006b67a
Move benchmark module within proxy (#181)
* Move benchmark within proxy module

* chmod 0644 for benchmark.py which was executable till now

* Turn utilities into its own section
2019-11-15 23:49:51 -08:00
Abhinav Singh 131e9366ac
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
2019-11-15 14:47:50 -08:00
Abhinav Singh 148c260472
Move dashboard backend within proxy module, now ships via same pip package (#177)
* Allow resources to load from http and ws when running w/o https

* Move dashboard backend (dashboard.py) within proxy module. Now shipped with pip install proxy.py

* Update ref to dashboard backend in github workflows

* Add git-pre-commit hook file.

Enable it by symlinking as .git/hooks/pre-commit

* Also enable static server for dashboard serving
2019-11-15 13:29:48 -08:00
Abhinav Singh 439d58fdc2
Devtools Protocol (#174)
* Refine docs

* Decouple relay from dashboard.

Will be re-used by devtools protocol plugin.

* Just have a single manager for all eventing

* Ofcourse managers cant be shared across processes

* Remove unused

* Add DevtoolsProtocolPlugin

* Emit REQUEST_COMPLETE core event

* Emit only if --enable-events used

* Add event emitter for response cycle

* Fill up core events to devtools protocol expectations

* Serve static content with Cache-Control header and gzip compression

* Add PWA manifest.json and icons from sample PWA apps (replace later)

* Catch any exception and be ssl agnostic

* Add CSP headers and avoid inline scripts

* Re-enable iframe and deobfuscation

* Embed plugins within <section/> block

* Make tab switching agnostic of block name

* Add support for browser history on tab change

* Default hash to #home

* Switch to tab if hash is already set

* Expand canvas to fill screen even without content

* Remove inline css for embedded devtools

* Make dashboard backend websocket API pluggable

* doc
2019-11-14 19:00:07 -08:00
Abhinav Singh c943dd7e27
Allow to pass flags as kwargs too in embed mode (#172)
* Dynamically load devtools instead of on page load

* Add support for passing flags as kwargs to main / start methods.

* Fix tests for refactored code

* Allow proxy.main, proxy.start, proxy.TestCase.

Also update README.md to reflect the same.

* Use Any for **opts

* Move main as __init__ to avoid name conflicts

* Fix tests

* Update setup.py entry_point

* Explicitly install requirements before setup.py

* Explicitly mention packages of interest

* ipv6 fails on ubuntu, use ipv4

* Make typing-extensions optional

* Instead of putting it all under __init__.py, move main.py to proxy.py

* Simply make setup.py module free

* autopep8
2019-11-13 16:38:59 -08:00
Abhinav Singh 1b0c2f8c5e Merge branch 'develop' of github.com:abhinavsingh/proxy.py into develop 2019-11-12 20:06:32 -08:00
Abhinav Singh 7561967be4
Load devtools within iframe (#171) 2019-11-12 20:04:46 -08:00
Abhinav Singh a46e73f51c Load devtools within iframe 2019-11-12 20:02:28 -08:00
Abhinav Singh 5cc9f2dde2
Dashboard Inspect traffic tab + devtools (#170)
* Explicitly link version changelog in TOC

* Separate out app header body builder

* Ensure unsubscribe when disabling inspection.  Fixes #164

* Avoid creation of new manager per dashboard instance.

* Add UI header for all plugins (tabs)

* Ensure app body for all plugin skeleton

* Move app-header and app-body within core for consistent dashboard look and feel

* Consistent UI header body for plugins

* autopep8

* make devtools

* convert to es6

* Add inspect_traffic plugin devtools app

* trigger re-build, github UI is stuck

* Dynamically load devtools within inspect traffic view

* Just copy devtools into public/dashboard folder

* Works but not how we wanted, devtools takes over entire body and doesnt contain itself within a div
2019-11-12 19:20:28 -08:00
Abhinav Singh e42cfefcf6
Consistent dashboard look and feel across plugins (#169)
* Explicitly link version changelog in TOC

* Separate out app header body builder

* Ensure unsubscribe when disabling inspection.  Fixes #164

* Avoid creation of new manager per dashboard instance.

* Add UI header for all plugins (tabs)

* Ensure app body for all plugin skeleton

* Move app-header and app-body within core for consistent dashboard look and feel

* Consistent UI header body for plugins

* autopep8
2019-11-12 15:29:37 -08:00
Abhinav Singh 3d65366c7b
Add proxy.main.TestCase for unit testing Python application with proxy.py (#167)
* Add demonstration of how to use proxy.py within Python application unittests

* mypy fixes

* test_with_proxy example

* Add docs for proxy.main.TestCase.

Also wait for proxy.py server to come up before running the tests.
2019-11-12 12:25:47 -08:00
Abhinav Singh 7ca7c2d8cc
Introduce sendMessage websocket api which allows for callbacks (#166)
* Introduce sendMessage websocket api which allows for callbacks, deprecate lastPingId in favor of callbacks

* Let InspectTrafficPlugin handle all pushed inspection events
2019-11-12 01:59:26 -08:00
Abhinav Singh d20cf1c764
Move traffic_control outside of core plugin, it maps to several plugin examples like redirectToUpstreamHost, filterByUpstreamHost plugins (#165) 2019-11-12 00:35:35 -08:00
Abhinav Singh ee7a69b1fc
Give structure to dashboard app (#163)
* Separate out files for different responsibilities.

1. Add src/plugins directory.  This directory holds one typescript file
   per plugin.  Each plugin is optionally can be displayed as a tab on
   the UI.
2. Move WebsocketApi to ws.ts.  This file contains all websocket APIs
   provided by dashboard.py backend.

* Make dashboard pluggable

* Move devtools under core too

* Register tabs dynamically

* Typescript fixes for abstract interfaces

* Initialize plugin app body skeleton

* Call activated / deactivated on tab change

* Move plugin name within plugin classes and initialize plugin within proxy dashboard constructor

* templatize api development plugin

* eslint fixes

* use globs

* Remove useless constructors
2019-11-12 00:02:15 -08:00
Abhinav Singh 0cc4e5e625
Add private / public key generation utils which comply with new requirements on Mac OS 10.15 (#160)
* Add utilities to generate private key and public keys with alternate cnames

* Add separate package proxy.py-plugins, fixes #156

* Generate certificates to comply with Mac requirements.

* Add utility for CSR generation and signing

* Fixes #161

* Add initial pki tests
2019-11-11 16:17:13 -08:00
Abhinav Singh 93d8a55c0e
Add non-blocking embedded mode feature (#159)
* Fixes #158

* mypy fixes

* Instructions for non-blocking embed mode

* Toggle running flag before shutdown
2019-11-07 20:53:08 -08:00
Abhinav Singh 183d03b866
Separate packages for Dashboard (#157)
* Refactor Makefile and add dashboard setup.py

* Package dashboard as proxy.py-dashboard pip package

* Give dashboard releases its own version

* Fix lib-package reference
2019-11-06 01:33:12 -08:00
Abhinav Singh 3aa1dc2824
Test refactor + Docker image CI (#154)
* Move tests into individual modules too

* Ensure one test class per file

* Fix docker image after refactoring

* Add github actions workflow for building docker image

* Fix image name

* Setup python required for extracting proxy version

* Version will also require deps
2019-10-29 20:41:39 -07:00
pyup.io bot 75a818d397 Update setuptools from 41.5.1 to 41.6.0 (#153) 2019-10-29 18:43:24 -07:00
Abhinav Singh 0e2194d683
Update README.md (#152)
* Update flags

* Update debugging instructions and run instructions for develops

* Update references to plugins directory

* For readability add sections for run from command line using pip

* Move internal doc under developer section

* Add option to pass fully-qualified plugin path
2019-10-28 16:14:34 -07:00
Abhinav Singh 1ce16b95de
Update mypy==0.740 (#151) 2019-10-28 15:29:33 -07:00
Abhinav Singh e14548252c
Proxy.py Dashboard (#141)
* Remove redundant variables

* Initialize frontend dashboard app (written in typescript)

* Add a WebsocketFrame.text method to quickly build a text frame raw packet, also close connection for static file serving, atleast Google Chrome seems to hang up instead of closing the connection

* Add read_and_build_static_file_response method for reusability in plugins

* teardown websocket connection when opcode CONNECTION_CLOSE is received

* First draft of proxy.py dashboard

* Remove uglify, obfuscator is superb enough

* Correct generic V

* First draft of dashboard

* ProtocolConfig is now Flags

* First big refactor toward no-single-file-module

* Working tests

* Update dashboard for refactored imports

* Remove proxy.py as now we can just call python -m proxy -h

* Fix setup.py for refactored code

* Banner update

* Lint check

* Fix dashboard static serving and no UNDER_TEST constant necessary

* Add support for plugin imports when specified in path/to/module.MyPlugin

* Update README with instructions to run proxy.py after refactor

* Move dashboard under /dashboard path

* Rename to devtools.ts

* remove unused

* Update github workflow for new directory structure

* Update test command too

* Fix coverage generation

* *.py is an invalid syntax on windows

* No * on windows

* Enable execution via github zip downloads

* Github Zip downloads cannot be executed as Github puts project under a folder named after Github project, this breaks python interpreter expectation of finding a __main__.py in the root directory

* Forget zip runs for now

* Initialize ProxyDashboard on page load rather than within typescript i.e. on script load

* Enforce eslint with standard style

* Add .editorconfig to make editor compatible with various style requirements (Makefile, Typescript, Python)

* Remove extra empty line

* Add ability to pass headers with HttpRequestRejected exception, also remove proxy agent header for HttpRequestRejected

* Add ability to pass headers with HttpRequestRejected exception, also remove proxy agent header for HttpRequestRejected

* Fix tests

* Move common code under common sub-module

* Move flags under common module

* Move acceptor under core

* Move connection under core submodule

* Move chunk_parser under http

* Move http_parser as http/parser

* Move http_methods as http/methods

* Move http_proxy as http/proxy

* Move web_server as http/server

* Move status_codes as http/codes

* move websocket as http/websocket

* Move exception under http/exception, also move http/proxy exceptions under http/exceptions

* move protocol_handler as http/handler

* move devtools as http/devtools

* Move version under common/version

* Lifecycle if now core Event

* autopep8

* Add core event queue

* Register / unregister handler

* Enable inspection support for frontend dashboard

* Dont give an illusion of exception for HttpProtocolExceptions

* Update readme for refactored codebase

* DictQueueType everywhere

* Move all websocket API related code under WebsocketApi class

* Inspection enabled on tab switch.

1. Additionally now acceptors are assigned an int id.
2. Fix tests to match change in constructor.

* Corresponding ends of the work queues can be closed immediately.

Since work queues between AcceptorPool and Acceptor process is used only
once, close corresponding ends asap instead of at shutdown.

* No need of a manager for shared multiprocess Lock.

This unnecessarily creates additional manager process.

* Move threadless into its own module

* Merge acceptor and acceptor_pool tests

* Defer os.close

* Change content display with tab clicks.

Also ensure relay manager shutdown.

* Remove --cov flags

* Use right type for SyncManager

* Ensure coverage again

* Print help to discover flags, --cov certainly not available on Travis for some reason

* Add pytest-cov to requirements-testing

* Re-add windows on .travis also add changelog to readme

* Use 3.7 and no pip upgrade since it fails on travis windows

* Attempt to fix pip install on windows

* Disable windows on travis, it fails and uses 3.8.  Try reporting coverage from github actions

* Move away from coveralls, use codecov

* Codecov app installation either didnt work or token still needs to be passed

* Remove travis CI

* Use https://github.com/codecov/codecov-action for coverage uploads

* Remove run codecov

* Ha, codecov action only works on linux, what a mess

* Add cookie.js though unable to use it with es5/es6 modules yet

* Enable testing for python 3.8 also Build dashboard during testing

* No python 3.8 on github actions yet

* Autopep8

* Add separate workflows for library (python) and dashboard (node) app

* Type jobs not job

* Add checkout

* Fix parsing node version

* Fix dashboard build on windows

* Show codecov instead of coveralls
2019-10-28 14:57:33 -07:00
pyup.io bot 3b2b2e5dd5 Update py-spy from 0.2.2 to 0.3.0 (#144) 2019-10-28 14:43:46 -07:00
pyup.io bot 521a49ffd1 Update setuptools from 41.5.0 to 41.5.1 (#149) 2019-10-28 13:28:46 -07:00
pyup.io bot e7e9e14e75 Update flake8 from 3.7.8 to 3.7.9 (#148) 2019-10-28 13:12:45 -07:00
pyup.io bot 52275f0588 Update typing-extensions from 3.7.4 to 3.7.4.1 (#147) 2019-10-28 12:30:53 -07:00
pyup.io bot 5db42b349e Update setuptools from 41.4.0 to 41.5.0 (#145) 2019-10-27 19:26:20 -07:00
pyup.io bot 57315289ae Update pytest from 5.2.1 to 5.2.2 (#142) 2019-10-26 20:38:22 -07:00
Abhinav Singh ca1d1e7139
os.close only for threadless (#138)
* os.close only for Threadless to avoid fd leaks

* Remove os.close mock which is only called for threadless
2019-10-16 13:09:38 -07:00
Abhinav Singh c77f8b5789
Add pipeline response parsing tests (#137)
* Add pipeline response parsing tests

* build_http_response now only adds content-length if transfer-encoding is
not provided.

Also return pending raw chunks from ChunkParser so that we can parse
pipelined chunk responses.
2019-10-16 03:22:08 -07:00
Abhinav Singh 69445a8921
Remove pip upgrade for windows which seems to be failing on travis (#136)
* Remove pip upgrade for windows which seems to be failing on travis

* Remove windows testing on Travis, pip install is failing
2019-10-16 01:13:27 -07:00
Abhinav Singh a1bb659488
Threadless execution using coroutines (#134)
* Workers need not register/unregister sock for every loop

* No need of explicit socket.settimeout(0) which is same as socket.setblocking(False)

* Remove settimeout assertion

* Only store sender side of Pipe().  Also ensure both end of the Pipe() are closed on shutdown

* Make now global. Also we seem to be using datetime.utcnow and time.time for similar purposes

* Use time.time throughout.  Remove incomplete test_cache_responses_plugin to avoid resource leak in tests

* Remove unused

* Wrap selector register/unregister within a context manager

* Refactor in preparation of threadless request handling

* MyPy generator fix

* Add --threadless flag

* Internally call them acceptors

* Internally use acceptors

* Add Threadless class.

Also no need to pass family over pipe to acceptors.

* Make threadless work for a single client :)

* Threadless is soon be our default

* Close client queue

* Use context manager for register/unregister

* Fix Acceptor tests broken after refactoring

* Use asyncio tasks to invoke ProtocolHandle.handle_events

This gives all client threads a chance to respond without
waiting for other handlers to return.

* Explicitly initialize event loop per Threadless process

* Mypy fixes

* Add ThreadlessWork abstract class implemented by ProtocolHandler

* Add benchmark.py

Avoid TIME_WAIT by properly shutting down the connection.

* Add benchmark.py as part of testing workflow

* When e2e encryption is enabled, unwrap socket before shutdown to ensure CLOSED state

* MyPy fixes, Union should have worked, but likely unwrap is not part of socket.socket hence

* Unwrap if wrapped before shutdown

* Unwrap if wrapped before shutdown

* socket.SHUT_RDWR will cause leaks

* MyPy

* Add instructions for monitor.sh

* Avoid recursive exception in new_socket_connection and only invoke plugins/shutdown if server connection was initialized

* Add Fast & Scalable section

* Update internal classes section

* Dont print out local dir path in help text :)

* Refactor

* Fix a bug where response parser for HTTP only requests was reused for pipelined requests resulting in a hang

* Add chrome_with_proxy.sh helper script

* Handle OSError during client.flush which can happen due to invalid protocol type for socket error

* Remove redundant e

* Add classmethods to quickly construct a parser object

* Don't raise from TcpConnection abstract class.

This allows both client/socket side of communication to handle
exceptions as necessary. We might refactor this again later to remove
redundant code :)

* Disable response parsing when TLS interception is enabled. See issue #127

* remove unused imports

* Within webserver parse pipelined requests only if we have a route

* Add ShortLinkPlugin plugin

* Add more shortlinks

* Add ShortLinkPlugin to README.md

* Add path forwarding too instead of leaving as excercise ;)

* Add shortlink to TOC

* Ensure no socket leaks

* Ensure no leaks

* Naming

* Default number of clients 1

* Avoid shortlinking localhost

* Stress more
2019-10-15 23:56:39 -07:00
Abhinav Singh 9d46cba1e8
Test plugin examples (#130)
* Add tests for plugin_examples.* to ensure we never break functionality

* Add tests for plugin_examples.*

* Test man in the middle

* Lint fixes

* Checkin

* Add tests for plugin examples with TLS encryption enabled
2019-10-13 03:03:05 -07:00
Abhinav Singh dc560be6ea
Add --timeout flag with default value of 10 second. (#129)
* Add --timeout flag with default value of 5.  This value was previously hardcoded to 30

* --timeout=10 by default

* Dispatch 408 timeout when connection is dropped due to inactivity

* Add httpStatusCodes named tuple

* Update plugin client connection reference after TLS connection upgrade
2019-10-12 21:02:17 -07:00
Abhinav Singh 6455a34973
Invoke proxy plugin handle_request for each request in HTTP/1.1 pipeline or when TLS interception is enabled (#128)
* Add tests for is_http_1_1_keep_alive

* Add ModifyPostDataPlugin in README

* Fixes #126

* Refactor HttpProxyBasePlugin API

* before_upstream_connection too can drop request by returning None

* Remove HTTP Server startup during tests, no longer used

* Removed unused imports

* Simplify load_plugins
2019-10-12 17:43:19 -07:00
Abhinav Singh 2840afc0bf Ensure teardown is always accompanied with Connection: close header
Fix tests
2019-10-11 11:06:35 -07:00
Abhinav Singh 3b5e2ccf9c Reduce docker image size 2019-10-11 11:03:51 -07:00
Abhinav Singh bb7f5a61dc
Invoke HttpWebServerBasePlugin.handle_request for each request in HTTP/1.1 pipeline (#125)
* Add tests to verify certificate generation

* Separate out tests for ProtocolHandler and WebServerPlugin

* Keep-alive connections for web server.

TODO: Only keep-alivei if HTTP/1.1

* Add request.path to avoid build_url repeatedly whose name is also slightly misleading

* Fix example usage of request.path

* Pipeline only for HTTP/1.1

* Lint fix

* Teardown HTTP/1.1 keep-alive request when Connection: close header is sent

* Add instructions on how to build docker image locally

* Move access_log to separate function for pretty logging
2019-10-10 22:15:07 -07:00
Abhinav Singh a19da5dcb9
Update issue templates (#123) 2019-10-10 16:18:12 -07:00
Abhinav Singh 5f91b179a3 Always update latest tag for docker releases 2019-10-10 15:45:57 -07:00
Abhinav Singh 27e4152cd2
Merge pull request #122 from abhinavsingh/develop
v1.1.1 Release
2019-10-10 15:43:55 -07:00
Abhinav Singh 3b9587b6f1
Ensure explicit flush before upgrade while TLS intercepting (#121)
* Ensure explicit flush before upgrade + nonblocking server sock.

* tls interception tests

* prepare for v1.1.1

* Add requirements.txt for typing extensions

* Add setup.py under lint workflow
2019-10-10 15:15:27 -07:00
Abhinav Singh d2a9cdd277
Merge pull request #119 from abhinavsingh/master
Sync master and develop
2019-10-10 00:33:47 -07:00
Abhinav Singh 22666098ab
Merge pull request #118 from abhinavsingh/develop
v1.1.0 Release
2019-10-10 00:32:38 -07:00
Abhinav Singh 7a6247ea18 v1.1.0 release
Add pip install typing-extensions==3.7.4 for docker image
2019-10-10 00:29:41 -07:00