Python Socket编程:如何返回403错误拦截含/../的URL
解决Python Socket中返回403 Forbidden无响应的问题
你遇到的问题核心是发送的HTTP响应不完整,导致curl无法正确解析服务器返回的内容,要么一直等待无结果,要么因连接异常触发52错误。咱们来一步步修复这个问题:
问题根源
你只发送了HTTP/1.0 403 Forbidden\r\n这一行状态行,但HTTP协议要求响应必须遵循状态行 + 响应头部 + 空行的结构(哪怕没有响应体,空行也不能省略)。缺少必要的头部和结束标记时,客户端会认为响应未完成,要么持续等待,要么在连接关闭时判定为异常。
修复后的代码
while True: print('Ready to serve....') connectionSocket, addr = serverSocket.accept() try: message = connectionSocket.recv(1024).decode() # 先处理客户端提前断开的情况 if not message: connectionSocket.close() continue filename = message.split()[1] if "/../" in filename: # 构造完整的403响应 full_response = ( 'HTTP/1.0 403 Forbidden\r\n' 'Content-Type: text/plain\r\n' 'Content-Length: 15\r\n' '\r\n' 'Forbidden Access' ) # 用sendall确保所有数据发送完成 connectionSocket.sendall(full_response.encode()) connectionSocket.close() continue # 这里放置正常处理合法请求的代码... except IndexError: # 处理非标准GET请求的情况 bad_request = 'HTTP/1.0 400 Bad Request\r\n\r\nInvalid Request' connectionSocket.sendall(bad_request.encode()) connectionSocket.close() except Exception as e: print(f"Unexpected error: {e}") connectionSocket.close()
关键修改说明
- 完整的HTTP响应结构:添加了
Content-Type(指定响应内容类型)、Content-Length(告知客户端响应体长度),最后用\r\n空行分隔头部和响应体,让客户端能明确识别响应结束。 - 使用
sendall()替代send():send()可能只发送部分数据,sendall()会循环发送直到所有字节都传递到客户端,避免因数据未发完就关闭连接导致的异常。 - 新增异常防护:处理了请求格式错误(比如不是合法的GET请求)和其他意外异常,避免程序崩溃,同时给客户端返回合理的错误码。
- 空请求处理:提前判断客户端是否提前断开连接,避免后续代码因空字符串报错。
测试验证
用curl测试时,执行以下命令:
curl --path-as-is http://你的服务器IP:端口/../任意路径
现在你应该能收到明确的403响应,内容为Forbidden Access,curl也不会再返回52错误。
内容的提问来源于stack exchange,提问作者imtryingmybest
相关产品推荐
相关产品推荐

