Я не могу установить HTTPS-соединение с программойPython

Программы на Python
Ответить
Anonymous
 Я не могу установить HTTPS-соединение с программой

Сообщение Anonymous »

Есть программа, которая генерирует XML-файлы с результатами соревнований, не могу разобраться в коде этой программы. В программе есть возможность выводить данные через HTTP-запросы. Я написал мини-сервер Tornado Python для получения этих данных. С обычным HTTP-соединением разобрался, и мне удалось установить соединение и получить данные, а с HTTPS — нет. Получается, что в обычном HTTP программа выступает в роли HTTP-клиента и отправляет данные на сервер. Сначала я отправил запрос опций, и после ответа сервера соединение устанавливается и отправляются почтовые запросы. Но в случае с HTTPS я не знаю, что происходит. Простое добавление оболочки TSL не работает. Потому что после успешного рукопожатия сразу разрывается соединение с сервером. После разрыва соединения программа пытается подключиться с другого порта. И я так понимаю, что даже первый запрос опций не успевает отправить. Интерфейс программы не содержит никаких данных о подключении, кроме включения и отключения режима HTTPS.
При успешном подключении приложение выглядит следующим образом.
Документации к нему нет. программа. :D
HTTP-соединение
Вот как выглядит мой код для успешного HTTP-соединения< /p>

Код: Выделить всё

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):

def log_request(self):
print("----- HTTP Request -----")
print(f"Method: {self.request.method}")
print(f"URI: {self.request.uri}")
print(f"Headers: \n{self.request.headers}")
if self.request.body:
print(f"Body: {self.request.body.decode('utf-8')}")
print(f"protocol: {self.request.protocol}")
print("------------------------")
print(f"Request: {self.request}")
print("------------------------")

def post(self):
self.log_request()
if len(self.request.body) >  MAX_MESSAGE_SIZE:
self.set_status(413)
self.write("Payload Too Large")
return
data = self.request.body.decode("utf-8")
print(f"Received POST data: {data}")

self.set_status(200)
self.write("POST data received")

def get(self):
self.set_status(201)

def options(self):
self.log_request()
self.set_status(200)
self.set_header("Cache-Control","no-cache")
self.set_header("X-HOVTP-Environment","Test")
self.set_header("X-HOVTP-Last-Serial-Number","12345")
self.set_header("X-HOVTP-Keep-Alive-Interval","20")

class sMainHandler(tornado.web.RequestHandler):

def log_request(self):
print("----- HTTP Request -----")
print(f"Method: {self.request.method}")
print(f"URI: {self.request.uri}")
print(f"Headers: \n{self.request.headers}")
if self.request.body:
print(f"Body: {self.request.body.decode('utf-8')}")
print(f"protocol: {self.request.protocol}")
print("------------------------")
print(f"Request: {self.request}")
print("------------------------")

def options(self):
self.log_request()
self.set_status(200)
self.set_header("Cache-Control", "no-store, no-cache")
self.set_header("Connection", "keep-alive")

def make_app():
return tornado.web.Application([
(r"/HOVTP/", MainHandler),
#(r".*", sMainHandler),
])

if __name__ == "__main__":
app = make_app()
app.listen(443)
print("Server is running on http://localhost:8888")
tornado.ioloop.IOLoop.current().start()

А теперь HTTPS-соединение
Вот мой самый рабочий код для подключения на данный момент

Код: Выделить всё

import tornado.ioloop
import tornado.web
from tornado import http1connection
from tornado.tcpserver import TCPServer
from tornado.iostream import StreamClosedError
import socket, ssl
import logging
import asyncio
import functools

def get_ssl_context():
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_context.verify_mode = ssl.VerifyMode.CERT_NONE
ssl_context.load_cert_chain("cert/certificate.crt", "cert/privateKey.key")
ssl_context.keylog_filename = "keys.txt"
ssl_context.options |= ssl.OP_NO_COMPRESSION
ssl_context.options |= ssl.OP_NO_TICKET
ssl_context.options |= ssl.OP_ENABLE_MIDDLEBOX_COMPAT
ssl_context.options |= ssl.OP_SINGLE_ECDH_USE
return ssl_context

class EchoServer(TCPServer):
async def handle_stream(self, stream, address):
while True:
try:
data = await stream.read_until(b"\n")
await stream.write(data)
except StreamClosedError:
print(stream.closed(), address)
break

if __name__ == "__main__":
try:
async def main():
server = EchoServer(get_ssl_context())
server.listen(443)
await asyncio.Event().wait()
asyncio.run(main())
except ssl.SSLError:
print(ssl.SSLError)
А вот вывод Wireshark

Код: Выделить всё

No.     Time           Source                Destination           Protocol Length Info
25 2.696257       127.0.0.1             127.0.0.1             TCP      56     52908 → 443 [SYN] Seq=0 Win=65535 Len=0 MSS=65495 WS=256 SACK_PERM

Frame 25: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 0, Len: 0

