I have a state machine with the following states: create, connect, send, receive.
When the state sequence is the following: create, connect, send, receive everything is ok (with my code, sent in the previous email). However when there is a receive code after connect there is a problem. There is no data after this receive phase (maybe is not problem) but after that: send executed successfully and the receive returns with no data. create connect receive : no data, maybe ok send: ok receive : no data here !! create: calls CreateSSL connect: calls ConnectSSL send: calls SendSSL receive: calls ReceiveSSL What may the problem? Attila On Mon, Jun 22, 2020 at 7:35 PM Viktor Dukhovni <openssl-us...@dukhovni.org> wrote: > On Mon, Jun 22, 2020 at 03:17:41PM +0200, Attila Csosz wrote: > > > char HEADERS[] = "GET /search?q=arduino HTTP/1.1\r\nHost: > > www.google.com\r\nConnection: > close\r\n\r\n"; > > char HOST_NAME_PORT[] = "www.google.com:443"; > > Note the "Connection: close" in the HTTP request header! > > > void init_openssl() > > { > > SSL_load_error_strings(); > > SSL_library_init(); > > } > > > > void CreateSSL() > > { > > // Create SSL context > > meth = SSLv23_client_method(); > > if (!meth) throw Exception("SSL: method"); > > > > ctx = SSL_CTX_new(meth); > > if (!ctx) throw Exception("SSL: SSL_CTX_new"); > > old_opts = SSL_CTX_set_options(ctx, SSL_OP_ALL); > > The SSL_CTX need only be created once, not once per connection. > You've made no provision for verifying the server certificate. > Typically you would load trusted CA certificate locations into > the SSL_CTX. > > > web = BIO_new_ssl_connect(ctx); > > if (!web) throw Exception("SSL: BIO_new_ssl_connect"); > > } > > This code belows in the ConnectSSL function. > > > > > void ConnectSSL() > > { > > // Connect > > res = BIO_set_conn_hostname(web, HOST_NAME_PORT); > > if (!res) throw Exception("SSL: BIO_ctrl"); > > > > res = BIO_get_ssl(web, &ssl); > > if (!res) throw Exception("SSL: BIO_ctrl"); > > > > res = SSL_set_cipher_list(ssl, PREFERRED_CIPHERS); > > if (!res) throw Exception("SSL: SSL_set_cipher_list"); > > > > res = BIO_do_connect(web); > > if (res <= 0) throw Exception("SSL: BIO_do_connect"); > > > > res = BIO_do_handshake(web); > > if (res <= 0) throw Exception("SSL: BIO_do_handshake"); > > This connection is unauthenticated. Perhaps that's OK, but often it is > not. > > > } > > > > void SendSSL() > > { > > // Send > > err = BIO_puts(web, HEADERS); > > if (err <= 0) throw Exception("SSL: BIO_puts"); > > } > > > > void ReceiveSSL() > > { > > // Read > > sResult = ""; > > for (;;) { > > len = BIO_read(web, buf, sizeof(buf)); > > sResult += buf; > > if (len <= 0) > > break; > > } > > The server closes the connection after returning its reply. > You need to close the SSL BIO to avoid a memory leak. > > > --------- > > It is ok for one request. > > > > My problem when I trying to send a new search request to google it works > > only when I call > > CreateSSL(); > > ConnectSSL(); > > again > > Naturally, you're not doing HTTP/1.1 connection keep-alive, and in any > case would need to be prepared for the server to close the connection > now and then. You need an actual HTTPS library, naive open-coding of an > HTTP client over SSL is unlikely to be correct. Something like libcurl > or similar is the way to go. > > > What may the problem? > > You're writing a naïve HTTPS client from scratch. A correct > implementation would understand "Content-Length" and chunked > trasfer encoding, handle server-initiated disconnects, be > prepared to receive multi-record responses, ... > > -- > Viktor. >