2011-07-07 12 views
1

適切な初期化した後、ここでは、着信HTTPS要求を処理するために無限ループだが、唯一つの要求あたりの接続(と仮定して要求は一つだけの読み取りを必要とする):この1行を変更すると、永続的なキープアライブ接続が実装されますか?

while TRUE do 
    begin // wait for incoming TCP connection 
    if listen(listen_socket, 100) 0 then continue; // listen failed 
    client_len := SizeOf(sa_cli); 
    sock := accept(listen_socket, @sa_cli, @client_len); // create socket for connection 
    if sock = INVALID_SOCKET then continue; // accept failed 
    ssl := SSL_new(ctx); // TCP connection ready, create ssl structure 
    if assigned(ssl) then 
    begin 
    SSL_set_fd(ssl, sock); // assign socket to ssl structure 
    if SSL_accept(ssl) = 1 then // handshake worked 
     begin 
     bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1); 
     if bytesin > 0 then 
     begin 
     buffer[bytesin] := #0; 
     // decide on response here... 
     response := 'HTTP/1.0 200 OK'#13#10 + etc; 
     SSL_write(ssl, pchar(response)^, length(response)); 
     end; // else read empty or failed 
     end; // else handshake failed 
    SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN or SSL_RECEIVED_SHUTDOWN); 
    CloseSocket(sock); 
    SSL_free(ssl); 
    end; // else ssl creation failed 
    end; // while 

はに

if ssl_accept(ssl) = 1 then 

を変えています

while ssl_accept(ssl) = 1 do 

デフォルトのHTTP 1.1キープアライブを正しくサポートするために必要なものすべて(つまり、c接続)?

+0

要求全体が1つの読むコールに満足されると仮定すると、失敗のレシピは次のとおりです。

は基本的に、あなたは、この種のモデル(擬似コード)を実装する必要があります。 – EricLaw

+0

これは、コードを短くして問題を気にかけないために行われました。 –

答えて

0

番号ssl_new()およびssl_accept()は、接続ごとに1回だけ呼び出される必要があります。一度接続してSSLセッションをネゴシエートすると、再度SSLセッションを行う必要はありません。 HTTPキープアライブは、各要求に対して再接続する必要がないように設計されています。代わりにssl_read()とSSL_write()にコールをループする必要があります。

また、クライアントのHTTPバージョンを確認することを忘れないでください。 HTTP 1.1クライアントは、デフォルトでキープアライブを要求することなくキープアライブをサポートすることが期待されています。 HTTP 1.0以前のクライアントでは、代わりに明示的に '接続:キープアライブ'要求ヘッダーを含める必要があります。いずれにしても、サーバーは接続が閉じられているか開いているかをクライアントに知らせるために、「Connection:close」または「Connection:keep-alive」応答ヘッダーを送信する必要があります。

while True do 
begin 
    accept an incoming connection... 

    initialize SSL... 

    repeat 
    read a request... 
    if not Connected then Break; 

    KeepAlive := ((client is HTTP1.1+) and (request['Connection'] = '')) or (request['Connection'] = 'keep-alive'); 

    prepare reply... 
    response['Connection'] := iif(KeepAlive, 'keep-alive', 'close'); 

    send reply... 

    while KeepAlive and Connected; 

    cleanup SSL... 
    close socket... 
end; 
+0

これは、特に「接続済み」を判断するために何をしているのかが不明なため、回答より多くの疑問が生じます。私はより一般的な質問としてこの問題を再確認するつもりです。また、サーバには「Connection:Close」を返すオプションがあり、キープアライブでは気にしません。 –

+0

要求がキープアライブを要求しても応答がそれを尊重するかもしれませんが、それは次の要求が到着する前に接続が実際に接続されていることを保証するものではありません。接続が、要求の間に長すぎるアイドル状態のままになっている場合、接続を閉じるファイアウォール/ルータを通過している可能性があります。 OpenSSLは、接続を読み書きしようとすると接続が切断されたかどうかを通知します。それに応じて私の擬似コード・モデルを調整しました。 –

+0

接続とリクエストが保証されていないため、私は質問6656090としてより一般的な問題を投稿しました。私は、ブロックソケットでSSL_readに詰まることを避けることができませんでした... –

関連する問題