我正在寻找使用flask API为选择性URL发送TCP重置的方法。 例如:
GET url1 -> sends 200 OK,GET url2 -> sends TCP reset,GET url3 -> sends 200 OK,GET url4 -> sends TCP reset
请让我知道我们是否可以使用flask API实现此目的。 ? 我们可以使用任何其他工具来实现这一目标。非常感谢您的帮助。
看看Python Sicket文档https://docs.python.org/3/howto/sockets.html
我认为您可以根据以下答案发送这样的TCP重置:Sending a reset in TCP/IP Socket connection
def client(host,port):
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
s.connect((host,port))
l_onoff = 1
l_linger = 0
s.setsockopt(socket.SOL_SOCKET,socket.SO_LINGER,struct.pack('ii',l_onoff,l_linger))
# send data here
s.close()
,
到目前为止,无法从flask应用程序本身获取flask的连接套接字对象。
根据我在other questions上关于flask套接字的发现,看来我们可以为werkzeug.serving.BaseWSGIServer
设置套接字的文件描述符。
另一个问题是sending a socket reset in a pythonic way。
因此,我能够将链接的问题的答案合并成这样,我使用了默认的werkzeug的wsgi服务器(调用app.run
时使用的服务器)。
import logging
import os
import socket
import socketserver
import struct
from flask import Flask,abort,request,session
from werkzeug.serving import BaseWSGIServer
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
app = Flask(__name__)
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.set_inheritable(True)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock.setsockopt(socket.SOL_SOCKET,1,0))
@app.route('/hello')
def hello():
return "Hello"
@app.route('/bye')
def bye():
return ""
if __name__ == "__main__":
try:
bind_to = ('127.0.0.1',5000)
sock.bind(bind_to)
sock.listen()
sock_fd = sock.fileno()
logging.info("Sock FD is {}".format(sock_fd))
# calls Socket.dup on the sock_fd
# and passes the context into init of inherited
# HTTPServer,rendering the server and sock
# unpatchable afterwards
base_wsgi = BaseWSGIServer(
*bind_to,app,fd=sock_fd)
base_wsgi.serve_forever()
finally:
if not sock._closed:
msg = "Socket not closed,closing."
sock.close()
else:
msg = "Socket already closed."
logger.info(msg)
使用不同的wsgi后端(例如Gevent,Twisted web,...)控制socket
和connection
可能更容易,也可能没有,
从Wireshk进行检查,现在它会在每个请求后另外发送RST 。因此,连接自然关闭后-FIN。
一个问题是无法控制RST-基本上使用SO_LINGER
选项扩展了套接字,从而导致在关闭连接时始终发送RST。要允许选择性的RST发送,必须将底层的connection
(从sock
创建)传播到端点,然后在该连接上设置sockoption并关闭它-这也可能导致底层的web服务器失败。