https - TrueCat17/Ren-Engine GitHub Wiki
Хоть в версии питона для Ren-Engine и присутствуют модули вроде request
и socket
для работы с сетью, модуль _ssl
- отсутствует.
Это значит, что скачать файл или страницу из интернета, используя протокол https
,
стандартными средствами невозможно.
А т. к. под 90% сайтов сейчас принудительно использует именно этот протокол,
то и работа с сетью, по сути, становится недоступной.
Это C
-расширение, и на каждой ОС оно должно удовлетворять всем требованиям "нативных" программ.
Проблема заключается в винде: при компиляции в dll-файле должно быть жёстко прописано,
откуда следует брать функции питона (python C API).
В Ren-Engine питон линкуется статически (т. е. встраивается в исполняемый файл),
т. к. этот подход на 30% повышает его производительность.
В этом случае в качестве объекта, содержащего функции питона следует указать имя исполняемого файла.
Кажется, что это просто?
Но в винде в качестве имени приложения (например, в диспетчере задач) отображается именно имя файла,
т. е. для каждой игры оно своё.
Поэтому задать раз и навсегда одно имя при компиляции _ssl
просто невозможно,
а с неправильным именем зависимости этот модуль не получится импортировать.
Так что тут получались следующие варианты:
- Жёстко патчить код модуля, чтобы получать и использовать ссылки на нужные функции нестандартным образом;
- Фиксить dll-файл во время обновления движка из лаунчера (долго, муторно и ненадёжно);
- Отказаться от 30% производительности и вернуться к динамической линковке питона;
- Вообще отказаться от работы с протоколом
https
; - Использовать библиотеку для работы с ssl на чистом питоне.
Как можно догадаться, был выбран последний вариант.
Хоть такой код и работает, очевидно, медленнее варианта, написанного на C
,
это не слишком критично, к тому же на чистом питоне:
- Исчезают вообще все проблемы сборки и использования кода на
C
; - Нет необходимости собирать код под все платформы (на Линуксе с этим хоть и лучше, но тоже не всё гладко);
- На всех платформах используется один код;
- Этот код весит
0.5
МБ вместо2.2
(в сумме для 3 платформ).
В качестве замены была выбрана библиотека tlslite-ng.
К ней были добавлены зависимости, и во всём этом были убраны лишние для Ren-Engine части, такие как совместимость со старыми версиями питона, работа с электронной почтой и т. д.
Отредактированные используемые исходники tlslite-ng
и зависимостей, а также некоторые подробности хранятся
здесь.
# HTTPTLSConnection = tlslite-ng + http.client
from tlslite import HTTPTLSConnection
domain = "raw.githubusercontent.com"
file = "TrueCat17/Ren-Engine/master/README.md"
conn = HTTPTLSConnection(domain, 443) # 443 - usual port for https
conn.request("GET", file) # method, path
response = conn.getresponse()
data = response.read(100)
print(data)
Для простого скачивания файла сделана функция
https.get_file(url, local_path, on_end, on_error, clean = False)
Здесь:
-
url
- url файла, который нужно скачать; -
local_path
- путь, куда нужно скачать файл; -
on_end
- функция, вызываемая при удачном завершении; -
on_error
- функция, вызываемая при ошибке; -
clean
- нужно ли удалять файл по путиlocal_path
(если есть).
Если clean
установлен в False
, то Ren-Engine
по возможности пытается продолжить скачивание,
а не начинать его с нуля (полезно при прерванной загрузке файла в прошлый раз).
Внимание!
Эту функцию не следует вызывать снова до завершения скачивания, ошибки или отмены.
Для отмены же имеется функция https.close(close_conn = True)
, где
close_conn
определяет, нужно ли закрывать соединение (HTTPTLSConnection
) с текущим сервером.