I need a minimal SSL server and came up with the following:
confirm(WSAStartup(MakeWord(1,1), WData) = 0); SSL_library_init; SSL_load_error_strings; ctx := SSL_CTX_new(SSLv23_server_method); confirm(ctx <> nil); confirm(SSL_CTX_use_certificate_chain_file(ctx, 'cert.pem') > 0); confirm(SSL_CTX_use_PrivateKey_file(ctx, 'key.pem', SSL_FILETYPE_PEM) > 0); confirm(SSL_CTX_check_private_key(ctx)); SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); listen_socket := socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); confirm(listen_socket <> 0); sa_serv.sin_family := AF_INET; sa_serv.sin_port := htons(DEFAULTPORT); sa_serv.sin_addr.s_addr := INADDR_ANY; confirm(bind(listen_socket, sa_serv, SizeOf(sa_serv)) = 0); while TRUE do begin if listen(listen_socket, 100) <> 0 then continue; client_len := SizeOf(sa_cli); sock := accept(listen_socket, @sa_cli, @client_len); if sock = INVALID_SOCKET then continue; ssl := SSL_new(ctx); if ssl = nil then continue; SSL_set_fd(ssl, sock); if SSL_accept(ssl) = 1 then begin bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1); if bytesin > 0 then begin buffer[bytesin] :=
A single SSL_read will capture the entire GET or POST request from Firefox, and everything works fine. On the other hand, Chrome GET will call the first few SSL_read calls to return null bytes, but eventually SSL_read will grab the entire GET request, and the code still works.
But when Chrome sends a POST, the first few calls to SSL_read pick up the null bytes, and the next SSL_read will grab ONLY HEADERS . The getresponse () routine cannot understand POST because another SSL_read is needed to capture the contents of the POST.
SSL_MODE_AUTO_RETRY was set, hoping that SSL_read would not be present until the entire request was completed, but this did not work. SSL_pending always returns zero, before or after each SSL_read, so no help either.
As this question answers , non-blocking SSL seems to contain a lot of torture and heartburn. I played with SSL_reads executing in a separate thread and killed the thread after shutting down on a verified read, but this seems dangerous because it is not known what state SSL is in (or how to reset it) when the thread is killed.
Does anyone have code for a minimal loop similar to the one above, but it will not hang on Chrome POST or SSL_read, which is simple and fairly vanilla easy to convert to Delphi 6?