No.      Time           Source                Destination           Protocol Length Info
26 2.696292       127.0.0.1             127.0.0.1             TCP      56     443 → 52908 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=65495 WS=256 SACK_PERM

Frame 26: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 443, Dst Port: 52908, Seq: 0, Ack: 1, Len: 0

No.     Time           Source                Destination           Protocol Length Info
27 2.696315       127.0.0.1             127.0.0.1             TCP      44     52908 → 443 [ACK] Seq=1 Ack=1 Win=2161152 Len=0

Frame 27: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 1, Ack: 1, Len: 0

No.     Time           Source                Destination           Protocol Length Info
28 2.696401       127.0.0.1             127.0.0.1             HTTP     302    OPTIONS /HOVTP/ HTTP/1.1

Frame 28: 302 bytes on wire (2416 bits), 302 bytes captured (2416 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 1, Ack: 1, Len: 258
Hypertext Transfer Protocol

No.     Time           Source                Destination           Protocol Length Info
30 2.696418       127.0.0.1             127.0.0.1             TCP      44     443 → 52908 [ACK] Seq=1 Ack=259 Win=2160896 Len=0

Frame 30: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 443, Dst Port: 52908, Seq: 1, Ack: 259, Len: 0

No.     Time           Source                Destination           Protocol Length Info
36 2.698030       127.0.0.1             127.0.0.1             HTTP     308    HTTP/1.1 200 OK

Frame 36: 308 bytes on wire (2464 bits), 308 bytes captured (2464 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 443, Dst Port: 52908, Seq: 1, Ack: 259, Len: 264
Hypertext Transfer Protocol

No.     Time           Source                Destination           Protocol Length Info
37 2.698047       127.0.0.1             127.0.0.1             TCP      44     52908 → 443 [ACK] Seq=259 Ack=265 Win=2160896 Len=0

Frame 37: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 259, Ack: 265, Len: 0

No.     Time           Source                Destination           Protocol Length Info
62 7.711112       127.0.0.1             127.0.0.1             HTTP     302    OPTIONS /HOVTP/ HTTP/1.1

Frame 62: 302 bytes on wire (2416 bits), 302 bytes captured (2416 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 259, Ack: 265, Len: 258
Hypertext Transfer Protocol

No.     Time           Source                Destination           Protocol Length Info
63 7.711134       127.0.0.1             127.0.0.1             TCP      44     443 → 52908 [ACK] Seq=265 Ack=517 Win=2160640 Len=0

Frame 63: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 443, Dst Port: 52908, Seq: 265, Ack: 517, Len: 0

No.     Time           Source                Destination           Protocol Length Info
66 7.712553       127.0.0.1             127.0.0.1             HTTP     308    HTTP/1.1 200 OK

Frame 66: 308 bytes on wire (2464 bits), 308 bytes captured (2464 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 443, Dst Port: 52908, Seq: 265, Ack: 517, Len: 264
Hypertext Transfer Protocol

No.      Time           Source                Destination           Protocol Length Info
67 7.712590       127.0.0.1             127.0.0.1             TCP      44     52908 → 443 [ACK] Seq=517 Ack=529 Win=2160640 Len=0

Frame 67: 44 bytes on wire (352 bits), 44 bytes captured (352 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 52908, Dst Port: 443, Seq: 517, Ack: 529, Len: 0

Я тоже пытался построить такой сервер

Код: Выделить всё

async def handle_connection(connection, address):
io_loop = tornado.ioloop.IOLoop.current()
print(f"Connect from {address[0]}:{address[1]}")
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_context.load_cert_chain("cert/certificate.crt", "cert/privateKey.key")
ssl_context.keylog_filename = "keys.txt"
ssl_context.options |= ssl.OP_NO_COMPRESSION
ssl_context.options |= ssl.OP_NO_TICKET
stream = tornado.iostream.IOStream(connection)
stream.set_nodelay(True)
stream = await stream.start_tls(True,ssl_context)
stream = await stream.wait_for_handshake()
print(stream.socket.session, stream.socket.session.id)
sessionList.append(stream)

def new_con(sock,fd,events):
print("Current connections:")
for i in sessionList:
print(i, i.closed())
while True:
try:
conn, fromaddr = sock.accept()
except BlockingIOError:
print("Close connection")
return
io_loop = tornado.ioloop.IOLoop.current()
io_loop.spawn_callback(handle_connection, conn, fromaddr)

async def main():
print("Listen for connection.")
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setblocking(0)
sock.bind(("127.0.0.1", 443))
sock.listen(5)
io_loop = tornado.ioloop.IOLoop.current()
callback = functools.partial(new_con, sock)
io_loop.add_handler(sock.fileno(), callback, io_loop.READ)
await asyncio.Event().wait()

if __name__ == "__main__":
try:
asyncio.run(main())
except ssl.SSLError:
print(ssl.SSLError)
Вот попытка подключения из Wireshark
Здесь я сохранил 3 попытки подключения, чтобы показать, как сервер меняет порт

Подробнее здесь: https://stackoverflow.com/questions/793 ... he-program
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»