{ "info": { "author": "izrik", "author_email": "izrik@izrik.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Topic :: Internet :: WWW/HTTP", "Topic :: Software Development :: Testing" ], "description": "=======\r\nDeproxy\r\n=======\r\n\r\nDeproxy is a tool for performing functional/regression testing of proxies, and other HTTP intermediaries. It is written in python, and the plan is to incorporate it into unittest-style test scripts for functional tests.\r\n\r\nTesting normal client/server interaction is relatively straight-forward: Use a specialized test client to send requests to the server, and compare the response that the server returns to what it ought to return.::\r\n\r\n ________ ________\r\n | Test | ---> req ---> | |\r\n | Client | | Server |\r\n |________| <--- resp <--- |________|\r\n\r\n\r\nProxies sit in-between an HTTP client (e.g. novaclient) and an HTTP server (e.g. the Nova API nodes). This makes testing a little more difficult.::\r\n\r\n ________ ________ ________\r\n | | ---> req ---> | | ---> req2 ---> | |\r\n | Client | | Proxy | | Server |\r\n |________| <--- resp2 <-- |________| <--- resp <--- |________|\r\n\r\nA proxy can modify either the incoming request to the server, or the outgoing response to the client, or both. In addition, it may handle the request itself (e.g. a cache or authenicator), and prevent it from reaching the server in the first place.\r\nThe functionality and positioning of the proxy provide more of a challenge to functionality testing. \r\nThe traditional model is not enough. \r\nBecause the test client only sees one side of the transaction, it can't make definitive determinations about the server's side of it. ::\r\n\r\n ________ ________ ________\r\n | Test | ---> req ---> | | ---> ???? ---> | |\r\n | Client | | Proxy | | Server |\r\n |________| <--- resp2 <-- |________| <--- ???? <--- |________|\r\n\r\nIf we don't have a copy of the request that the server received, then we can't compare it to the request sent, which means we don't know for sure that the proxy is modifiying it correctly. \r\nLikewise, if we don't have a copy of the response that the server originally sent, we can't make conclusively prove that the proxy is modifying responses correctly.\r\n[Some specific cases don't have this problem, such as whether the proxy overwrites the \"Server\" header on a response; that can be confirmed because a response will only ever have one \"Server\" header, and that can easily be checked by the test client.]\r\nBut in the general case, we can't say for sure about other functional requirements.\r\nAdditionally, if the proxy is required to prevent a request from even reaching the server (as in the case of invalid authentication credentials in the request) the test client cannot determine whether any such request was in fact forwarded, because all it sees is the error response from the proxy.\r\nFor that, we'd need to be able see both sides of the exchange, and record all requests that made it to the server.\r\nThat is what Deproxy does.::\r\n\r\n ________ ________ ________\r\n | | ---> req ---> | | ---> req2 ---> | |\r\n | (C) | | Proxy | | (S) |\r\n | | <--- resp2 <-- |________| <--- resp <--- | |\r\n | | | |\r\n | |_______________________________________________| |\r\n | |\r\n | Deproxy |\r\n |_________________________________________________________________|\r\n\r\nDeproxy acts as both the client and the server, and the proxy it is testing will forward requests from one side to the other.\r\nAny requests received by the server side are matched up with the requests that started them.\r\nA call to the Deproxy object's make_request method will return the request that the client side sent, the request that the server side received, the response that the server side sent, and the response that the client side received. In this way, we can conclusively prove whether or not the proxy modified requests and responses correctly. We can even conclusively show when no request makes it to the server in the first place, because the received_request and sent_response fields will be null.\r\n\r\nBut this is just scratching the surface. The Deproxy module contains additional tools and utilities for custom server responses, mocking, testing multiple endpoints, and more.\r\n\r\n\r\n\r\n.. :changelog:\r\n\r\nHistory\r\n-------\r\n\r\n0.11 (in progress)\r\n++++++++++++++++\r\n\r\n0.10 (2015-05-26)\r\n++++++++++++++++\r\n\r\n- Preliminary HTTPS support.\r\n\r\n0.9 (2015-05-19)\r\n++++++++++++++++\r\n\r\n- Read message bodies encoded with the \"chunked\" transfer-encoding.\r\n\r\n0.8 (2013-06-05)\r\n++++++++++++++++\r\n\r\n- Rough preliminary support for using ssl for requests.\r\n- Add \"Content-Length: 0\" header if no body is present on the request.\r\n\r\n0.7 (2013-05-31)\r\n++++++++++++++++\r\n\r\n- Changed the signature of ``add_endpoint`` so that the user can just pass a\r\n port, instead of an ugly ``('localhost', port)`` tuple, when creating an\r\n endpoint.\r\n- Added the ability for the user to specify a default handler for a Deproxy via\r\n the ``default_handler`` parameter to ``__init__``.\r\n- Added the ability for the user to specify a default handler for a specific\r\n endpoint via the ``default_handler`` parameter to ``add_endpoint``.\r\n- Added the ability for the user to specify separate handlers for each endpoint\r\n via the ``handlers`` parameter to ``make_request``.\r\n- Renamed the ``make_request`` method's ``handler_function`` parameter to\r\n ``default_handler``.\r\n- Renamed the ``MessageChain`` class's ``handler`` to ``default_handler``, to\r\n avoid confusion with the new ``handlers`` attribute.\r\n- Renamed the built-in ``default_handler`` function to ``simple_handler`` to\r\n avoid confusion.\r\n- Renamed the ``delay`` function's ``handler_function`` parameter to\r\n ``next_handler`` and made it optional, defaulting to ``simple_handler``.\r\n- Stringified parameters to ``Request`` and ``Response``. They are always\r\n converted to strings now. Also made some of them optional.\r\n- Fixes to ``route``. It's still not 100%, though.\r\n\r\nThere are several breaking changes to method signatures. Upgrading existing\r\ntests to use v0.7 will be tedious, but not difficult.\r\n\r\n0.6 (2013-05-30)\r\n++++++++++++++++\r\n\r\n- Added a class, ``HeaderCollection``, to hold request and response headers\r\n instead of using a ``dict``. The new class is a hybrid of a dictionary and a\r\n list of tuples. It supports case-insensitive lookup and storing multiple\r\n values for headers with the same name.\r\n- Updated reading of simple message bodies. It doesn't yet support chunked\r\n transfers or encodings, but it's far more useful.\r\n- Re-organized the codebase from a multi-file package into a single module.\r\n\r\n0.5 (2013-05-16)\r\n++++++++++++++++\r\n\r\n- Fixed the logic when adding default headers so that they are recorded in the\r\n handlings as well.\r\n\r\n0.4 (2013-05-16)\r\n++++++++++++++++\r\n\r\n- Added option to ``make_request`` to not add default request headers\r\n- Added option to handler functions to not add default response headers", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/izrik/pydeproxy", "keywords": "http proxy testing", "license": "Copyright (c) 2012-2014 Richard Sartor\r\n\r\n Permission is hereby granted, free of charge, to any person obtaining a\r\n copy of this software and associated documentation files (the \"Software\"),\r\n to deal in the Software without restriction, including without limitation\r\n the rights to use, copy, modify, merge, publish, distribute, sublicense,\r\n and/or sell copies of the Software, and to permit persons to whom the\r\n Software is furnished to do so, subject to the following conditions:\r\n\r\n The above copyright notice and this permission notice shall be included in\r\n all copies or substantial portions of the Software.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r\n FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\n DEALINGS IN THE SOFTWARE.\r\n\r\n[ http://opensource.org/licenses/MIT ]", "maintainer": "", "maintainer_email": "", "name": "deproxy", "package_url": "https://pypi.org/project/deproxy/", "platform": "", "project_url": "https://pypi.org/project/deproxy/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/izrik/pydeproxy" }, "release_url": "https://pypi.org/project/deproxy/0.10/", "requires_dist": null, "requires_python": null, "summary": "Python library for testing HTTP proxies.", "version": "0.10" }, "last_serial": 2101851, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "76c6f7ab35544e6469b94a828e02c91d", "sha256": "4a67504ddf9e972230d25e76aaa89e4176f7df4641fc07f3f7a56d878f35d596" }, "downloads": -1, "filename": "deproxy-0.1.tar.gz", "has_sig": false, "md5_digest": "76c6f7ab35544e6469b94a828e02c91d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10351, "upload_time": "2013-03-04T23:10:02", "url": "https://files.pythonhosted.org/packages/4c/2d/5354588cf7918713386fcc390fd1da0c2cfddbdb7ff24216e527d08c7b6b/deproxy-0.1.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "a4c8b2f31d1cdbeef378d80b4a9ff6c7", "sha256": "2e20f9c58067900f8c5c24a5739c6b69df417370ec77841fe8977dc66b6aee08" }, "downloads": -1, "filename": "deproxy-0.1.1.tar.gz", "has_sig": false, "md5_digest": "a4c8b2f31d1cdbeef378d80b4a9ff6c7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10413, "upload_time": "2013-04-02T18:38:28", "url": "https://files.pythonhosted.org/packages/7c/6d/3e7189a5dc1934a03daaf424bad914a54acd49639e7e014cf677ebb55419/deproxy-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "c013435b93fb145152011fcd8a930eec", "sha256": "6a36b3d271a16a73c5f791ca63791e6d93f8c8e54a106bc1506b7b19d0f24b17" }, "downloads": -1, "filename": "deproxy-0.1.2.tar.gz", "has_sig": false, "md5_digest": "c013435b93fb145152011fcd8a930eec", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10488, "upload_time": "2013-04-02T20:53:02", "url": "https://files.pythonhosted.org/packages/0c/0a/1e2f5925891b4d02964dc7958ed00be8093e9a0450915606031860518769/deproxy-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "a89d6cebcf2ed5efdece42a147350333", "sha256": "c8533e6d29e49470aa303ff7fa57e1554fd135827cc035de1911fc59177b4fa5" }, "downloads": -1, "filename": "deproxy-0.1.3.tar.gz", "has_sig": false, "md5_digest": "a89d6cebcf2ed5efdece42a147350333", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10495, "upload_time": "2013-04-02T21:04:38", "url": "https://files.pythonhosted.org/packages/c0/9d/406fa95b944ef5ea6f026f189e2bc178fdc3fb71303beefecafde6023667/deproxy-0.1.3.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "ff077d07e90c1a204585ebc041afe53b", "sha256": "f07135e67bcfc741c2b702b27ae67b0f08e649b30715192302ff6575ee11f38c" }, "downloads": -1, "filename": "deproxy-0.1.4.tar.gz", "has_sig": false, "md5_digest": "ff077d07e90c1a204585ebc041afe53b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10754, "upload_time": "2013-04-02T21:59:17", "url": "https://files.pythonhosted.org/packages/5a/3f/67aa5e1536799983505a1f9e85e8e98cd46817edb10397a69a11a185ae10/deproxy-0.1.4.tar.gz" } ], "0.1.5": [ { "comment_text": "", "digests": { "md5": "5af7d0aa3255ae098a2d0d29cde8f654", "sha256": "ff9489b4f84244ed790feba91b142180c615cfd751a632a2fcc6a47ad4f06f0a" }, "downloads": -1, "filename": "deproxy-0.1.5.tar.gz", "has_sig": false, "md5_digest": "5af7d0aa3255ae098a2d0d29cde8f654", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11136, "upload_time": "2013-04-03T20:54:45", "url": "https://files.pythonhosted.org/packages/f8/a5/c966d6b82ab12544fa3c17524326862b89d333a6e1c5af67c6d0beba752f/deproxy-0.1.5.tar.gz" } ], "0.10": [ { "comment_text": "", "digests": { "md5": "1c86861d5adf080043cb1e6d852d86b7", "sha256": "1f9285a8bf59a10783df8e92859110cb877a3435907977517524ca8ab63a15b0" }, "downloads": -1, "filename": "deproxy-0.10.tar.gz", "has_sig": false, "md5_digest": "1c86861d5adf080043cb1e6d852d86b7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18385, "upload_time": "2015-05-26T20:34:58", "url": "https://files.pythonhosted.org/packages/cf/45/efa548dbd8e4990ef4c1c6868d18c770422623748df55cd2f99644b49884/deproxy-0.10.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "b78d0fc3be27aedd55736888cf813d85", "sha256": "73d21a4097382e7086147126a28542f8a5d5e331641c47b180405410a5847517" }, "downloads": -1, "filename": "deproxy-0.2.tar.gz", "has_sig": false, "md5_digest": "b78d0fc3be27aedd55736888cf813d85", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10882, "upload_time": "2013-04-15T20:33:05", "url": "https://files.pythonhosted.org/packages/ac/ad/1fa4c60fbfc8263c424aaa194d74384b95efe2316532969281133345359e/deproxy-0.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "863975707d40f2a7c7e5bbf292c3b578", "sha256": "dc101997724bf9343146a2bf9943e3e571f9df36ef781c3a3a752dcc1a4f4b5f" }, "downloads": -1, "filename": "deproxy-0.3.tar.gz", "has_sig": false, "md5_digest": "863975707d40f2a7c7e5bbf292c3b578", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13176, "upload_time": "2013-04-17T17:33:24", "url": "https://files.pythonhosted.org/packages/cc/e1/3dcf62631d6a0504e32bb61711619357f5fc2dd0ae3d2e66f0c949fcf5d7/deproxy-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "116d82bc030bffaa6ce202efb304e5ae", "sha256": "4e1b87a2acd000c13f7f674606c63c13c22f0111fa5504edc6605dc91fcd1887" }, "downloads": -1, "filename": "deproxy-0.4.tar.gz", "has_sig": false, "md5_digest": "116d82bc030bffaa6ce202efb304e5ae", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13748, "upload_time": "2013-05-16T19:40:51", "url": "https://files.pythonhosted.org/packages/5e/6f/9bff4c1e185213efa0eeb4f7465003e2f45e75fae39075811de7c5a6d3aa/deproxy-0.4.tar.gz" } ], "0.5": [ { "comment_text": "", "digests": { "md5": "79ff355ef091c7d6522036073dc5db9a", "sha256": "a6bc6a7a2ecfafa6b484ccddbe91a012b0f5bda52a22a7ee5beb174e23570684" }, "downloads": -1, "filename": "deproxy-0.5.tar.gz", "has_sig": false, "md5_digest": "79ff355ef091c7d6522036073dc5db9a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13830, "upload_time": "2013-05-16T21:49:45", "url": "https://files.pythonhosted.org/packages/23/f2/7caf4c97cd4ddd3bafbc943bdf2b5b17ea3b496d2913b817fde1c14c5a09/deproxy-0.5.tar.gz" } ], "0.6": [ { "comment_text": "", "digests": { "md5": "c950f8be67d2de3301437833347bc2a6", "sha256": "6eb932620ff1d9d33b8f1e2af22cd7c7491b65bcc9d282372423097d26a5383e" }, "downloads": -1, "filename": "deproxy-0.6.tar.gz", "has_sig": false, "md5_digest": "c950f8be67d2de3301437833347bc2a6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14738, "upload_time": "2013-05-30T20:43:38", "url": "https://files.pythonhosted.org/packages/68/aa/167414589603f3a78f5cdd37dae3d16a355c8befc4f7994b70c9865cbfd4/deproxy-0.6.tar.gz" } ], "0.7": [ { "comment_text": "", "digests": { "md5": "6ac788034de824de7a0146e10499b4c2", "sha256": "8e202ad78871e2c0472df64cf54a87a61f20e2c778717c7e1beb9b332dd29630" }, "downloads": -1, "filename": "deproxy-0.7.tar.gz", "has_sig": false, "md5_digest": "6ac788034de824de7a0146e10499b4c2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17200, "upload_time": "2013-05-31T21:03:10", "url": "https://files.pythonhosted.org/packages/55/12/409ffd58d2c6b2e79b59424c5530c1715807a22d003aa40e266c84ff0f0f/deproxy-0.7.tar.gz" } ], "0.8": [ { "comment_text": "", "digests": { "md5": "58e688532ccaa34de739295cf3fd1c3f", "sha256": "920f04a008a0db14c8c22949847c64547070d1021f7cc95d589f814fb97a8b63" }, "downloads": -1, "filename": "deproxy-0.8.tar.gz", "has_sig": false, "md5_digest": "58e688532ccaa34de739295cf3fd1c3f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17844, "upload_time": "2013-06-05T16:46:07", "url": "https://files.pythonhosted.org/packages/16/56/8578a562ab887aeb6c78f8bb1a5d0cfdefdbc182c69c2a6411bf2d9348b9/deproxy-0.8.tar.gz" } ], "0.9": [ { "comment_text": "", "digests": { "md5": "a93b57b2430887dc5866fadcdaa0a0c9", "sha256": "95b25682810c08569d17a471f5da7543b741fd08d2f9e305c82d3ac90d556478" }, "downloads": -1, "filename": "deproxy-0.9.tar.gz", "has_sig": false, "md5_digest": "a93b57b2430887dc5866fadcdaa0a0c9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18165, "upload_time": "2015-05-19T12:46:37", "url": "https://files.pythonhosted.org/packages/3b/69/e3234e1bbf514ad90d0cbc8361293777c94ffd04d672a68aa85baf4ed5f6/deproxy-0.9.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "1c86861d5adf080043cb1e6d852d86b7", "sha256": "1f9285a8bf59a10783df8e92859110cb877a3435907977517524ca8ab63a15b0" }, "downloads": -1, "filename": "deproxy-0.10.tar.gz", "has_sig": false, "md5_digest": "1c86861d5adf080043cb1e6d852d86b7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18385, "upload_time": "2015-05-26T20:34:58", "url": "https://files.pythonhosted.org/packages/cf/45/efa548dbd8e4990ef4c1c6868d18c770422623748df55cd2f99644b49884/deproxy-0.10.tar.gz" } ] }