mirror of https://github.com/openssl/openssl
Update the OpenSSL Guide tutorials with changes to the demos
The demo code has changed to accept the hostname/port on the command line. We update the tutorials to keep in sync with the demo code. Reviewed-by: Paul Dale <pauli@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Richard Levitte <levitte@openssl.org> Reviewed-by: Hugo Landau <hlandau@openssl.org> (Merged from https://github.com/openssl/openssl/pull/22552)
This commit is contained in:
parent
cb8107b632
commit
9e973eb297
|
@ -341,13 +341,26 @@ data on a retry. An optional mode does exist
|
|||
the buffer being written to change from one retry to the next. However, in this
|
||||
case, you must still retry exactly the same data - even though the buffer that
|
||||
contains that data may change location. See L<SSL_CTX_set_mode(3)> for further
|
||||
details.
|
||||
details. As in the TLS tutorials (L<ossl-guide-tls-client-block(7)>) we write
|
||||
the request in three chunks.
|
||||
|
||||
/* Write an HTTP GET request to the peer */
|
||||
while (!SSL_write_ex(ssl, request, strlen(request), &written)) {
|
||||
while (!SSL_write_ex(ssl, request_start, strlen(request_start), &written)) {
|
||||
if (handle_io_failure(ssl, 0) == 1)
|
||||
continue; /* Retry */
|
||||
printf("Failed to write HTTP request\n");
|
||||
printf("Failed to write start of HTTP request\n");
|
||||
goto end; /* Cannot retry: error */
|
||||
}
|
||||
while (!SSL_write_ex(ssl, hostname, strlen(hostname), &written)) {
|
||||
if (handle_io_failure(ssl, 0) == 1)
|
||||
continue; /* Retry */
|
||||
printf("Failed to write hostname in HTTP request\n");
|
||||
goto end; /* Cannot retry: error */
|
||||
}
|
||||
while (!SSL_write_ex(ssl, request_end, strlen(request_end), &written)) {
|
||||
if (handle_io_failure(ssl, 0) == 1)
|
||||
continue; /* Retry */
|
||||
printf("Failed to write end of HTTP request\n");
|
||||
goto end; /* Cannot retry: error */
|
||||
}
|
||||
|
||||
|
|
|
@ -213,23 +213,43 @@ uni-directional one:
|
|||
=head2 Writing data to the streams
|
||||
|
||||
Once the streams are successfully created we can start writing data to them. In
|
||||
this example we will be sending a different HTTP request on each stream. We
|
||||
assume the strings B<request1> and B<request2> hold the appropriate HTTP
|
||||
requests. For the sake of simplicity this example does this sequentially,
|
||||
writing to B<stream1> first and, when this is successful, writing to B<stream2>
|
||||
second. Remember that our client is blocking so these calls will only return
|
||||
once they have been successfully completed. A real application would not need to
|
||||
do these writes sequentially or in any particular order. For example we could
|
||||
start two threads (one for each stream) and write the requests to each stream
|
||||
simultaneously.
|
||||
this example we will be sending a different HTTP request on each stream. To
|
||||
avoid repeating too much code we write a simple helper function to send an HTTP
|
||||
request to a stream:
|
||||
|
||||
int write_a_request(SSL *stream, const char *request_start,
|
||||
const char *hostname)
|
||||
{
|
||||
const char *request_end = "\r\n\r\n";
|
||||
size_t written;
|
||||
|
||||
if (!SSL_write_ex(stream, request_start, strlen(request_start), &written))
|
||||
return 0;
|
||||
if (!SSL_write_ex(stream, hostname, strlen(hostname), &written))
|
||||
return 0;
|
||||
if (!SSL_write_ex(stream, request_end, strlen(request_end), &written))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
We assume the strings B<request1_start> and B<request2_start> hold the
|
||||
appropriate HTTP requests. We can then call our helper function above to send
|
||||
the requests on the two streams. For the sake of simplicity this example does
|
||||
this sequentially, writing to B<stream1> first and, when this is successful,
|
||||
writing to B<stream2> second. Remember that our client is blocking so these
|
||||
calls will only return once they have been successfully completed. A real
|
||||
application would not need to do these writes sequentially or in any particular
|
||||
order. For example we could start two threads (one for each stream) and write
|
||||
the requests to each stream simultaneously.
|
||||
|
||||
/* Write an HTTP GET request on each of our streams to the peer */
|
||||
if (!SSL_write_ex(stream1, request1, strlen(request1), &written)) {
|
||||
if (!write_a_request(stream1, request1_start, hostname)) {
|
||||
printf("Failed to write HTTP request on stream 1\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!SSL_write_ex(stream2, request2, strlen(request2), &written)) {
|
||||
if (!write_a_request(stream2, request2_start, hostname)) {
|
||||
printf("Failed to write HTTP request on stream 2\n");
|
||||
goto end;
|
||||
}
|
||||
|
|
|
@ -272,13 +272,13 @@ like this:
|
|||
* Tell the server during the handshake which hostname we are attempting
|
||||
* to connect to in case the server supports multiple hosts.
|
||||
*/
|
||||
if (!SSL_set_tlsext_host_name(ssl, HOSTNAME)) {
|
||||
if (!SSL_set_tlsext_host_name(ssl, hostname)) {
|
||||
printf("Failed to set the SNI hostname\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
Here the HOSTNAME argument is a string representing the hostname of the server,
|
||||
e.g. "www.example.com".
|
||||
Here the C<hostname> argument is a string representing the hostname of the
|
||||
server, e.g. "www.example.com".
|
||||
|
||||
Secondly, we need to tell OpenSSL what hostname we expect to see in the
|
||||
certificate coming back from the server. This is almost always the same one that
|
||||
|
@ -293,7 +293,7 @@ itself. We do this via the L<SSL_set1_host(3)> function:
|
|||
* Virtually all clients should do this unless you really know what you
|
||||
* are doing.
|
||||
*/
|
||||
if (!SSL_set1_host(ssl, HOSTNAME)) {
|
||||
if (!SSL_set1_host(ssl, hostname)) {
|
||||
printf("Failed to set the certificate verification hostname");
|
||||
goto end;
|
||||
}
|
||||
|
@ -345,15 +345,26 @@ connection.
|
|||
|
||||
To send data to the server we use the L<SSL_write_ex(3)> function and to receive
|
||||
data from the server we use the L<SSL_read_ex(3)> function. In HTTP 1.0 the
|
||||
client always writes data first.
|
||||
client always writes data first. Our HTTP request will include the hostname that
|
||||
we are connecting to. For simplicitly, we write the HTTP request in three
|
||||
chunks. First we write the start of the request. Secondly we write the hostname
|
||||
we are sending the request to. Finally we send the end of the request.
|
||||
|
||||
size_t written;
|
||||
const char *request =
|
||||
"GET / HTTP/1.0\r\nConnection: close\r\nHost: "HOSTNAME"\r\n\r\n";
|
||||
const char *request_start = "GET / HTTP/1.0\r\nConnection: close\r\nHost: ";
|
||||
const char *request_end = "\r\n\r\n";
|
||||
|
||||
/* Write an HTTP GET request to the peer */
|
||||
if (!SSL_write_ex(ssl, request, strlen(request), &written)) {
|
||||
printf("Failed to write HTTP request\n");
|
||||
if (!SSL_write_ex(ssl, request_start, strlen(request_start), &written)) {
|
||||
printf("Failed to write start of HTTP request\n");
|
||||
goto end;
|
||||
}
|
||||
if (!SSL_write_ex(ssl, hostname, strlen(hostname), &written)) {
|
||||
printf("Failed to write hostname in HTTP request\n");
|
||||
goto end;
|
||||
}
|
||||
if (!SSL_write_ex(ssl, request_end, strlen(request_end), &written)) {
|
||||
printf("Failed to write end of HTTP request\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
|
|
@ -252,13 +252,27 @@ retry. An optional mode does exist (B<SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER>)
|
|||
which will configure OpenSSL to allow the buffer being written to change from
|
||||
one retry to the next. However, in this case, you must still retry exactly the
|
||||
same data - even though the buffer that contains that data may change location.
|
||||
See L<SSL_CTX_set_mode(3)> for further details.
|
||||
See L<SSL_CTX_set_mode(3)> for further details. As in the TLS client
|
||||
blocking tutorial (L<ossl-guide-tls-client-block(7)>) we write the request
|
||||
in three chunks.
|
||||
|
||||
/* Write an HTTP GET request to the peer */
|
||||
while (!SSL_write_ex(ssl, request, strlen(request), &written)) {
|
||||
while (!SSL_write_ex(ssl, request_start, strlen(request_start), &written)) {
|
||||
if (handle_io_failure(ssl, 0) == 1)
|
||||
continue; /* Retry */
|
||||
printf("Failed to write HTTP request\n");
|
||||
printf("Failed to write start of HTTP request\n");
|
||||
goto end; /* Cannot retry: error */
|
||||
}
|
||||
while (!SSL_write_ex(ssl, hostname, strlen(hostname), &written)) {
|
||||
if (handle_io_failure(ssl, 0) == 1)
|
||||
continue; /* Retry */
|
||||
printf("Failed to write hostname in HTTP request\n");
|
||||
goto end; /* Cannot retry: error */
|
||||
}
|
||||
while (!SSL_write_ex(ssl, request_end, strlen(request_end), &written)) {
|
||||
if (handle_io_failure(ssl, 0) == 1)
|
||||
continue; /* Retry */
|
||||
printf("Failed to write end of HTTP request\n");
|
||||
goto end; /* Cannot retry: error */
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue