| --- serf/src/buckets/buckets.c 2016-02-29 15:09:54.864201070 -0500 |
| +++ src/third_party/serf/instaweb_buckets.c 2016-02-29 15:09:54.872201020 -0500 |
| @@ -609,29 +609,21 @@ |
| va_list argp; |
| |
| if (verbose_flag) { |
| - apr_sockaddr_t *sa; |
| log_time(); |
| |
| - if (skt) { |
| - /* Log local and remote ip address:port */ |
| - fprintf(stderr, "[l:"); |
| - if (apr_socket_addr_get(&sa, APR_LOCAL, skt) == APR_SUCCESS) { |
| - char buf[32]; |
| - apr_sockaddr_ip_getbuf(buf, 32, sa); |
| - fprintf(stderr, "%s:%d", buf, sa->port); |
| - } |
| - fprintf(stderr, " r:"); |
| - if (apr_socket_addr_get(&sa, APR_REMOTE, skt) == APR_SUCCESS) { |
| - char buf[32]; |
| - apr_sockaddr_ip_getbuf(buf, 32, sa); |
| - fprintf(stderr, "%s:%d", buf, sa->port); |
| - } |
| - fprintf(stderr, "] "); |
| - } |
| - |
| if (filename) |
| fprintf(stderr, "%s: ", filename); |
| |
| + // PageSpeed change: don't actually log the socket information here. |
| + // |
| + // To log the socket information Serf uses a function from APR 1.3, but |
| + // that's newer than we support on some of our platforms. Leaving this |
| + // out means our log messages won't be quite as thorough as they could |
| + // be, but no worse than in the previous version of serf. |
| + // |
| + // Once all our supported platforms have APR 1.3+ we can remove this |
| + // patch. |
| + |
| va_start(argp, fmt); |
| vfprintf(stderr, fmt, argp); |
| va_end(argp); |
| --- serf/src/buckets/bwtp_buckets.c 2016-02-29 15:09:54.864201070 -0500 |
| +++ src/third_party/serf/instaweb_bwtp_buckets.c 2016-02-29 15:09:54.872201020 -0500 |
| @@ -228,7 +228,8 @@ |
| req_len = apr_snprintf(ctx->req_line, sizeof(ctx->req_line), |
| "%s %d " "%" APR_UINT64_T_HEX_FMT " %s%s\r\n", |
| (ctx->type ? "BWM" : "BWH"), |
| - ctx->channel, calc_header_size(ctx->headers), |
| + ctx->channel, |
| + (unsigned long long)calc_header_size(ctx->headers), |
| (ctx->open ? "OPEN " : ""), |
| ctx->phrase); |
| new_bucket = serf_bucket_simple_copy_create(ctx->req_line, req_len, |
| --- serf/src/buckets/response_buckets.c 2016-02-29 15:09:54.864201070 -0500 |
| +++ src/third_party/serf/instaweb_response_buckets.c 2016-02-29 15:09:54.872201020 -0500 |
| @@ -273,41 +273,53 @@ |
| ctx->body = |
| serf_bucket_barrier_create(ctx->stream, bkt->allocator); |
| |
| + /* |
| + * PageSpeed change: This section is re-ordered from the original |
| + * code from serf to Follow HTTP spec by checking |
| + * "Transfer-Encoding: chunked", before "Content-Length". |
| + */ |
| + |
| /* Are we C-L, chunked, or conn close? */ |
| - v = serf_bucket_headers_get(ctx->headers, "Content-Length"); |
| + v = serf_bucket_headers_get(ctx->headers, "Transfer-Encoding"); |
| if (v) { |
| - apr_uint64_t length; |
| - length = apr_strtoi64(v, NULL, 10); |
| - if (errno == ERANGE) { |
| - return APR_FROM_OS_ERROR(ERANGE); |
| - } |
| - ctx->body = serf_bucket_response_body_create( |
| - ctx->body, length, bkt->allocator); |
| - } |
| - else { |
| - v = serf_bucket_headers_get(ctx->headers, "Transfer-Encoding"); |
| - |
| /* Need to handle multiple transfer-encoding. */ |
| - if (v && strcasecmp("chunked", v) == 0) { |
| + if (strcasecmp("chunked", v) == 0) { |
| ctx->chunked = 1; |
| ctx->body = serf_bucket_dechunk_create(ctx->body, |
| bkt->allocator); |
| } |
| } |
| - v = serf_bucket_headers_get(ctx->headers, "Content-Encoding"); |
| - if (v) { |
| - /* Need to handle multiple content-encoding. */ |
| - if (v && strcasecmp("gzip", v) == 0) { |
| - ctx->body = |
| - serf_bucket_deflate_create(ctx->body, bkt->allocator, |
| - SERF_DEFLATE_GZIP); |
| - } |
| - else if (v && strcasecmp("deflate", v) == 0) { |
| - ctx->body = |
| - serf_bucket_deflate_create(ctx->body, bkt->allocator, |
| - SERF_DEFLATE_DEFLATE); |
| - } |
| + else { |
| + v = serf_bucket_headers_get(ctx->headers, "Content-Length"); |
| + if (v) { |
| + apr_uint64_t length; |
| + length = apr_strtoi64(v, NULL, 10); |
| + if (errno == ERANGE) { |
| + return APR_FROM_OS_ERROR(ERANGE); |
| + } |
| + ctx->body = serf_bucket_response_body_create( |
| + ctx->body, length, bkt->allocator); |
| + } |
| } |
| + /* |
| + * PageSpeed would prefer to receive gzipped output if that's what |
| + * was asked for. |
| + * |
| + * v = serf_bucket_headers_get(ctx->headers, "Content-Encoding"); |
| + * if (v) { |
| + * * Need to handle multiple content-encoding. * |
| + * if (v && strcasecmp("gzip", v) == 0) { |
| + * ctx->body = |
| + * serf_bucket_deflate_create(ctx->body, bkt->allocator, |
| + * SERF_DEFLATE_GZIP); |
| + * } |
| + * else if (v && strcasecmp("deflate", v) == 0) { |
| + * ctx->body = |
| + * serf_bucket_deflate_create(ctx->body, bkt->allocator, |
| + * SERF_DEFLATE_DEFLATE); |
| + * } |
| + * } |
| + */ |
| } |
| break; |
| case STATE_BODY: |
| --- serf/src/outgoing.c 2016-02-29 15:09:54.864201070 -0500 |
| +++ src/third_party/serf/instaweb_outgoing.c 2016-02-29 15:09:54.872201020 -0500 |
| @@ -909,6 +909,7 @@ |
| apr_status_t status = APR_SUCCESS; |
| int consumed_response = 0; |
| |
| +#if 0 /* This disables authentication support for now */ |
| /* Only enable the new authentication framework if the program has |
| * registered an authentication credential callback. |
| * |
| @@ -932,6 +933,7 @@ |
| return status; |
| } |
| } |
| +#endif |
| |
| if (!consumed_response) { |
| return (*request->handler)(request, |
| @@ -1117,6 +1119,12 @@ |
| * acceptor to get one created. |
| */ |
| if (request->resp_bkt == NULL) { |
| + if (request->acceptor == NULL) { |
| + if ((status = setup_request(request)) != APR_SUCCESS) { |
| + goto error; |
| + } |
| + } |
| + |
| request->resp_bkt = (*request->acceptor)(request, conn->stream, |
| request->acceptor_baton, |
| tmppool); |
| @@ -1479,6 +1487,18 @@ |
| return APR_NOTFOUND; |
| } |
| |
| +/* |
| + * Instaweb/mod_pagespeed added API: Returns true if this connection |
| + * has had error events reported during the last call to |
| + * serf_context_run. It should be called after serf_context_run |
| + * invocation, and not within callbacks. |
| + * |
| + * Return value is conceptually bool, but Serf implementation language is C. |
| +*/ |
| +int serf_connection_is_in_error_state(serf_connection_t* conn) |
| +{ |
| + return ((conn->seen_in_pollset & (APR_POLLERR | APR_POLLHUP)) != 0); |
| +} |
| |
| void serf_connection_set_max_outstanding_requests( |
| serf_connection_t *conn, |
| @@ -1524,6 +1544,8 @@ |
| request->conn = conn; |
| request->setup = setup; |
| request->setup_baton = setup_baton; |
| + request->acceptor = NULL; |
| + request->acceptor_baton = NULL; |
| request->handler = NULL; |
| request->respool = NULL; |
| request->req_bkt = NULL; |
| @@ -1671,12 +1693,17 @@ |
| } |
| |
| |
| -serf_bucket_t *serf_request_bucket_request_create( |
| +/* |
| + * PageSpeed customization: Add serf_request_bucket_request_create_for_host |
| + * which lets Host: be set separately from the URL. |
| + */ |
| +serf_bucket_t *serf_request_bucket_request_create_for_host( |
| serf_request_t *request, |
| const char *method, |
| const char *uri, |
| serf_bucket_t *body, |
| - serf_bucket_alloc_t *allocator) |
| + serf_bucket_alloc_t *allocator, |
| + const char *host) |
| { |
| serf_bucket_t *req_bkt, *hdrs_bkt; |
| serf_connection_t *conn = request->conn; |
| @@ -1697,9 +1724,10 @@ |
| serf_bucket_request_set_root(req_bkt, conn->host_url); |
| } |
| |
| - if (conn->host_info.hostinfo) |
| - serf_bucket_headers_setn(hdrs_bkt, "Host", |
| - conn->host_info.hostinfo); |
| + if (host == NULL) |
| + host = request->conn->host_info.hostname; |
| + if (host) |
| + serf_bucket_headers_setn(hdrs_bkt, "Host", host); |
| |
| /* Setup server authorization headers, unless this is a CONNECT request. */ |
| if (!request->ssltunnel) { |
| @@ -1732,6 +1760,17 @@ |
| return req_bkt; |
| } |
| |
| +serf_bucket_t *serf_request_bucket_request_create( |
| + serf_request_t *request, |
| + const char *method, |
| + const char *uri, |
| + serf_bucket_t *body, |
| + serf_bucket_alloc_t *allocator) |
| +{ |
| + return serf_request_bucket_request_create_for_host( |
| + request, method, uri, body, allocator, NULL); |
| +} |
| + |
| apr_interval_time_t serf_connection_get_latency(serf_connection_t *conn) |
| { |
| if (conn->ctx->proxy_address) { |
| --- serf/src/buckets/ssl_buckets.c 2016-02-29 15:09:54.864201070 -0500 |
| +++ src/third_party/serf/instaweb_ssl_buckets.c 2016-02-29 15:11:19.831661212 -0500 |
| @@ -34,6 +34,12 @@ |
| * Originally developed by Aaron Bannert and Justin Erenkrantz, eBuilt. |
| */ |
| |
| +/* |
| + * This file contains two new functions by jmarantz@google.com to expose |
| + * functions for setting SSL certificate directory & file. It also has fixes |
| + * so we compile against boringssl. |
| + */ |
| + |
| #include <apr_pools.h> |
| #include <apr_network_io.h> |
| #include <apr_portable.h> |
| @@ -462,7 +468,8 @@ |
| switch (nm->type) { |
| case GEN_DNS: |
| if (copy_action == ErrorOnNul && |
| - strlen(nm->d.ia5->data) != nm->d.ia5->length) |
| + strlen((const char*)nm->d.ia5->data) != |
| + nm->d.ia5->length) |
| return SERF_ERROR_SSL_CERT_FAILED; |
| if (san_arr && *san_arr) |
| p = pstrdup_escape_nul_bytes((const char *)nm->d.ia5->data, |
| @@ -1192,8 +1199,13 @@ |
| else { |
| int err = ERR_get_error(); |
| ERR_clear_error(); |
| +#ifndef OPENSSL_IS_BORINGSSL |
| if (ERR_GET_LIB(err) == ERR_LIB_PKCS12 && |
| ERR_GET_REASON(err) == PKCS12_R_MAC_VERIFY_FAILURE) { |
| +#else |
| + if (ERR_GET_LIB(err) == ERR_LIB_PKCS8 && |
| + ERR_GET_REASON(err) == PKCS8_R_INCORRECT_PASSWORD) { |
| +#endif |
| if (ctx->cert_pw_callback) { |
| const char *password; |
| |
| @@ -1413,7 +1425,9 @@ |
| const char * hostname) |
| { |
| #ifdef SSL_set_tlsext_host_name |
| - if (SSL_set_tlsext_host_name(context->ssl, hostname) != 1) { |
| + if (!context->ssl) { |
| + return APR_EGENERAL; |
| + } else if (SSL_set_tlsext_host_name(context->ssl, hostname) != 1) { |
| ERR_clear_error(); |
| } |
| #endif |
| @@ -1429,6 +1443,28 @@ |
| return result ? APR_SUCCESS : SERF_ERROR_SSL_CERT_FAILED; |
| } |
| |
| +/* |
| + * PageSpeed addition to allow configuring SSL directory from a directive. |
| + */ |
| +apr_status_t serf_ssl_set_certificates_directory(serf_ssl_context_t *ssl_ctx, |
| + const char* path) |
| +{ |
| + X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx->ctx); |
| + int result = X509_STORE_load_locations(store, NULL, path); |
| + return result ? APR_SUCCESS : APR_EGENERAL; |
| +} |
| + |
| +/* |
| + * PageSpeed addition to allow configuring SSL directory from a directive. |
| + */ |
| +apr_status_t serf_ssl_set_certificates_file(serf_ssl_context_t *ssl_ctx, |
| + const char* file) |
| +{ |
| + X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx->ctx); |
| + int result = X509_STORE_load_locations(store, file, NULL); |
| + return result ? APR_SUCCESS : APR_EGENERAL; |
| +} |
| + |
| apr_status_t serf_ssl_load_cert_file( |
| serf_ssl_certificate_t **cert, |
| const char *file_path, |
| @@ -1652,6 +1688,21 @@ |
| return cert->depth; |
| } |
| |
| +/* |
| + * PageSpeed addition to allow verification of certificate hostnames. |
| + * |
| + * Hostname must be null-terminated. |
| + * For return values, see X509_check_host. |
| + */ |
| +int serf_ssl_check_host(const serf_ssl_certificate_t *cert, |
| + const char* hostname) |
| +{ |
| + return X509_check_host(cert->ssl_cert, |
| + hostname, |
| + strlen(hostname), |
| + 0 /* we don't need to set any flags */, |
| + NULL /* we don't need the SAN or CN extracted*/); |
| +} |
| |
| apr_hash_t *serf_ssl_cert_issuer( |
| const serf_ssl_certificate_t *cert, |
| @@ -1798,6 +1849,7 @@ |
| |
| if (!--ctx->ssl_ctx->refcount) { |
| ssl_free_context(ctx->ssl_ctx); |
| + ctx->ssl_ctx = NULL; |
| } |
| |
| serf_default_destroy_and_data(bucket); |