https - TrueCat17/Ren-Engine GitHub Wiki

Проблема в использовании интернета

Хоть в версии питона для Ren-Engine и присутствуют модули вроде request и socket для работы с сетью, модуль _ssl - отсутствует.
Это значит, что скачать файл или страницу из интернета, используя протокол https, стандартными средствами невозможно.
А т. к. под 90% сайтов сейчас принудительно использует именно этот протокол, то и работа с сетью, по сути, становится недоступной.


Почему отсутствует модуль _ssl

Это C-расширение, и на каждой ОС оно должно удовлетворять всем требованиям "нативных" программ.
Проблема заключается в винде: при компиляции в dll-файле должно быть жёстко прописано, откуда следует брать функции питона (python C API).
В Ren-Engine питон линкуется статически (т. е. встраивается в исполняемый файл), т. к. этот подход на 30% повышает его производительность. В этом случае в качестве объекта, содержащего функции питона следует указать имя исполняемого файла.

Кажется, что это просто?
Но в винде в качестве имени приложения (например, в диспетчере задач) отображается именно имя файла, т. е. для каждой игры оно своё.
Поэтому задать раз и навсегда одно имя при компиляции _ssl просто невозможно, а с неправильным именем зависимости этот модуль не получится импортировать.

Так что тут получались следующие варианты:

  1. Жёстко патчить код модуля, чтобы получать и использовать ссылки на нужные функции нестандартным образом;
  2. Фиксить dll-файл во время обновления движка из лаунчера (долго, муторно и ненадёжно);
  3. Отказаться от 30% производительности и вернуться к динамической линковке питона;
  4. Вообще отказаться от работы с протоколом https;
  5. Использовать библиотеку для работы с ssl на чистом питоне.

Как можно догадаться, был выбран последний вариант.
Хоть такой код и работает, очевидно, медленнее варианта, написанного на C, это не слишком критично, к тому же на чистом питоне:

  • Исчезают вообще все проблемы сборки и использования кода на C;
  • Нет необходимости собирать код под все платформы (на Линуксе с этим хоть и лучше, но тоже не всё гладко);
  • На всех платформах используется один код;
  • Этот код весит 0.5 МБ вместо 2.2 (в сумме для 3 платформ).

Замена для _ssl

В качестве замены была выбрана библиотека 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) с текущим сервером.

⚠️ **GitHub.com Fallback** ⚠️