Author: brane Date: Fri Apr 6 14:21:56 2018 New Revision: 1828524 URL: http://svn.apache.org/viewvc?rev=1828524&view=rev Log: On the ocsp-verification branch: sync with trunk up to r1828523.
Added: serf/branches/ocsp-verification/buckets/brotli_buckets.c - copied unchanged from r1828523, serf/trunk/buckets/brotli_buckets.c Modified: serf/branches/ocsp-verification/ (props changed) serf/branches/ocsp-verification/SConstruct serf/branches/ocsp-verification/buckets/dechunk_buckets.c serf/branches/ocsp-verification/buckets/deflate_buckets.c serf/branches/ocsp-verification/buckets/response_buckets.c serf/branches/ocsp-verification/buckets/ssl_buckets.c serf/branches/ocsp-verification/dist.sh serf/branches/ocsp-verification/protocols/http2_protocol.c serf/branches/ocsp-verification/serf.h serf/branches/ocsp-verification/serf_bucket_types.h serf/branches/ocsp-verification/src/pump.c serf/branches/ocsp-verification/test/MockHTTPinC/MockHTTP_server.c serf/branches/ocsp-verification/test/serf_bwtp.c serf/branches/ocsp-verification/test/serf_get.c serf/branches/ocsp-verification/test/serf_spider.c serf/branches/ocsp-verification/test/test_buckets.c serf/branches/ocsp-verification/test/test_context.c serf/branches/ocsp-verification/test/test_serf.h serf/branches/ocsp-verification/test/test_util.c Propchange: serf/branches/ocsp-verification/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Fri Apr 6 14:21:56 2018 @@ -3,4 +3,4 @@ /serf/branches/get-remaining:1701859-1708111 /serf/branches/multiple_ssl_impls:1699382 /serf/branches/windows-sspi:1698866-1698877 -/serf/trunk:1771884-1778786 +/serf/trunk:1771884-1828523 Modified: serf/branches/ocsp-verification/SConstruct URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/SConstruct?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/SConstruct (original) +++ serf/branches/ocsp-verification/SConstruct Fri Apr 6 14:21:56 2018 @@ -8,9 +8,9 @@ # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -102,6 +102,10 @@ opts.AddVariables( "Path to GSSAPI's install area", None, None), + PathVariable('BROTLI', + "Path to Brotli's install area", + None, + PathVariable.PathIsDir), BoolVariable('DEBUG', "Enable debugging info and strict compile warnings", False), @@ -119,7 +123,7 @@ opts.AddVariables( RawListVariable('LINKFLAGS', "Extra flags for the linker (space-separated)", None), RawListVariable('CPPFLAGS', "Extra flags for the C preprocessor " - "(space separated)", None), + "(space separated)", None), ) if sys.platform == 'win32': @@ -143,14 +147,15 @@ if sys.platform == 'win32': EnumVariable('MSVC_VERSION', "Visual C++ to use for building", None, - allowed_values=('15.0', '14.0', '12.0', + allowed_values=('15.0', '14.1', '14.0', '12.0', '11.0', '10.0', '9.0', '8.0', '6.0'), map={'2005' : '8.0', '2008' : '9.0', '2010' : '10.0', '2012' : '11.0', '2013' : '12.0', - '2015' : '14.0' + '2015' : '14.0', + '2017' : '14.1', }), # We always documented that we handle an install layout, but in fact we @@ -169,15 +174,15 @@ env = Environment(variables=opts, gen_def_script = env.File('build/gen_def.py').rstr() env.Append(BUILDERS = { - 'GenDef' : - Builder(action = sys.executable + ' %s $SOURCES > $TARGET' % (gen_def_script,), + 'GenDef' : + Builder(action = '"%s" "%s" $SOURCES > $TARGET' % (sys.executable, gen_def_script,), suffix='.def', src_suffix='.h') }) match = re.search('SERF_MAJOR_VERSION ([0-9]+).*' 'SERF_MINOR_VERSION ([0-9]+).*' 'SERF_PATCH_VERSION ([0-9]+)', - env.File('serf.h').get_contents(), + env.File('serf.h').get_contents().decode('utf-8'), re.DOTALL) MAJOR, MINOR, PATCH = [int(x) for x in match.groups()] env.Append(MAJOR=str(MAJOR)) @@ -194,12 +199,13 @@ CALLOUT_OKAY = not (env.GetOption('clean unknown = opts.UnknownVariables() if unknown: - print 'Warning: Used unknown variables:', ', '.join(unknown.keys()) + print('Warning: Used unknown variables:', ', '.join(unknown.keys())) apr = str(env['APR']) apu = str(env['APU']) zlib = str(env['ZLIB']) gssapi = env.get('GSSAPI', None) +brotli = env.get('BROTLI', None) if gssapi and os.path.isdir(gssapi): krb5_config = os.path.join(gssapi, 'bin', 'krb5-config') @@ -278,6 +284,10 @@ if sys.platform != 'win32': if sys.platform == 'sunos5': env.Append(LIBS=['m']) env.Append(PLATFORM='posix') + + if brotli: + env.Append(LIBS=['brotlicommon', 'brotlidec']) + else: # Warning level 4, no unused argument warnings env.Append(CCFLAGS=['/W4', @@ -356,13 +366,34 @@ if sys.platform == 'win32': LIBPATH=['$ZLIB']) # openssl - env.Append(LIBS=['libeay32.lib', 'ssleay32.lib']) if not env.get('SOURCE_LAYOUT', None): env.Append(CPPPATH=['$OPENSSL/include/openssl'], LIBPATH=['$OPENSSL/lib']) else: env.Append(CPPPATH=['$OPENSSL/inc32'], LIBPATH=['$OPENSSL/out32dll']) + conf = Configure(env) + if conf.CheckLib('libcrypto'): + # OpenSSL 1.1.0+ + env.Append(LIBS=['libcrypto.lib', 'libssl.lib']) + else: + # Legacy OpenSSL + env.Append(LIBS=['libeay32.lib', 'ssleay32.lib']) + conf.Finish() + + # brotli + if brotli: + brotli_libs = 'brotlicommon.lib brotlidec.lib' + env.Append(LIBS=['brotlicommon.lib', 'brotlidec.lib']) + if not env.get('SOURCE_LAYOUT', None): + env.Append(CPPPATH=['$BROTLI/include'], + LIBPATH=['$BROTLI/lib']) + else: + env.Append(CPPPATH=['$BROTLI/include'], + LIBPATH=['$BROTLI/Release']) + else: + brotli_libs = '' + else: if CALLOUT_OKAY: if os.path.isdir(apr): @@ -415,6 +446,13 @@ else: env.Append(CPPPATH=['$OPENSSL/include']) env.Append(LIBPATH=['$OPENSSL/lib']) + if brotli: + brotli_libs = '-lbrotlicommon -lbrotlienc' + env.Append(CPPPATH=['$BROTLI/include'], + LIBPATH=['$BROTLI/lib']) + else: + brotli_libs = '' + # Check for OpenSSL functions which are only available in some of # the versions we support. Also handles forks like LibreSSL. conf = Configure(env) @@ -424,10 +462,12 @@ if not conf.CheckFunc('X509_STORE_get0_p env.Append(CPPDEFINES=['SERF_NO_SSL_X509_STORE_WRAPPERS']) if conf.CheckFunc('CRYPTO_set_locking_callback'): env.Append(CPPDEFINES=['SERF_HAVE_SSL_LOCKING_CALLBACKS']) -if conf.CheckFunc('OPENSSL_malloc_init'): +if conf.CheckFunc('OPENSSL_malloc_init', '#include <openssl/crypto.h>'): env.Append(CPPDEFINES=['SERF_HAVE_OPENSSL_MALLOC_INIT']) if conf.CheckFunc('SSL_set_alpn_protos'): env.Append(CPPDEFINES=['SERF_HAVE_OPENSSL_ALPN']) +if conf.CheckType('OSSL_HANDSHAKE_STATE', '#include <openssl/ssl.h>'): + env.Append(CPPDEFINES=['SERF_HAVE_OSSL_HANDSHAKE_STATE']) env = conf.Finish() # If build with gssapi, get its information and define SERF_HAVE_GSSAPI @@ -441,6 +481,16 @@ if gssapi and CALLOUT_OKAY: if sys.platform == 'win32': env.Append(CPPDEFINES=['SERF_HAVE_SSPI']) +if brotli and CALLOUT_OKAY: + conf = Configure(env) + if conf.CheckCHeader('brotli/decode.h') and \ + conf.CheckFunc('BrotliDecoderTakeOutput'): + env.Append(CPPDEFINES=['SERF_HAVE_BROTLI']) + else: + print("Cannot find Brotli library >= 1.0.0 in '%s'." % env.get('BROTLI')) + Exit(1) + env = conf.Finish() + # Set preprocessor define to disable the logging framework if disablelogging: env.Append(CPPDEFINES=['SERF_DISABLE_LOGGING']) @@ -456,12 +506,13 @@ pkgconfig = env.Textfile('serf-%d.pc' % env.File('build/serf.pc.in'), SUBST_DICT = { '@MAJOR@': str(MAJOR), - '@PREFIX@': '$PREFIX', - '@LIBDIR@': '$LIBDIR', + '@PREFIX@': re.escape(str(env['PREFIX'])), + '@LIBDIR@': re.escape(str(env['LIBDIR'])), '@INCLUDE_SUBDIR@': 'serf-%d' % (MAJOR,), '@VERSION@': '%d.%d.%d' % (MAJOR, MINOR, PATCH), - '@LIBS@': '%s %s %s -lz' % (apu_libs, apr_libs, - env.get('GSSAPI_LIBS', '')), + '@LIBS@': '%s %s %s %s -lz' % (apu_libs, apr_libs, + env.get('GSSAPI_LIBS', ''), + brotli_libs), }) env.Default(lib_static, lib_shared, pkgconfig) Modified: serf/branches/ocsp-verification/buckets/dechunk_buckets.c URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/buckets/dechunk_buckets.c?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/buckets/dechunk_buckets.c (original) +++ serf/branches/ocsp-verification/buckets/dechunk_buckets.c Fri Apr 6 14:21:56 2018 @@ -82,12 +82,17 @@ static apr_status_t wait_for_chunk(serf_ /* if a line was read, then parse it. */ if (ctx->linebuf.state == SERF_LINEBUF_READY) { + char *end; /* Convert from HEX digits. The linebuffer ensures a '\0' */ - ctx->body_left = apr_strtoi64(ctx->linebuf.line, NULL, 16); + ctx->body_left = apr_strtoi64(ctx->linebuf.line, &end, 16); if (errno == ERANGE) { return APR_FROM_OS_ERROR(ERANGE); } + else if (ctx->linebuf.line == end) { + /* Invalid chunk length, bail out. */ + return SERF_ERROR_BAD_HTTP_RESPONSE; + } if (ctx->body_left == 0) { /* Just read the last-chunk marker. We're DONE. */ Modified: serf/branches/ocsp-verification/buckets/deflate_buckets.c URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/buckets/deflate_buckets.c?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/buckets/deflate_buckets.c (original) +++ serf/branches/ocsp-verification/buckets/deflate_buckets.c Fri Apr 6 14:21:56 2018 @@ -277,14 +277,24 @@ static apr_status_t serf_deflate_refill( while (1) { - if (ctx->memLevel < 0) + if (ctx->memLevel < 0) { zRC = inflate(&ctx->zstream, flush_v); - else + if (zRC == Z_BUF_ERROR && APR_STATUS_IS_EOF(ctx->stream_status) && + ctx->zstream.avail_out > 0) { + /* Zlib can't continue, although there's still space in the + output buffer. This can happen either if the stream is + truncated or corrupted. As we don't know for sure, + return a generic error. */ + return SERF_ERROR_DECOMPRESSION_FAILED; + } + } + else { zRC = deflate(&ctx->zstream, flush_v); + } - /* We're full or zlib requires more space. Either case, clear - out our buffer, reset, and return. */ if (zRC == Z_BUF_ERROR || ctx->zstream.avail_out == 0) { + /* We're full or zlib requires more space. Either case, clear + out our buffer, reset, and return. */ apr_size_t private_len; serf_bucket_t *tmp; Modified: serf/branches/ocsp-verification/buckets/response_buckets.c URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/buckets/response_buckets.c?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/buckets/response_buckets.c (original) +++ serf/branches/ocsp-verification/buckets/response_buckets.c Fri Apr 6 14:21:56 2018 @@ -459,6 +459,14 @@ static apr_status_t run_machine(serf_buc SERF_DEFLATE_DEFLATE); serf_bucket_set_config(ctx->body, ctx->config); } + else if (serf_bucket_is_brotli_supported() + && v && strcasecmp("br", v) == 0) + { + ctx->body = + serf_bucket_brotli_decompress_create(ctx->body, + bkt->allocator); + serf_bucket_set_config(ctx->body, ctx->config); + } } } break; Modified: serf/branches/ocsp-verification/buckets/ssl_buckets.c URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/buckets/ssl_buckets.c?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/buckets/ssl_buckets.c (original) +++ serf/branches/ocsp-verification/buckets/ssl_buckets.c Fri Apr 6 14:21:56 2018 @@ -299,12 +299,13 @@ detect_renegotiate(const SSL *s, int whe #endif /* The server asked to renegotiate the SSL session. */ -#ifdef TLS_ST_SW_HELLO_REQ +#ifdef SERF_HAVE_OSSL_HANDSHAKE_STATE if (SSL_get_state(s) == TLS_ST_SW_HELLO_REQ) { #elif defined(SSL_ST_RENEGOTIATE) if (SSL_state(s) == SSL_ST_RENEGOTIATE) { #else #error "neither TLS_ST_SW_HELLO_REQ nor SSL_ST_RENEGOTIATE is available" + { #endif serf_ssl_context_t *ssl_ctx = SSL_get_app_data(s); @@ -1154,7 +1155,7 @@ static apr_status_t ssl_decrypt(void *ba /* Once we got through the initial handshake, we should have received the ALPN information if there is such information. */ ctx->handshake_finished = SSL_is_init_finished(ctx->ssl) -#ifdef TLS_ST_OK +#ifdef SERF_HAVE_OSSL_HANDSHAKE_STATE || (SSL_get_state(ctx->ssl) == TLS_ST_OK); #elif defined(SSL_CB_HANDSHAKE_DONE) || (SSL_state(ctx->ssl) Modified: serf/branches/ocsp-verification/dist.sh URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/dist.sh?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/dist.sh (original) +++ serf/branches/ocsp-verification/dist.sh Fri Apr 6 14:21:56 2018 @@ -87,9 +87,10 @@ mv "${release}" "${release}.win" cd ${work} -# allow md5sum and sha1sum tool names to be overridden +# allow checksum tool names to be overridden [ -n "$MD5SUM" ] || MD5SUM=md5sum [ -n "$SHA1SUM" ] || SHA1SUM=sha1sum +[ -n "$SHA256SUM" ] || SHA256SUM=sha1sum echo "" echo "Done:" @@ -130,3 +131,6 @@ echo "" echo "sha1sums:" $SHA1SUM "${release}.tar.bz2" "${release}.zip" echo "" +echo "sha256sums:" +$SHA256SUM "${release}.tar.bz2" "${release}.zip" +echo "" Modified: serf/branches/ocsp-verification/protocols/http2_protocol.c URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/protocols/http2_protocol.c?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/protocols/http2_protocol.c (original) +++ serf/branches/ocsp-verification/protocols/http2_protocol.c Fri Apr 6 14:21:56 2018 @@ -824,7 +824,14 @@ http2_handle_settings(void *baton, /* Sanitize? */ serf__log(LOGLVL_INFO, SERF_LOGHTTP2, h2->config, "Setting Initial Window Size %u\n", value); - h2->lr_window += (value - h2->lr_default_window); + /* This only affects the default window size for new streams + (the connection window size is left unchanged): + + Both endpoints can adjust the initial window size for new + streams by including a value for SETTINGS_INITIAL_WINDOW_SIZE + in the SETTINGS frame that forms part of the connection + preface. The connection flow-control window can only be + changed using WINDOW_UPDATE frames. */ h2->lr_default_window = value; break; case HTTP2_SETTING_MAX_FRAME_SIZE: Modified: serf/branches/ocsp-verification/serf.h URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/serf.h?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/serf.h (original) +++ serf/branches/ocsp-verification/serf.h Fri Apr 6 14:21:56 2018 @@ -1702,7 +1702,9 @@ struct serf_connection_type_t { /** @} */ -/* Internal functions for bucket use and lifecycle tracking */ +/* Internal functions for bucket use and lifecycle tracking. + ### Some of these are directly or via Macros used by third party + ### applications, such as Apache Subversion */ apr_status_t serf_debug__record_read( const serf_bucket_t *bucket, apr_status_t status); Modified: serf/branches/ocsp-verification/serf_bucket_types.h URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/serf_bucket_types.h?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/serf_bucket_types.h (original) +++ serf/branches/ocsp-verification/serf_bucket_types.h Fri Apr 6 14:21:56 2018 @@ -1029,6 +1029,28 @@ void serf_bucket_split_create(serf_bucke apr_size_t max_chunk_size); +/** + * Check if Serf bucket functions support Brotli (RFC 7932) format. + * Return non-zero if Brotli is supported and zero otherwise. If Brotli + * is not supported, the behavior of all related bucket functions such + * as @a serf_bucket_brotli_decompress_create is undefined. + * + * @since New in 1.4. + */ +int serf_bucket_is_brotli_supported(void); + +/** @since New in 1.4. */ +extern const serf_bucket_type_t serf_bucket_type_brotli_decompress; +/** @since New in 1.4. */ +#define SERF_BUCKET_IS_BROTLI_DECOMPRESS(b) \ + SERF_BUCKET_CHECK((b), brotli_decompress) + +/** @since New in 1.4. */ +serf_bucket_t * +serf_bucket_brotli_decompress_create(serf_bucket_t *stream, + serf_bucket_alloc_t *alloc); + + /* ### do we need a PIPE bucket type? they are simple apr_file_t objects */ Modified: serf/branches/ocsp-verification/src/pump.c URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/src/pump.c?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/src/pump.c (original) +++ serf/branches/ocsp-verification/src/pump.c Fri Apr 6 14:21:56 2018 @@ -35,7 +35,7 @@ static apr_status_t pump_cleanup(void *b if (pump->ostream_head != NULL) { #ifdef SERF_DEBUG_BUCKET_USE - serf__bucket_drain(conn->ostream_head); + serf__bucket_drain(pump->ostream_head); #endif serf_bucket_destroy(pump->ostream_head); pump->ostream_head = NULL; Modified: serf/branches/ocsp-verification/test/MockHTTPinC/MockHTTP_server.c URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/test/MockHTTPinC/MockHTTP_server.c?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/test/MockHTTPinC/MockHTTP_server.c (original) +++ serf/branches/ocsp-verification/test/MockHTTPinC/MockHTTP_server.c Fri Apr 6 14:21:56 2018 @@ -2239,10 +2239,6 @@ mhSetServerEnableOCSP(mhServCtx_t *ctx) #include <openssl/ssl.h> #include <openssl/err.h> -#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L -#define USE_LEGACY_OPENSSL -#endif - struct sslCtx_t { bool handshake_done; bool renegotiate; @@ -2278,7 +2274,7 @@ static int pem_passwd_cb(char *buf, int */ static int bio_apr_socket_create(BIO *bio) { -#ifndef USE_LEGACY_OPENSSL +#ifndef SERF_NO_SSL_BIO_WRAPPERS BIO_set_shutdown(bio, 1); BIO_set_init(bio, 1); BIO_set_data(bio, NULL); @@ -2294,7 +2290,7 @@ static int bio_apr_socket_create(BIO *bi static void bio_set_data(BIO *bio, void *data) { -#ifndef USE_LEGACY_OPENSSL +#ifndef SERF_NO_SSL_BIO_WRAPPERS BIO_set_data(bio, data); #else bio->ptr = data; @@ -2303,7 +2299,7 @@ static void bio_set_data(BIO *bio, void static void *bio_get_data(BIO *bio) { -#ifndef USE_LEGACY_OPENSSL +#ifndef SERF_NO_SSL_BIO_WRAPPERS return BIO_get_data(bio); #else return bio->ptr; @@ -2404,7 +2400,7 @@ static int bio_apr_socket_write(BIO *bio } -#ifdef USE_LEGACY_OPENSSL +#ifdef SERF_NO_SSL_BIO_WRAPPERS static BIO_METHOD bio_apr_socket_method = { BIO_TYPE_SOCKET, "APR sockets", @@ -2425,7 +2421,7 @@ static BIO_METHOD *bio_meth_apr_socket_n { BIO_METHOD *biom = NULL; -#ifndef USE_LEGACY_OPENSSL +#ifndef SERF_NO_SSL_BIO_WRAPPERS biom = BIO_meth_new(BIO_TYPE_SOCKET, "APR sockets"); if (biom) { BIO_meth_set_write(biom, bio_apr_socket_write); @@ -2443,7 +2439,7 @@ static BIO_METHOD *bio_meth_apr_socket_n static void bio_meth_free(BIO_METHOD *biom) { -#ifndef USE_LEGACY_OPENSSL +#ifndef SERF_NO_SSL_BIO_WRAPPERS BIO_meth_free(biom); #endif } @@ -2672,7 +2668,7 @@ static apr_status_t initSSLCtx(_mhClient /* Init OpenSSL globally */ if (!init_done) { -#ifndef USE_LEGACY_OPENSSL +#ifdef SERF_HAVE_OPENSSL_MALLOC_INIT OPENSSL_malloc_init(); #else CRYPTO_malloc_init(); @@ -2755,8 +2751,8 @@ static apr_status_t initSSLCtx(_mhClient X509 *ssl_cert = PEM_read_X509(fp, NULL, NULL, NULL); fclose(fp); - SSL_CTX_add_extra_chain_cert(ssl_ctx->ctx, ssl_cert); X509_STORE_add_cert(store, ssl_cert); + SSL_CTX_add_extra_chain_cert(ssl_ctx->ctx, ssl_cert); } } Modified: serf/branches/ocsp-verification/test/serf_bwtp.c URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/test/serf_bwtp.c?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/test/serf_bwtp.c (original) +++ serf/branches/ocsp-verification/test/serf_bwtp.c Fri Apr 6 14:21:56 2018 @@ -191,7 +191,10 @@ static apr_status_t setup_request(serf_r serf_bucket_headers_setn(hdrs_bkt, "User-Agent", "Serf/" SERF_VERSION_STRING); /* Shouldn't serf do this for us? */ - serf_bucket_headers_setn(hdrs_bkt, "Accept-Encoding", "gzip"); + if (serf_bucket_is_brotli_supported()) + serf_bucket_headers_setn(hdrs_bkt, "Accept-Encoding", "gzip, br"); + else + serf_bucket_headers_setn(hdrs_bkt, "Accept-Encoding", "gzip"); if (ctx->authn != NULL) { serf_bucket_headers_setn(hdrs_bkt, "Authorization", ctx->authn); @@ -255,7 +258,10 @@ static apr_status_t setup_channel(serf_r serf_bucket_headers_setn(hdrs_bkt, "User-Agent", "Serf/" SERF_VERSION_STRING); /* Shouldn't serf do this for us? */ - serf_bucket_headers_setn(hdrs_bkt, "Accept-Encoding", "gzip"); + if (serf_bucket_is_brotli_supported()) + serf_bucket_headers_setn(hdrs_bkt, "Accept-Encoding", "gzip, br"); + else + serf_bucket_headers_setn(hdrs_bkt, "Accept-Encoding", "gzip"); if (ctx->authn != NULL) { serf_bucket_headers_setn(hdrs_bkt, "Authorization", ctx->authn); Modified: serf/branches/ocsp-verification/test/serf_get.c URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/test/serf_get.c?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/test/serf_get.c (original) +++ serf/branches/ocsp-verification/test/serf_get.c Fri Apr 6 14:21:56 2018 @@ -34,7 +34,7 @@ /* #define CONNECTION_CLOSE_HDR */ typedef struct app_baton_t { - const char *hostinfo; + const char *hostname; int using_ssl; int head_request; int negotiate_http2; @@ -223,7 +223,7 @@ static apr_status_t conn_setup(apr_socke serf_ssl_server_cert_chain_callback_set(conn_ctx->ssl_ctx, ignore_all_cert_errors, print_certs, NULL); - serf_ssl_set_hostname(conn_ctx->ssl_ctx, ctx->hostinfo); + serf_ssl_set_hostname(conn_ctx->ssl_ctx, ctx->hostname); *output_bkt = serf_bucket_ssl_encrypt_create(*output_bkt, conn_ctx->ssl_ctx, @@ -372,7 +372,10 @@ static apr_status_t setup_request(serf_r serf_bucket_headers_setn(hdrs_bkt, "User-Agent", "Serf/" SERF_VERSION_STRING); /* Shouldn't serf do this for us? */ - serf_bucket_headers_setn(hdrs_bkt, "Accept-Encoding", "gzip"); + if (serf_bucket_is_brotli_supported()) + serf_bucket_headers_setn(hdrs_bkt, "Accept-Encoding", "gzip, br"); + else + serf_bucket_headers_setn(hdrs_bkt, "Accept-Encoding", "gzip"); #ifdef CONNECTION_CLOSE_HDR serf_bucket_headers_setn(hdrs_bkt, "Connection", "close"); #endif @@ -725,7 +728,7 @@ int main(int argc, const char **argv) app_ctx.head_request = 0; } - app_ctx.hostinfo = url.hostinfo; + app_ctx.hostname = url.hostname; app_ctx.pem_path = pem_path; app_ctx.pem_pwd = pem_pwd; Modified: serf/branches/ocsp-verification/test/serf_spider.c URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/test/serf_spider.c?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/test/serf_spider.c (original) +++ serf/branches/ocsp-verification/test/serf_spider.c Fri Apr 6 14:21:56 2018 @@ -323,7 +323,10 @@ static apr_status_t setup_request(serf_r "Serf/" SERF_VERSION_STRING); /* Shouldn't serf do this for us? */ - serf_bucket_headers_setn(hdrs_bkt, "Accept-Encoding", "gzip"); + if (serf_bucket_is_brotli_supported()) + serf_bucket_headers_setn(hdrs_bkt, "Accept-Encoding", "gzip, br"); + else + serf_bucket_headers_setn(hdrs_bkt, "Accept-Encoding", "gzip"); if (ctx->app_ctx->authn != NULL) { serf_bucket_headers_setn(hdrs_bkt, "Authorization", Modified: serf/branches/ocsp-verification/test/test_buckets.c URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/test/test_buckets.c?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/test/test_buckets.c (original) +++ serf/branches/ocsp-verification/test/test_buckets.c Fri Apr 6 14:21:56 2018 @@ -1122,6 +1122,104 @@ static void test_response_body_chunked_g serf_bucket_destroy(bkt); } +/* Test for issue: the server aborts the connection and also sends + a bogus CRLF in place of the expected chunk size. Test that we get + a decent error code from the response bucket instead of APR_EOF. */ +static void test_response_body_chunked_bogus_crlf(CuTest *tc) +{ + test_baton_t *tb = tc->testBaton; + serf_bucket_t *bkt, *tmp; + serf_bucket_alloc_t *alloc = test__create_bucket_allocator(tc, tb->pool); + + tmp = SERF_BUCKET_SIMPLE_STRING("HTTP/1.1 200 OK" CRLF + "Content-Type: text/plain" CRLF + "Transfer-Encoding: chunked" CRLF + CRLF + "2" CRLF + "AB" CRLF + CRLF, + alloc); + + bkt = serf_bucket_response_create(tmp, alloc); + + { + char buf[1024]; + apr_size_t len; + apr_status_t status; + + status = read_all(bkt, buf, sizeof(buf), &len); + + CuAssertIntEquals(tc, SERF_ERROR_BAD_HTTP_RESPONSE, status); + } + + /* This will also destroy response stream bucket. */ + serf_bucket_destroy(bkt); +} + +static void test_response_body_chunked_invalid_len(CuTest *tc) +{ + test_baton_t *tb = tc->testBaton; + serf_bucket_t *bkt, *tmp; + serf_bucket_alloc_t *alloc = test__create_bucket_allocator(tc, tb->pool); + + tmp = SERF_BUCKET_SIMPLE_STRING("HTTP/1.1 200 OK" CRLF + "Content-Type: text/plain" CRLF + "Transfer-Encoding: chunked" CRLF + CRLF + "2" CRLF + "AB" CRLF + "invalid" CRLF + CRLF, + alloc); + + bkt = serf_bucket_response_create(tmp, alloc); + + { + char buf[1024]; + apr_size_t len; + apr_status_t status; + + status = read_all(bkt, buf, sizeof(buf), &len); + + CuAssertIntEquals(tc, SERF_ERROR_BAD_HTTP_RESPONSE, status); + } + + /* This will also destroy response stream bucket. */ + serf_bucket_destroy(bkt); +} + +static void test_response_body_chunked_overflow_len(CuTest *tc) +{ + test_baton_t *tb = tc->testBaton; + serf_bucket_t *bkt, *tmp; + serf_bucket_alloc_t *alloc = test__create_bucket_allocator(tc, tb->pool); + + tmp = SERF_BUCKET_SIMPLE_STRING("HTTP/1.1 200 OK" CRLF + "Content-Type: text/plain" CRLF + "Transfer-Encoding: chunked" CRLF + CRLF + "2" CRLF + "AB" CRLF + "12345678901234567890123456789" CRLF + CRLF, + alloc); + + bkt = serf_bucket_response_create(tmp, alloc); + + { + char buf[1024]; + apr_size_t len; + apr_status_t status; + + status = read_all(bkt, buf, sizeof(buf), &len); + + CuAssertIntEquals(tc, APR_FROM_OS_ERROR(ERANGE), status); + } + + /* This will also destroy response stream bucket. */ + serf_bucket_destroy(bkt); +} + static void test_response_bucket_peek_at_headers(CuTest *tc) { test_baton_t *tb = tc->testBaton; @@ -1298,7 +1396,7 @@ static void test_linebuf_crlf_split(CuTe CRLF, APR_SUCCESS }, { 1, "6" CR, APR_SUCCESS }, { 1, "", APR_EAGAIN }, - { 1, LF "blabla" CRLF CRLF, APR_SUCCESS }, }; + { 1, LF "blabla" CRLF "0" CRLF CRLF, APR_SUCCESS }, }; apr_status_t status; const char *expected = "blabla"; @@ -2968,6 +3066,234 @@ static void test_http2_frame_bucket_basi serf_bucket_destroy(frame_out); } +static void test_brotli_decompress_bucket_basic(CuTest *tc) +{ + test_baton_t *tb = tc->testBaton; + serf_bucket_t *input; + serf_bucket_t *bkt; + serf_bucket_alloc_t *alloc = test__create_bucket_allocator(tc, tb->pool); + + { + const char input_data[] = { + "\x3B" + }; + + input = serf_bucket_simple_create(input_data, sizeof(input_data) - 1, + NULL, NULL, alloc); + bkt = serf_bucket_brotli_decompress_create(input, alloc); + read_and_check_bucket(tc, bkt, ""); + serf_bucket_destroy(bkt); + } + + { + const char input_data[] = { + "\x8B\x03\x80\x61\x62\x63\x64\x65\x66\x67\x68\x03" + }; + + input = serf_bucket_simple_create(input_data, sizeof(input_data) - 1, + NULL, NULL, alloc); + bkt = serf_bucket_brotli_decompress_create(input, alloc); + read_and_check_bucket(tc, bkt, "abcdefgh"); + serf_bucket_destroy(bkt); + } + + { + const char input_data[] = { + "\x1B\x0E\x00\x00\x84\x71\xC0\xC6\xDA\x50\x22\x80\x88\x26" + "\x81\x14\x35\x1F" + }; + + input = serf_bucket_simple_create(input_data, sizeof(input_data) - 1, + NULL, NULL, alloc); + bkt = serf_bucket_brotli_decompress_create(input, alloc); + read_and_check_bucket(tc, bkt, "aaabbbcccdddeee"); + serf_bucket_destroy(bkt); + } +} + +static void test_brotli_decompress_bucket_truncated_input(CuTest *tc) +{ + test_baton_t *tb = tc->testBaton; + serf_bucket_t *input; + serf_bucket_t *bkt; + serf_bucket_alloc_t *alloc = test__create_bucket_allocator(tc, tb->pool); + const char input_data[] = { + "\x8B\x03\x80\x61\x62\x63\x64\x65\x66\x67\x68\x03" + }; + + /* Truncate our otherwise valid input. */ + input = serf_bucket_simple_create(input_data, 5, NULL, NULL, alloc); + bkt = serf_bucket_brotli_decompress_create(input, alloc); + + { + char buf[1024]; + apr_size_t len; + apr_status_t status; + + status = read_all(bkt, buf, sizeof(buf), &len); + CuAssertIntEquals(tc, SERF_ERROR_DECOMPRESSION_FAILED, status); + } + + serf_bucket_destroy(bkt); +} + +static void test_brotli_decompress_bucket_read_bytewise(CuTest *tc) +{ + test_baton_t *tb = tc->testBaton; + serf_bucket_t *input; + serf_bucket_t *bkt; + serf_bucket_alloc_t *alloc = test__create_bucket_allocator(tc, tb->pool); + apr_status_t status; + apr_size_t total_read = 0; + /* Brotli-encoded sequence of 100,000 zeroes. */ + const char input_data[] = { + "\x5B\x9F\x86\x01\x40\x02\x26\x1E\x0B\x24\xCB\x2F\x00" + }; + + input = serf_bucket_simple_create(input_data, sizeof(input_data) - 1, + NULL, NULL, alloc); + bkt = serf_bucket_brotli_decompress_create(input, alloc); + + do { + const char *data; + apr_size_t len; + + status = serf_bucket_read(bkt, 1, &data, &len); + if (SERF_BUCKET_READ_ERROR(status)) + CuFail(tc, "Got error during bucket reading."); + + if (len > 1) { + CuFail(tc, "Unexpected read with len > 1."); + } + else if (len == 1) { + CuAssertIntEquals(tc, '0', data[0]); + total_read += len; + } + } while (status != APR_EOF); + + CuAssertIntEquals(tc, 100000, (int)total_read); + + serf_bucket_destroy(bkt); +} + +static void test_brotli_decompress_bucket_chunked_input(CuTest *tc) +{ + test_baton_t *tb = tc->testBaton; + serf_bucket_t *input; + serf_bucket_t *bkt; + serf_bucket_alloc_t *alloc = test__create_bucket_allocator(tc, tb->pool); + + /* What if the encoded data spans over multiple chunks? + * (And let's throw in a couple of empty chunks as well...) */ + input = serf_bucket_aggregate_create(alloc); + serf_bucket_aggregate_append(input, + SERF_BUCKET_SIMPLE_STRING("\x8B\x03", alloc)); + serf_bucket_aggregate_append(input, + SERF_BUCKET_SIMPLE_STRING("\x80\x61\x62", alloc)); + serf_bucket_aggregate_append(input, + SERF_BUCKET_SIMPLE_STRING("", alloc)); + serf_bucket_aggregate_append(input, + SERF_BUCKET_SIMPLE_STRING("\x63\x64\x65\x66\x67\x68\x03", alloc)); + serf_bucket_aggregate_append(input, + SERF_BUCKET_SIMPLE_STRING("", alloc)); + + bkt = serf_bucket_brotli_decompress_create(input, alloc); + read_and_check_bucket(tc, bkt, "abcdefgh"); + serf_bucket_destroy(bkt); +} + +static void test_brotli_decompress_bucket_chunked_input2(CuTest *tc) +{ + test_baton_t *tb = tc->testBaton; + serf_bucket_t *input; + serf_bucket_t *bkt; + serf_bucket_alloc_t *alloc = test__create_bucket_allocator(tc, tb->pool); + + /* Try an edge case where the valid encoded data (empty string) is + * followed by an empty chunk. */ + input = serf_bucket_aggregate_create(alloc); + serf_bucket_aggregate_append(input, + SERF_BUCKET_SIMPLE_STRING("\x3B", alloc)); + serf_bucket_aggregate_append(input, + SERF_BUCKET_SIMPLE_STRING("", alloc)); + + bkt = serf_bucket_brotli_decompress_create(input, alloc); + read_and_check_bucket(tc, bkt, ""); + serf_bucket_destroy(bkt); +} + +static void test_brotli_decompress_bucket_garbage_at_end(CuTest *tc) +{ + test_baton_t *tb = tc->testBaton; + serf_bucket_t *input; + serf_bucket_t *bkt; + serf_bucket_alloc_t *alloc = test__create_bucket_allocator(tc, tb->pool); + const char input_data[] = { + "\x8B\x03\x80\x61\x62\x63\x64\x65\x66\x67\x68\x03garbage" + }; + + input = serf_bucket_simple_create(input_data, sizeof(input_data) - 1, + NULL, NULL, alloc); + bkt = serf_bucket_brotli_decompress_create(input, alloc); + + { + char buf[1024]; + apr_size_t len; + apr_status_t status; + + status = read_all(bkt, buf, sizeof(buf), &len); + CuAssertIntEquals(tc, SERF_ERROR_DECOMPRESSION_FAILED, status); + } +} + +static void test_brotli_decompress_response_body(CuTest *tc) +{ + test_baton_t *tb = tc->testBaton; + serf_bucket_t *input; + serf_bucket_t *bkt; + serf_bucket_alloc_t *alloc = test__create_bucket_allocator(tc, tb->pool); + + input = SERF_BUCKET_SIMPLE_STRING( + "HTTP/1.1 200 OK" CRLF + "Content-Type: text/html" CRLF + "Content-Length: 12" CRLF + "Content-Encoding: br" CRLF + CRLF + "\x8B\x03\x80\x61\x62\x63\x64\x65\x66\x67\x68\x03", + alloc); + + bkt = serf_bucket_response_create(input, alloc); + read_and_check_bucket(tc, bkt, "abcdefgh"); + serf_bucket_destroy(bkt); +} + +static void test_deflate_bucket_truncated_data(CuTest *tc) +{ + test_baton_t *tb = tc->testBaton; + serf_bucket_t *input; + serf_bucket_t *bkt; + serf_bucket_alloc_t *alloc = test__create_bucket_allocator(tc, tb->pool); + + /* This is a valid, but truncated gzip data (in two chunks). */ + input = serf_bucket_aggregate_create(alloc); + serf_bucket_aggregate_append(input, + SERF_BUCKET_SIMPLE_STRING_LEN("\x1F\x8B\x08\x00\x00", 5, alloc)); + serf_bucket_aggregate_append(input, + SERF_BUCKET_SIMPLE_STRING_LEN("\x00\x00\x00\x00\x03", 5, alloc)); + + bkt = serf_bucket_deflate_create(input, alloc, SERF_DEFLATE_GZIP); + { + char buf[1024]; + apr_size_t len; + apr_status_t status; + + status = read_all(bkt, buf, sizeof(buf), &len); + CuAssertIntEquals(tc, SERF_ERROR_DECOMPRESSION_FAILED, status); + } + + serf_bucket_destroy(bkt); +} + CuSuite *test_buckets(void) { CuSuite *suite = CuSuiteNew(); @@ -2983,6 +3309,9 @@ CuSuite *test_buckets(void) SUITE_ADD_TEST(suite, test_response_body_chunked_no_crlf); SUITE_ADD_TEST(suite, test_response_body_chunked_incomplete_crlf); SUITE_ADD_TEST(suite, test_response_body_chunked_gzip_small); + SUITE_ADD_TEST(suite, test_response_body_chunked_bogus_crlf); + SUITE_ADD_TEST(suite, test_response_body_chunked_invalid_len); + SUITE_ADD_TEST(suite, test_response_body_chunked_overflow_len); SUITE_ADD_TEST(suite, test_response_bucket_peek_at_headers); SUITE_ADD_TEST(suite, test_response_bucket_iis_status_code); SUITE_ADD_TEST(suite, test_response_bucket_no_reason); @@ -3010,11 +3339,21 @@ CuSuite *test_buckets(void) SUITE_ADD_TEST(suite, test_hpack_huffman_encode); SUITE_ADD_TEST(suite, test_hpack_header_encode); SUITE_ADD_TEST(suite, test_http2_frame_bucket_basic); + if (serf_bucket_is_brotli_supported()) { + SUITE_ADD_TEST(suite, test_brotli_decompress_bucket_basic); + SUITE_ADD_TEST(suite, test_brotli_decompress_bucket_truncated_input); + SUITE_ADD_TEST(suite, test_brotli_decompress_bucket_read_bytewise); + SUITE_ADD_TEST(suite, test_brotli_decompress_bucket_chunked_input); + SUITE_ADD_TEST(suite, test_brotli_decompress_bucket_chunked_input2); + SUITE_ADD_TEST(suite, test_brotli_decompress_bucket_garbage_at_end); + SUITE_ADD_TEST(suite, test_brotli_decompress_response_body); + } #if 0 /* This test for issue #152 takes a lot of time generating 4GB+ of random data so it's disabled by default. */ SUITE_ADD_TEST(suite, test_deflate_4GBplus_buckets); #endif + SUITE_ADD_TEST(suite, test_deflate_bucket_truncated_data); Modified: serf/branches/ocsp-verification/test/test_context.c URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/test/test_context.c?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/test/test_context.c (original) +++ serf/branches/ocsp-verification/test/test_context.c Fri Apr 6 14:21:56 2018 @@ -456,8 +456,8 @@ static void test_keepalive_limit_one_by_ EndGiven for (i = 0 ; i < SENT_REQUESTS ; i++) { - create_new_request_with_resp_hdlr(tb, &handler_ctx[i], "GET", "/", i+1, - handle_response_keepalive_limit); + create_new_request_ex(tb, &handler_ctx[i], "GET", "/", i+1, + NULL, handle_response_keepalive_limit); } /* The two retries of request 1 both also have req_id=1, which means that @@ -561,8 +561,8 @@ static void test_keepalive_limit_one_by_ EndGiven for (i = 0 ; i < SENT_REQUESTS ; i++) { - create_new_request_with_resp_hdlr(tb, &handler_ctx[i], "GET", "/", i+1, - handle_response_keepalive_limit_burst); + create_new_request_ex(tb, &handler_ctx[i], "GET", "/", i+1, + NULL, handle_response_keepalive_limit_burst); } /* The two retries of request 1 both also have req_id=1, which means that @@ -973,6 +973,50 @@ static void test_max_keepalive_requests( CuAssertIntEquals(tc, num_requests, tb->handled_requests->nelts); } +/* Implements test_request_setup_t */ +static apr_status_t setup_request_err(serf_request_t *request, + void *setup_baton, + serf_bucket_t **req_bkt, + apr_pool_t *pool) +{ + static mockbkt_action actions[] = { + { 1, "a", APR_SUCCESS }, + /* Return an error after first successful read. */ + { 1, "", APR_EINVAL } + }; + handler_baton_t *ctx = setup_baton; + serf_bucket_alloc_t *alloc; + serf_bucket_t *mock_bkt; + + alloc = serf_request_get_alloc(request); + mock_bkt = serf_bucket_mock_create(actions, 2, alloc); + *req_bkt = serf_request_bucket_request_create(request, + ctx->method, ctx->path, + mock_bkt, alloc); + return APR_SUCCESS; +} + +static void test_outgoing_request_err(CuTest *tc) +{ + test_baton_t *tb = tc->testBaton; + handler_baton_t handler_ctx[1]; + apr_status_t status; + + setup_test_mock_server(tb); + status = setup_test_client_context(tb, NULL, tb->pool); + CuAssertIntEquals(tc, APR_SUCCESS, status); + + /* Setup an outgoing request with the body bucket returning an error. */ + create_new_request_ex(tb, &handler_ctx[0], "POST", "/", 1, + setup_request_err, NULL); + + status = run_client_and_mock_servers_loops(tb, 1, handler_ctx, tb->pool); + CuAssertIntEquals(tc, APR_EINVAL, status); + CuAssertIntEquals(tc, 1, tb->sent_requests->nelts); + CuAssertIntEquals(tc, 0, tb->accepted_requests->nelts); + CuAssertIntEquals(tc, 0, tb->handled_requests->nelts); +} + /*****************************************************************************/ CuSuite *test_context(void) { @@ -998,6 +1042,7 @@ CuSuite *test_context(void) SUITE_ADD_TEST(suite, test_connection_large_response); SUITE_ADD_TEST(suite, test_connection_large_request); SUITE_ADD_TEST(suite, test_max_keepalive_requests); + SUITE_ADD_TEST(suite, test_outgoing_request_err); return suite; } Modified: serf/branches/ocsp-verification/test/test_serf.h URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/test/test_serf.h?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/test/test_serf.h (original) +++ serf/branches/ocsp-verification/test/test_serf.h Fri Apr 6 14:21:56 2018 @@ -123,6 +123,13 @@ apr_status_t use_new_connection(test_bat void *test_setup(void *baton); void *test_teardown(void *baton); +/* Simple variant of serf_request_setup_t for tests. */ +typedef apr_status_t (*test_request_setup_t)( + serf_request_t *request, + void *setup_baton, + serf_bucket_t **req_bkt, + apr_pool_t *pool); + typedef struct handler_baton_t { serf_response_acceptor_t acceptor; void *acceptor_baton; @@ -138,6 +145,8 @@ typedef struct handler_baton_t { const char *path; /* Use this for a raw request message */ const char *request; + /* Or this, if more control is needed. */ + test_request_setup_t request_setup; int done; test_baton_t *tb; @@ -171,6 +180,7 @@ apr_status_t handle_response(serf_reques void setup_handler(test_baton_t *tb, handler_baton_t *handler_ctx, const char *method, const char *path, int req_id, + test_request_setup_t req_setup, serf_response_handler_t handler); void create_new_prio_request(test_baton_t *tb, handler_baton_t *handler_ctx, @@ -181,11 +191,12 @@ void create_new_request(test_baton_t *tb const char *method, const char *path, int req_id); void -create_new_request_with_resp_hdlr(test_baton_t *tb, - handler_baton_t *handler_ctx, - const char *method, const char *path, - int req_id, - serf_response_handler_t handler); +create_new_request_ex(test_baton_t *tb, + handler_baton_t *handler_ctx, + const char *method, const char *path, + int req_id, + test_request_setup_t req_setup, + serf_response_handler_t handler); const char *create_large_response_message(apr_pool_t *pool); const char *create_large_request_message_body(apr_pool_t *pool); Modified: serf/branches/ocsp-verification/test/test_util.c URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/test/test_util.c?rev=1828524&r1=1828523&r2=1828524&view=diff ============================================================================== --- serf/branches/ocsp-verification/test/test_util.c (original) +++ serf/branches/ocsp-verification/test/test_util.c Fri Apr 6 14:21:56 2018 @@ -191,8 +191,13 @@ apr_status_t setup_request(serf_request_ { handler_baton_t *ctx = setup_baton; serf_bucket_t *body_bkt; + apr_status_t status = APR_SUCCESS; - if (ctx->request) + if (ctx->request_setup) + { + status = ctx->request_setup(request, setup_baton, req_bkt, pool); + } + else if (ctx->request) { /* Create a raw request bucket. */ *req_bkt = serf_bucket_simple_create(ctx->request, strlen(ctx->request), @@ -226,7 +231,7 @@ apr_status_t setup_request(serf_request_ *handler = ctx->handler; *handler_baton = ctx; - return APR_SUCCESS; + return status; } apr_status_t handle_response(serf_request_t *request, @@ -270,6 +275,7 @@ apr_status_t handle_response(serf_reques void setup_handler(test_baton_t *tb, handler_baton_t *handler_ctx, const char *method, const char *path, int req_id, + test_request_setup_t req_setup, serf_response_handler_t handler) { handler_ctx->method = method; @@ -285,6 +291,7 @@ void setup_handler(test_baton_t *tb, han handler_ctx->handled_requests = tb->handled_requests; handler_ctx->tb = tb; handler_ctx->request = NULL; + handler_ctx->request_setup = req_setup; } void create_new_prio_request(test_baton_t *tb, @@ -292,7 +299,7 @@ void create_new_prio_request(test_baton_ const char *method, const char *path, int req_id) { - setup_handler(tb, handler_ctx, method, path, req_id, NULL); + setup_handler(tb, handler_ctx, method, path, req_id, NULL, NULL); serf_connection_priority_request_create(tb->connection, setup_request, handler_ctx); @@ -303,20 +310,21 @@ void create_new_request(test_baton_t *tb const char *method, const char *path, int req_id) { - setup_handler(tb, handler_ctx, method, path, req_id, NULL); + setup_handler(tb, handler_ctx, method, path, req_id, NULL, NULL); serf_connection_request_create(tb->connection, setup_request, handler_ctx); } void -create_new_request_with_resp_hdlr(test_baton_t *tb, - handler_baton_t *handler_ctx, - const char *method, const char *path, - int req_id, - serf_response_handler_t handler) +create_new_request_ex(test_baton_t *tb, + handler_baton_t *handler_ctx, + const char *method, const char *path, + int req_id, + test_request_setup_t req_setup, + serf_response_handler_t handler) { - setup_handler(tb, handler_ctx, method, path, req_id, handler); + setup_handler(tb, handler_ctx, method, path, req_id, req_setup, handler); serf_connection_request_create(tb->connection, setup_request, handler_ctx);