proxy.py/proxy/plugin/reverse_proxy.py

73 lines
2.2 KiB
Python

# -*- coding: utf-8 -*-
"""
proxy.py
~~~~~~~~
⚡⚡⚡ Fast, Lightweight, Pluggable, TLS interception capable proxy server focused on
Network monitoring, controls & Application development, testing, debugging.
:copyright: (c) 2013-present by Abhinav Singh and contributors.
:license: BSD, see LICENSE for more details.
"""
import random
from typing import List, Tuple
from urllib import parse as urlparse
from ..common.constants import DEFAULT_BUFFER_SIZE, DEFAULT_HTTP_PORT
from ..common.utils import socket_connection, text_
from ..http.parser import HttpParser
from ..http.websocket import WebsocketFrame
from ..http.server import HttpWebServerBasePlugin, httpProtocolTypes
class ReverseProxyPlugin(HttpWebServerBasePlugin):
"""Extend in-built Web Server to add Reverse Proxy capabilities.
This example plugin is equivalent to following Nginx configuration:
location /get {
proxy_pass http://httpbin.org/get
}
Example:
$ curl http://localhost:9000/get
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "localhost",
"User-Agent": "curl/7.64.1"
},
"origin": "1.2.3.4, 5.6.7.8",
"url": "https://localhost/get"
}
"""
REVERSE_PROXY_LOCATION: str = r'/get$'
REVERSE_PROXY_PASS = [
b'http://httpbin.org/get'
]
def routes(self) -> List[Tuple[int, str]]:
return [
(httpProtocolTypes.HTTP, ReverseProxyPlugin.REVERSE_PROXY_LOCATION),
(httpProtocolTypes.HTTPS, ReverseProxyPlugin.REVERSE_PROXY_LOCATION)
]
def handle_request(self, request: HttpParser) -> None:
upstream = random.choice(ReverseProxyPlugin.REVERSE_PROXY_PASS)
url = urlparse.urlsplit(upstream)
assert url.hostname
with socket_connection((text_(url.hostname), url.port if url.port else DEFAULT_HTTP_PORT)) as conn:
conn.send(request.build())
self.client.queue(memoryview(conn.recv(DEFAULT_BUFFER_SIZE)))
def on_websocket_open(self) -> None:
pass
def on_websocket_message(self, frame: WebsocketFrame) -> None:
pass
def on_websocket_close(self) -> None:
pass