DEV Community

drake
drake

Posted on

用python实现http路由转发

当本地存在8081端口的情况下,8080端口接收请求转发到8081端口


import http.server
import socketserver
import socket
import requests
# from urllib.parse import urlparse


# 检查端口是否被占用
def is_port_in_use(port):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        try:
            s.bind(("localhost", port))
            return False
        except OSError:
            return True


# 自定义请求处理器
class ProxyHandler(http.server.SimpleHTTPRequestHandler):
    def forward_request(self, method):
        # 构造目标 URL,将请求转发到 8081 端口
        target_url = f"http://localhost:8081{self.path}"

        # 获取请求头
        headers = {key: value for key, value in self.headers.items()}

        # 处理请求体(如果有)
        content_length = int(self.headers.get('Content-Length', 0))
        body = self.rfile.read(content_length) if content_length > 0 else None

        try:
            # 根据请求方法转发请求
            if method == "GET":
                response = requests.get(target_url, headers=headers, timeout=5)
            elif method == "POST":
                response = requests.post(target_url, headers=headers, data=body, timeout=5)
            else:
                self.send_error(405, "Method Not Allowed")
                return

            # 发送响应状态码
            self.send_response(response.status_code)
            # 发送响应头
            for key, value in response.headers.items():
                self.send_header(key, value)
            self.end_headers()
            # 发送响应内容
            self.wfile.write(response.content)

        except requests.RequestException as e:
            self.send_error(502, f"Bad Gateway: {str(e)}")

    def do_GET(self):
        if is_port_in_use(8081):
            self.forward_request("GET")
        else:
            self.send_response(200)
            self.send_header("Content-type", "text/plain")
            self.end_headers()
            self.wfile.write(b"Port 8081 is not available, handling request at 8080")

    def do_POST(self):
        if is_port_in_use(8081):
            self.forward_request("POST")
        else:
            self.send_response(200)
            self.send_header("Content-type", "text/plain")
            self.end_headers()
            self.wfile.write(b"Port 8081 is not available, handling request at 8080")



def live_listen():
    # 设置服务器
    PORT = 8080
    Handler = ProxyHandler

    # 使用 ThreadingTCPServer 支持并发请求
    with socketserver.ThreadingTCPServer(("", PORT), Handler) as httpd:
        print(f"Serving on port {PORT}")
        try:
            httpd.serve_forever()
        except KeyboardInterrupt:
            print("\nServer stopped")
            httpd.server_close()
Enter fullscreen mode Exit fullscreen mode

Heroku

Built for developers, by developers.

Whether you're building a simple prototype or a business-critical product, Heroku's fully-managed platform gives you the simplest path to delivering apps quickly — using the tools and languages you already love!

Learn More

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

DEV is better (more customized, reading settings like dark mode etc) when you're signed in!

Okay