previous question询问是否更改一行代码是否实现了持久SSL连接。在看到该问题的答复并检查了SSL文档的不足后,出现以下情况:


对于服务器,持久连接只是在SSL_accept()和SSL_set_shutdown()之间进行重复的请求/响应。
根据this page,客户端必须通过发送适当的“ Content-length:”标头或使用商定的终止请求来指示将有多少个请求。


但是,不能保证客户端会发送预期的内容。因此,使用阻塞套接字的服务器似乎可以无限期地挂在SSL_read()上,同时等待从未到达的其他请求。 (SSL_CTX_set_timeout()似乎不会导致随后的SSL_read()提前退出,因此,如果套接字阻塞,则不清楚如何执行this Wikipedia page中所述的超时连接。)

显然,服务器可以通过返回带有响应的“ Connection:Close”标头来表明它不会保持活动状态,因此我最终获得了以下代码,至少应始终正确执行单个请求/响应每个连接:

while TRUE do
  begin  // wait for incoming TCP connection
  if notzero(listen(listen_socket, 100)) 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
      request := '';
      repeat // gather request
        bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1);
        if bytesin > 0 then
          begin
          buffer[bytesin] := #0;
          request := request + buffer;
          end;
      until SSL_pending(ssl) <= 0;
      if notempty(request) then
        begin // decide on response, avoid keep-alive
        response := 'HTTP/1.0 200 OK'#13#10'Connection: Close'#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; // infinite while


两个问题:

(1)由于SSL_accept()必须为true才能达到SSL_read(),是否为true SSL_read()永远无法挂起以等待第一个请求?

(2)应该如何修改此代码以使用阻塞套接字进行超时的持久性/保持活动的SSL连接(如果可能的话)?

最佳答案

this letter引用,“确保避免无限阻塞的唯一方法是使用非阻塞I / O。”因此,我想我会放弃尝试超时阻止SSL_read()s的方法。

07-28 03:10
查看更多