2013-05-03 4 views
3

Я недавно обновил свой Delphi 7 до Delphi XE2, и я к нему не знаком. Я использовал Indy 10 с OpenSSL для получения содержимого HTTP. Он работает отлично, и я хотел бы поделиться своей программой с другими людьми. Я только узнал, что мои программы не будут работать на других ПК без библиотек OpenSSL. Я даже не получил исключение, ошибку и т. Д. Из-за отсутствия файлов DLL. Я думал, что Indy10 имеет либо собственную поддержку SSL, либо, по крайней мере, использует библиотеки DLL из ресурсов после компиляции, поэтому он будет переносимым. У меня есть 2 вопроса:Indy 10 и OpenSSL

1) Как я могу сообщить пользователю, что ему не хватает библиотек OpenSSL? (Друзья не сообщили об исключениях, ошибках и т. Д. БЕЗ OpenSSL DLL.)

2) Можно ли Indy10 читать библиотеки OpenSSL из ресурсов?

ответ

8

Indy не реализует SSL изначально. Он реализует гибкую архитектуру IOHandler, которая позволяет подключать любую версию SSL к Indy. Indy сам реализует собственный класс IOHandler, основанный на OpenSSL (поддержка MS CryptoAPI запланирована на будущее). SecureBlackbox, например, предоставляет класс Indy IOHandler для своего собственного механизма SSL.

На большинстве платформ OpenSSL используется через внешние библиотеки DLL, которые нельзя использовать из ресурсов. Indy не поставляется с DLL OpenSSL, поскольку шифрование OpenSSL ограничено международными законами об импорте/экспорте, поэтому у обоих поставщиков ОС, которые поставляются на международном уровне, есть специальные лицензии на отправку DLL OpenSSL, или конечным пользователям приходится самостоятельно загружать/компилировать OpenSSL самостоятельно. Именно это делает Indy «переносимым», когда дело доходит до OpenSSL. Indy использует любые DLL OpenSSL, предварительно установленные вне Indy, либо в ОС, либо в собственной папке установки вашего приложения.

Единственное исключение для Indy - OpenSSL на iOS, которое требует использования OpenSSL статически, потому что на устройствах iOS не допускаются сторонние динамические библиотеки.

Если вы хотите использовать OpenSSL статически с Indy на других платформах, вам нужно самостоятельно собрать/получить статическую версию OpenSSL и добавить его в свой проект, а затем перекомпилировать Indy, чтобы включить его определение STATICLOAD_OPENSSL (которое в настоящее время определено только для iOS) и, наконец, включите блок IdSSLOpenSSLHeaders_static.pas в код uses вашего кода, чтобы подключить необходимый код поддержки. Обратите внимание, что это поддерживается только в недавно выпущенной версии Indy 10.6.

Если это слишком много для вас, используйте стороннюю реализацию SSL, совместимую с Indy, такую ​​как SecureBlackbox, или напишите свой собственный класс IOHandler, который сделает все, что вам нужно.

Как для других вопросов:

1) Инди делает вызывать исключения, если он не может загрузить OpenSSL правильно во время операций с сокетами. Таким образом, вероятность того, что эти исключения пойманы и проглочены, прежде чем вы сможете сообщить об этом своим пользователям. Если вы не хотите полагаться на это, вы можете вручную вызвать функцию Indys Load() в блоке IdSSLOpenSSLHeaders.pas перед началом работы сокета. Load() загрузит OpenSSL в память, если он еще не загружен.Если Load() не работает, вы можете вызвать функцию WhichFailedToLoad() в том же блоке, чтобы узнать, почему Load() не удалось.

2) Нет, OpenSSL нельзя использовать из ресурсов (без какой-либо действительно серьезной низкоуровневой хитрости).

+0

Большое спасибо! Это очистило все для меня. –

+1

Почему Indy не реализует SSL изначально? Все страдают из-за необходимости использования этих внешних dll. –

+1

Было бы серьезным обязательством внедрить SSL изначально. Зачем тратить время и силы, когда другие уже реализуют реализации? В любом случае я упомянул, что мы планируем создать оболочку IOHandler для CryptoAPI, чтобы решить проблемы с DLL и проблемы импорта/экспорта в Windows, поскольку она встроена в ОС. На других платформах обычно используется OpenSSL. –

1

1) Попробуйте загрузить e DLL самостоятельно перед вызовом Indy, и если LoadLibrary не удастся, вы можете создать исключение.

2) Вы можете, посмотрите это:

Load a DLL From a Resource Directly From Memory in Delphi Applications

+0

Это должно сработать, но мне придется отредактировать фактический исходный код Indy, и я не знаю с чего начать. –

+1

Зачем вам редактировать Indy Code? Приложение будет загружать dll только один раз, поэтому, если вы загрузите его до вызова indy, вы будете в порядке. –

+0

Я не знаю, возможно ли это, если Indy уже вызывает LoadLibrary до того, как я это сделаю (инициализация). И что, если Indy вызывает GetModuleHandle и т. Д., Он будет загружать библиотеки, вероятно, дважды или что-то в этом роде. Я еще ничего не тестировал, но я сделаю это позже, чтобы узнать, работает ли это. –