Author: rhuijben
Date: Tue Oct 13 21:29:20 2015
New Revision: 1708518
URL: http://svn.apache.org/viewvc?rev=1708518&view=rev
Log:
After hours of debugging fix the mock http server to properly allow serf to
drop the connection halfway during ssl communication when renegotiating.
This fixes the test_ssl_renegotiate() testfailure on trunk on Windows.
* serf-dev/dev/test/MockHTTPinC/MockHTTP_server.c
(processServer): Report closed connections to the caller in the intended
way, if they aren't reported by reading before.
(sslCtx_t): Use a single bio status as reads and writes can be mixed from
ssl.
(bio_apr_socket_read,
bio_apr_socket_read): Set error and retry info in both functions.
(initSSLCtx): Update initialization.
(sslSocketWrite): Clear bio_status. Return real error if we have one.
(sslSocketRead): Handle an ssl errror as EOF when handling a renegotiate.
(sslHandshake): Update variable name.
Modified:
serf/trunk/test/MockHTTPinC/MockHTTP_server.c
Modified: serf/trunk/test/MockHTTPinC/MockHTTP_server.c
URL:
http://svn.apache.org/viewvc/serf/trunk/test/MockHTTPinC/MockHTTP_server.c?rev=1708518&r1=1708517&r2=1708518&view=diff
==============================================================================
--- serf/trunk/test/MockHTTPinC/MockHTTP_server.c (original)
+++ serf/trunk/test/MockHTTPinC/MockHTTP_server.c Tue Oct 13 21:29:20 2015
@@ -1429,6 +1429,11 @@ static apr_status_t processServer(mhServ
}
}
+ if (desc->rtnevents & APR_POLLHUP) {
+ /* may overwrite the result of stream->type->peek */
+ status = APR_EOF;
+ }
+
return status;
}
@@ -2169,7 +2174,7 @@ mhSetServerEnableOCSP(mhServCtx_t *ctx)
struct sslCtx_t {
bool handshake_done;
bool renegotiate;
- apr_status_t bio_read_status;
+ apr_status_t bio_status;
SSL_CTX* ctx;
SSL* ssl;
@@ -2255,7 +2260,7 @@ static int bio_apr_socket_read(BIO *bio,
BIO_clear_retry_flags(bio);
status = apr_socket_recv(cctx->skt, in, &len);
- ssl_ctx->bio_read_status = status;
+ ssl_ctx->bio_status = status;
if (len || status != APR_EAGAIN)
_mhLog(MH_VERBOSE, cctx->skt, "Read %d bytes from ssl socket with "
@@ -2280,12 +2285,18 @@ static int bio_apr_socket_write(BIO *bio
{
apr_size_t len = inlen;
_mhClientCtx_t *cctx = bio->ptr;
+ sslCtx_t *ssl_ctx = cctx->ssl_ctx;
+
+ BIO_clear_retry_flags(bio);
apr_status_t status = apr_socket_send(cctx->skt, in, &len);
+ ssl_ctx->bio_status = status;
- if (len || status != APR_EAGAIN)
+ if (len || !APR_STATUS_IS_EAGAIN(status))
_mhLog(MH_VERBOSE, cctx->skt, "Wrote %d of %d bytes to ssl socket with
"
"status %d.\n", len, inlen, status);
+ else if (APR_STATUS_IS_EAGAIN(status))
+ BIO_set_retry_write(bio);
if (READ_ERROR(status))
return -1;
@@ -2462,7 +2473,7 @@ static apr_status_t initSSLCtx(_mhClient
{
sslCtx_t *ssl_ctx = apr_pcalloc(cctx->pool, sizeof(*ssl_ctx));
cctx->ssl_ctx = ssl_ctx;
- ssl_ctx->bio_read_status = APR_SUCCESS;
+ ssl_ctx->bio_status = APR_SUCCESS;
_mhLog(MH_VERBOSE, cctx->skt, "Initializing SSL context.\n");
@@ -2588,9 +2599,11 @@ static apr_status_t initSSLCtx(_mhClient
static apr_status_t
sslSocketWrite(_mhClientCtx_t *cctx, const char *data, apr_size_t *len)
{
+ int result;
sslCtx_t *ssl_ctx = cctx->ssl_ctx;
- int result = SSL_write(ssl_ctx->ssl, data, *len);
+ ssl_ctx->bio_status = APR_SUCCESS;
+ result = SSL_write(ssl_ctx->ssl, data, *len);
if (result > 0) {
*len = result;
return APR_SUCCESS;
@@ -2601,7 +2614,7 @@ sslSocketWrite(_mhClientCtx_t *cctx, con
_mhLog(MH_VERBOSE, cctx->skt, "ssl_socket_write: ssl error?\n");
- return APR_EGENERAL;
+ return ssl_ctx->bio_status ? ssl_ctx->bio_status : APR_EGENERAL;
}
/**
@@ -2613,6 +2626,7 @@ sslSocketRead(apr_socket_t *skt, void *b
{
sslCtx_t *ssl_ctx = baton;
+ ssl_ctx->bio_status = APR_SUCCESS;
int result = SSL_read(ssl_ctx->ssl, data, *len);
if (result > 0) {
*len = result;
@@ -2625,11 +2639,18 @@ sslSocketRead(apr_socket_t *skt, void *b
case SSL_ERROR_SYSCALL:
/* error in bio_bucket_read, probably APR_EAGAIN or APR_EOF */
*len = 0;
- return ssl_ctx->bio_read_status;
+ return ssl_ctx->bio_status;
case SSL_ERROR_WANT_READ:
*len = 0;
return APR_EAGAIN;
case SSL_ERROR_SSL:
+ if (ssl_ctx->renegotiate) {
+ /* The client kills the connection, so we can expect protocol
+ errors... Let's just return that we didn't see an error,
+ but that the connection was closed. */
+ *len = 0;
+ return APR_EOF;
+ }
default:
*len = 0;
_mhLog(MH_VERBOSE, skt,
@@ -2757,7 +2778,7 @@ static apr_status_t sslHandshake(_mhClie
case SSL_ERROR_WANT_WRITE:
return APR_EAGAIN;
case SSL_ERROR_SYSCALL:
- return ssl_ctx->bio_read_status; /* Usually APR_EAGAIN */
+ return ssl_ctx->bio_status; /* Usually APR_EAGAIN */
default:
_mhLog(MH_VERBOSE, cctx->skt, "SSL Error %d: ", ssl_err);
#if MH_VERBOSE