2015-10-04 8 views
4

Я пытаюсь создать https-сервер в lazarus, используя синапс, но я терплю неудачу. Я хочу, чтобы сервер myserver получал данные от других https-клиентов. Я отправляю запросы с моим браузером, используя https://localhost:1500, а сервер myserver принимает сигналы. Но когда я пытаюсь читать отправленные данные, я ничего не получаю. Когда я тестировал простой HTTP-сервер, все работало нормально. Но теперь в случае https он не работает. Я использую ubuntu 15.04 в качестве своей ОСКак создать https-сервер, используя синапс в lazarus

s: = ASocket.RecvString (таймаут); // возвращает noething

Мой пример кода:

unit Unit1; 

{$mode objfpc}{$H+} 

interface 

uses 
    Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls; 

type 

    { TForm1 } 

    TForm1 = class(TForm) 
    Button1: TButton; 
    procedure Button1Click(Sender: TObject); 
    private 
    { private declarations } 
    public 
    { public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.lfm} 

uses 
    blcksock, sockets, Synautil, ssl_openssl, ssl_openssl_lib; 

procedure AttendConnection(ASocket: TTCPBlockSocket); 
var 
    timeout: integer; 
    s: string; 
    method, uri, protocol: string; 
    OutputDataString: string; 
    ResultCode: integer; 
begin 
    timeout := 1000; 

    WriteLn('Received headers+document from browser:'); 

    //read request line 
    s := ASocket.RecvString(timeout); 
    WriteLn(s); 
    method := fetch(s, ' '); 
    uri := fetch(s, ' '); 
    protocol := fetch(s, ' '); 

    //read request headers 
    repeat 
    s := ASocket.RecvString(Timeout); 
    WriteLn(s); 
    until s = ''; 

    // Now write the document to the output stream 

    if uri = '/' then 
    begin 
    // Write the output document to the stream 
    OutputDataString := 
     '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' 
     + ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' + CRLF 
     + '<html><h1>Teste</h1></html>' + CRLF; 

    // Write the headers back to the client 
    ASocket.SendString('HTTP/1.0 200' + CRLF); 
    ASocket.SendString('Content-type: Text/Html' + CRLF); 
    ASocket.SendString('Content-length: ' + IntTostr(Length(OutputDataString)) + CRLF); 
    ASocket.SendString('Connection: close' + CRLF); 
    ASocket.SendString('Date: ' + Rfc822DateTime(now) + CRLF); 
    ASocket.SendString('Server: Servidor do Felipe usando Synapse' + CRLF); 
    ASocket.SendString('' + CRLF); 

    // if ASocket.lasterror <> 0 then HandleError; 

    // Write the document back to the browser 
    ASocket.SendString(OutputDataString); 
    end 
    else 
    ASocket.SendString('HTTP/1.0 404' + CRLF); 
end; 

{ TForm1 } 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    ListenerSocket, ConnectionSocket: TTCPBlockSocket; 
begin 
    ListenerSocket := TTCPBlockSocket.Create; 
    ConnectionSocket := TTCPBlockSocket.Create; 

    ListenerSocket.CreateSocket; 
    ListenerSocket.SSL.CertificateFile := '/home/imants/projects/apps/medieval/bin/40669199_localhost_8080.cert'; 
    ListenerSocket.SSL.PrivateKeyFile := '/home/imants/projects/apps/medieval/bin/40669199_localhost_8080.key'; 
    ListenerSocket.SSLDoConnect; 
    ListenerSocket.setLinger(true,10); 
    ListenerSocket.bind('localhost','1500'); 
    ListenerSocket.listen; 

    repeat 
    if ListenerSocket.canread(1000) then 
    begin 
     ConnectionSocket.Socket := ListenerSocket.accept; 
     WriteLn('Attending Connection. Error code (0=Success): ', ConnectionSocket.lasterror); 
     AttendConnection(ConnectionSocket); 
     ConnectionSocket.CloseSocket; 
    end; 
    until false; 

    ListenerSocket.Free; 
    ConnectionSocket.Free; 
end; 

end. 
+0

Вы следовали (или находили) инструкции по адресу http://www.ararat.cz/synapse/doku.php/public:howto:httpsserver? – Rik

+0

Нет. Я нашел этот пример еще где я попытаюсь проверить HTTP Server Demo (который, я думаю, поставляется с синапсом) и попытается изменить его соответствующим образом. –

+0

К сожалению, пример http-сервера ведьма приходит с синапсом - это спецификация Windows, потому что он использует winsock unit witch Lazarus не поддерживает по крайней мере в Linux –

ответ

3

Есть два источника, которые я знаю, с примером для HTTP-сервера в Synapse.

Первый пример представлен в Synapse stable package (release 40). Хотя я бы рекомендовал вам использовать SVN version (вы можете использовать кнопку Download Snapshot на этой странице), вы все равно можете использовать примеры в пакете «релиз 40».

Пример в synapse40\source\demo\httpsserv должен использоваться как HTTPS-сервер. Если вы не можете взять пример httpserv (HTTP) и изменить его как shown here. (Но я думаю, что httpsserv это то же самое с теми изменениями)

Если вы на Linux (Lazarus), вы должны изменить каждое вхождение winsock в synsock и удалите windows -clause.

Другим примером может быть found here. (Direct download of SynHttp.zip) Насколько я понял, он также имеет функциональность HTTPS-сервера.

2

Я знаю, что вы хотите использовать Synapse, но вы можете захотеть взглянуть на Инди. Я уже несколько лет разрабатываю серверные/клиентские приложения с indy, и мне это нравится. Он отлично работает с окнами и linux (32bit, 64bit, arm ...) и имеет некоторые приятные функции. Вы можете использовать компонент TIdHTTPServer. Кроме того, получите IOHandlerSSLOpenSSL. Событие OnCommandGet (AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo) является наиболее важным. Он позволяет получить доступ к запросу (например, A ARequestInfo.Document) и вашему HTTP-ответу (AResponseInfo).

+0

Я использовал indy, и это работало решеткой. Но у него есть некоторые плохие проблемы с Lazarus, так как мой сервер автоматической сборки не может скомпилировать его на 100% из-за некоторых ошибок в Lazarus или их пакета. При компиляции он не может найти IdStreamVCL :(Поэтому теперь я пытаюсь использовать некоторые другие методы. Но если я не найду что-то, то да Indy. –

+1

Установка Indy для Lazarus - это беспорядок, но вам не нужно :) Вы можете просто скопировать папку indy в папку проекта. В Lazarus нажмите Shift + Ctrl + F11 и выберите «Параметры компилятора» -> «Контуры». Добавьте свою исходную папку Indy (Indy \ source) в файлы других файлов и ваши готовые файлы :) Просто добавьте нужные единицы и создайте компоненты во время выполнения. –

+0

Ваш совет помог мне разобраться с проблемами с инди. Это не лучшее решение, которое я хотел бы сделать лучше, чем это было. Но поскольку это не отвечало на мой первоначальный вопрос, я не буду принимать это как ответ. –