summaryrefslogtreecommitdiff
path: root/chromium/net
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-05-15 10:20:33 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-05-15 10:28:57 +0000
commitd17ea114e5ef69ad5d5d7413280a13e6428098aa (patch)
tree2c01a75df69f30d27b1432467cfe7c1467a498da /chromium/net
parent8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec (diff)
downloadqtwebengine-chromium-d17ea114e5ef69ad5d5d7413280a13e6428098aa.tar.gz
BASELINE: Update Chromium to 67.0.3396.47
Change-Id: Idcb1341782e417561a2473eeecc82642dafda5b7 Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/net')
-rw-r--r--chromium/net/BUILD.gn117
-rw-r--r--chromium/net/OWNERS1
-rw-r--r--chromium/net/android/keystore.cc2
-rw-r--r--chromium/net/android/network_library.h7
-rw-r--r--chromium/net/base/address_tracker_linux.cc2
-rw-r--r--chromium/net/base/address_tracker_linux.h9
-rw-r--r--chromium/net/base/backoff_entry.cc2
-rw-r--r--chromium/net/base/backoff_entry.h4
-rw-r--r--chromium/net/base/backoff_entry_serializer.cc2
-rw-r--r--chromium/net/base/backoff_entry_serializer.h2
-rw-r--r--chromium/net/base/backoff_entry_serializer_unittest.cc2
-rw-r--r--chromium/net/base/backoff_entry_unittest.cc2
-rw-r--r--chromium/net/base/datagram_buffer.cc56
-rw-r--r--chromium/net/base/datagram_buffer.h102
-rw-r--r--chromium/net/base/datagram_buffer_unittest.cc54
-rw-r--r--chromium/net/base/escape.cc340
-rw-r--r--chromium/net/base/escape.h18
-rw-r--r--chromium/net/base/escape_unittest.cc373
-rw-r--r--chromium/net/base/file_stream_context.cc32
-rw-r--r--chromium/net/base/file_stream_context.h34
-rw-r--r--chromium/net/base/file_stream_context_posix.cc7
-rw-r--r--chromium/net/base/file_stream_context_win.cc17
-rw-r--r--chromium/net/base/filename_util_unittest.cc884
-rw-r--r--chromium/net/base/ip_address.cc68
-rw-r--r--chromium/net/base/ip_address.h15
-rw-r--r--chromium/net/base/ip_address_unittest.cc29
-rw-r--r--chromium/net/base/load_flags_list.h37
-rw-r--r--chromium/net/base/load_states_list.h39
-rw-r--r--chromium/net/base/load_timing_info.h13
-rw-r--r--chromium/net/base/mime_sniffer.cc4
-rw-r--r--chromium/net/base/mime_sniffer_unittest.cc109
-rw-r--r--chromium/net/base/mime_util.cc1
-rw-r--r--chromium/net/base/net_error_list.h6
-rw-r--r--chromium/net/base/net_errors.cc11
-rw-r--r--chromium/net/base/net_errors.h5
-rw-r--r--chromium/net/base/net_info_source_list.h4
-rw-r--r--chromium/net/base/network_config_watcher_mac.cc147
-rw-r--r--chromium/net/base/network_config_watcher_mac.h2
-rw-r--r--chromium/net/base/network_interfaces.h7
-rw-r--r--chromium/net/base/network_interfaces_fuchsia.cc33
-rw-r--r--chromium/net/base/network_throttle_manager.h97
-rw-r--r--chromium/net/base/network_throttle_manager_impl.cc2
-rw-r--r--chromium/net/base/network_throttle_manager_impl.h4
-rw-r--r--chromium/net/base/network_throttle_manager_impl_unittest.cc564
-rw-r--r--chromium/net/base/percentile_estimator.cc100
-rw-r--r--chromium/net/base/percentile_estimator.h59
-rw-r--r--chromium/net/base/percentile_estimator_unittest.cc242
-rw-r--r--chromium/net/base/proxy_server.cc56
-rw-r--r--chromium/net/base/proxy_server.h16
-rw-r--r--chromium/net/base/registry_controlled_domains/effective_tld_names.dat1078
-rw-r--r--chromium/net/base/registry_controlled_domains/effective_tld_names.gperf172
-rw-r--r--chromium/net/base/test_proxy_delegate.cc5
-rw-r--r--chromium/net/base/unescape_url_component_fuzzer.cc6
-rw-r--r--chromium/net/base/upload_data_stream.h2
-rw-r--r--chromium/net/base/url_util.cc42
-rw-r--r--chromium/net/base/url_util.h9
-rw-r--r--chromium/net/cert/cert_database_nss.cc2
-rw-r--r--chromium/net/cert/cert_status_flags_list.h5
-rw-r--r--chromium/net/cert/cert_verifier.h27
-rw-r--r--chromium/net/cert/cert_verifier_unittest.cc2
-rw-r--r--chromium/net/cert/cert_verify_proc.cc73
-rw-r--r--chromium/net/cert/cert_verify_proc_builtin.cc32
-rw-r--r--chromium/net/cert/cert_verify_proc_ios.cc8
-rw-r--r--chromium/net/cert/cert_verify_proc_ios_unittest.mm (renamed from chromium/net/cert/cert_verify_proc_ios_unittest.cc)15
-rw-r--r--chromium/net/cert/cert_verify_proc_mac.cc6
-rw-r--r--chromium/net/cert/cert_verify_proc_mac_unittest.cc1
-rw-r--r--chromium/net/cert/cert_verify_proc_nss.cc45
-rw-r--r--chromium/net/cert/cert_verify_proc_unittest.cc64
-rw-r--r--chromium/net/cert/cert_verify_proc_win.cc43
-rw-r--r--chromium/net/cert/cert_verify_result.cc3
-rw-r--r--chromium/net/cert/cert_verify_result.h2
-rw-r--r--chromium/net/cert/ct_known_logs.cc8
-rw-r--r--chromium/net/cert/ct_log_verifier.cc9
-rw-r--r--chromium/net/cert/ct_log_verifier.h6
-rw-r--r--chromium/net/cert/ct_log_verifier_unittest.cc6
-rw-r--r--chromium/net/cert/ct_objects_extractor_unittest.cc2
-rw-r--r--chromium/net/cert/ct_policy_enforcer_unittest.cc2
-rw-r--r--chromium/net/cert/internal/name_constraints.h3
-rw-r--r--chromium/net/cert/known_roots.cc27
-rw-r--r--chromium/net/cert/known_roots.h7
-rw-r--r--chromium/net/cert/multi_log_ct_verifier_unittest.cc5
-rw-r--r--chromium/net/cert/multi_threaded_cert_verifier.cc52
-rw-r--r--chromium/net/cert/multi_threaded_cert_verifier.h34
-rw-r--r--chromium/net/cert/nss_cert_database.cc1
-rw-r--r--chromium/net/cert/nss_cert_database_unittest.cc5
-rw-r--r--chromium/net/cert/root_cert_list_generated.h1493
-rw-r--r--chromium/net/cert/sth_distributor.cc69
-rw-r--r--chromium/net/cert/sth_distributor.h56
-rw-r--r--chromium/net/cert/sth_distributor_unittest.cc137
-rw-r--r--chromium/net/cert/sth_observer.h31
-rw-r--r--chromium/net/cert/sth_reporter.h31
-rw-r--r--chromium/net/cert/test_root_certs_win.cc5
-rw-r--r--chromium/net/cert/x509_certificate.cc14
-rw-r--r--chromium/net/cert/x509_certificate.h4
-rw-r--r--chromium/net/cert/x509_certificate_unittest.cc102
-rw-r--r--chromium/net/cert/x509_util.cc31
-rw-r--r--chromium/net/cert/x509_util.h11
-rw-r--r--chromium/net/cert/x509_util_unittest.cc2
-rw-r--r--chromium/net/cert/x509_util_win.cc2
-rw-r--r--chromium/net/cert_net/cert_net_fetcher_impl_unittest.cc4
-rw-r--r--chromium/net/cert_net/nss_ocsp.cc109
-rw-r--r--chromium/net/cert_net/nss_ocsp.h23
-rw-r--r--chromium/net/cert_net/nss_ocsp_unittest.cc10
-rw-r--r--chromium/net/cookies/OWNERS2
-rw-r--r--chromium/net/cookies/canonical_cookie.cc31
-rw-r--r--chromium/net/cookies/canonical_cookie_unittest.cc14
-rw-r--r--chromium/net/cookies/cookie_change_dispatcher.h5
-rw-r--r--chromium/net/cookies/cookie_change_dispatcher_test_helpers.cc33
-rw-r--r--chromium/net/cookies/cookie_change_dispatcher_test_helpers.h19
-rw-r--r--chromium/net/cookies/cookie_constants.h2
-rw-r--r--chromium/net/cookies/cookie_monster.cc135
-rw-r--r--chromium/net/cookies/cookie_monster.h20
-rw-r--r--chromium/net/cookies/cookie_monster_change_dispatcher.cc260
-rw-r--r--chromium/net/cookies/cookie_monster_change_dispatcher.h111
-rw-r--r--chromium/net/cookies/cookie_monster_store_test.h1
-rw-r--r--chromium/net/cookies/cookie_monster_unittest.cc164
-rw-r--r--chromium/net/cookies/cookie_store.cc4
-rw-r--r--chromium/net/cookies/cookie_store.h10
-rw-r--r--chromium/net/cookies/cookie_store_change_unittest.h2103
-rw-r--r--chromium/net/cookies/cookie_store_test_helpers.cc65
-rw-r--r--chromium/net/cookies/cookie_store_test_helpers.h44
-rw-r--r--chromium/net/cookies/cookie_store_unittest.h21
-rw-r--r--chromium/net/cookies/cookie_util.cc33
-rw-r--r--chromium/net/cookies/cookie_util.h5
-rw-r--r--chromium/net/cookies/cookie_util_unittest.cc13
-rw-r--r--chromium/net/cookies/parsed_cookie.cc6
-rw-r--r--chromium/net/cookies/parsed_cookie.h4
-rw-r--r--chromium/net/cookies/parsed_cookie_unittest.cc14
-rwxr-xr-xchromium/net/data/gencerts/__init__.py6
-rwxr-xr-xchromium/net/data/gencerts/openssl_conf.py5
-rw-r--r--chromium/net/data/ov_name_constraints/README.md7
-rwxr-xr-xchromium/net/data/ov_name_constraints/generate-certs.py201
-rw-r--r--chromium/net/data/ov_name_constraints/int-bmp-o1.pem88
-rw-r--r--chromium/net/data/ov_name_constraints/int-cn.pem88
-rw-r--r--chromium/net/data/ov_name_constraints/int-o1-o2.pem88
-rw-r--r--chromium/net/data/ov_name_constraints/int-o1-plus-o2.pem88
-rw-r--r--chromium/net/data/ov_name_constraints/int-o2-o1.pem88
-rw-r--r--chromium/net/data/ov_name_constraints/int-o3.pem88
-rw-r--r--chromium/net/data/ov_name_constraints/keys/i.key28
-rw-r--r--chromium/net/data/ov_name_constraints/keys/leaf.key28
-rw-r--r--chromium/net/data/ov_name_constraints/keys/root.key28
-rw-r--r--chromium/net/data/ov_name_constraints/leaf-no-o.pem88
-rw-r--r--chromium/net/data/ov_name_constraints/leaf-o1-o2.pem89
-rw-r--r--chromium/net/data/ov_name_constraints/leaf-o1.pem88
-rw-r--r--chromium/net/data/ov_name_constraints/nc-int-exclude-o1.pem92
-rw-r--r--chromium/net/data/ov_name_constraints/nc-int-permit-bmp-o1.pem88
-rw-r--r--chromium/net/data/ov_name_constraints/nc-int-permit-cn.pem92
-rw-r--r--chromium/net/data/ov_name_constraints/nc-int-permit-dns.pem92
-rw-r--r--chromium/net/data/ov_name_constraints/nc-int-permit-o1.pem92
-rw-r--r--chromium/net/data/ov_name_constraints/nc-int-permit-o2-o1-o3.pem95
-rw-r--r--chromium/net/data/ov_name_constraints/root.pem88
-rw-r--r--chromium/net/data/ssl/certificates/39_months_based_on_last_day.pem84
-rw-r--r--chromium/net/data/ssl/certificates/README4
-rw-r--r--chromium/net/data/ssl/certificates/comodo-chain.pem117
-rw-r--r--chromium/net/data/ssl/root_stores/root_stores.json2853
-rwxr-xr-xchromium/net/data/ssl/root_stores/update_root_stores.py15
-rwxr-xr-xchromium/net/data/ssl/scripts/generate-test-certs.sh13
-rw-r--r--chromium/net/data/ssl/scripts/quic-test.cnf (renamed from chromium/net/data/ssl/scripts/quic-test.cnf.txt)0
-rw-r--r--chromium/net/data/websocket/OWNERS1
-rw-r--r--chromium/net/disk_cache/blockfile/entry_impl.cc4
-rw-r--r--chromium/net/disk_cache/blockfile/entry_impl.h1
-rw-r--r--chromium/net/disk_cache/blockfile/file_win.cc13
-rw-r--r--chromium/net/disk_cache/blockfile/mapped_file.h2
-rw-r--r--chromium/net/disk_cache/disk_cache.h11
-rw-r--r--chromium/net/disk_cache/entry_unittest.cc9
-rw-r--r--chromium/net/disk_cache/memory/mem_entry_impl.cc4
-rw-r--r--chromium/net/disk_cache/memory/mem_entry_impl.h1
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_impl.cc7
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_impl.h1
-rw-r--r--chromium/net/disk_cache/simple/simple_index.cc7
-rw-r--r--chromium/net/disk_cache/simple/simple_index.h2
-rw-r--r--chromium/net/dns/OWNERS2
-rw-r--r--chromium/net/dns/address_sorter_posix.cc2
-rw-r--r--chromium/net/dns/address_sorter_posix_unittest.cc33
-rw-r--r--chromium/net/dns/dns_client.cc16
-rw-r--r--chromium/net/dns/dns_client.h8
-rw-r--r--chromium/net/dns/dns_session.cc7
-rw-r--r--chromium/net/dns/dns_session.h3
-rw-r--r--chromium/net/dns/dns_session_unittest.cc6
-rw-r--r--chromium/net/dns/dns_socket_pool.cc4
-rw-r--r--chromium/net/dns/dns_test_util.cc6
-rw-r--r--chromium/net/dns/dns_test_util.h2
-rw-r--r--chromium/net/dns/dns_transaction.cc7
-rw-r--r--chromium/net/dns/dns_transaction_unittest.cc61
-rw-r--r--chromium/net/dns/host_cache.cc2
-rw-r--r--chromium/net/dns/host_cache.h6
-rw-r--r--chromium/net/dns/host_cache_unittest.cc52
-rw-r--r--chromium/net/dns/host_resolver.cc4
-rw-r--r--chromium/net/dns/host_resolver.h10
-rw-r--r--chromium/net/dns/host_resolver_impl.cc48
-rw-r--r--chromium/net/dns/host_resolver_impl.h24
-rw-r--r--chromium/net/dns/host_resolver_impl_unittest.cc1
-rw-r--r--chromium/net/dns/mock_mdns_socket_factory.h4
-rw-r--r--chromium/net/dns/mojo_host_struct_traits.cc1
-rw-r--r--chromium/net/dns/notify_watcher_mac.cc6
-rw-r--r--chromium/net/dns/notify_watcher_mac.h8
-rw-r--r--chromium/net/docs/bug-triage-suggested-workflow.md22
-rw-r--r--chromium/net/docs/bug-triage.md52
-rw-r--r--chromium/net/docs/crash-course-in-net-internals.md16
-rw-r--r--chromium/net/docs/host-resolver.md102
-rw-r--r--chromium/net/extras/sqlite/sqlite_channel_id_store.cc8
-rw-r--r--chromium/net/extras/sqlite/sqlite_persistent_cookie_store.cc141
-rw-r--r--chromium/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc22
-rw-r--r--chromium/net/filter/OWNERS1
-rw-r--r--chromium/net/filter/source_stream_type_list.h5
-rw-r--r--chromium/net/http/bidirectional_stream.cc82
-rw-r--r--chromium/net/http/bidirectional_stream.h3
-rw-r--r--chromium/net/http/bidirectional_stream_impl.h4
-rw-r--r--chromium/net/http/bidirectional_stream_unittest.cc65
-rw-r--r--chromium/net/http/broken_alternative_services.cc11
-rw-r--r--chromium/net/http/broken_alternative_services.h6
-rw-r--r--chromium/net/http/broken_alternative_services_unittest.cc6
-rw-r--r--chromium/net/http/http_auth.h6
-rw-r--r--chromium/net/http/http_cache.h10
-rw-r--r--chromium/net/http/http_cache_transaction.cc11
-rw-r--r--chromium/net/http/http_cache_unittest.cc174
-rw-r--r--chromium/net/http/http_cache_writers.cc5
-rw-r--r--chromium/net/http/http_cache_writers_unittest.cc40
-rw-r--r--chromium/net/http/http_network_layer_unittest.cc2
-rw-r--r--chromium/net/http/http_network_session.cc20
-rw-r--r--chromium/net/http/http_network_session.h15
-rw-r--r--chromium/net/http/http_network_session_peer.cc8
-rw-r--r--chromium/net/http/http_network_session_peer.h4
-rw-r--r--chromium/net/http/http_network_transaction.cc103
-rw-r--r--chromium/net/http/http_network_transaction.h34
-rw-r--r--chromium/net/http/http_network_transaction_ssl_unittest.cc2
-rw-r--r--chromium/net/http/http_network_transaction_unittest.cc1334
-rw-r--r--chromium/net/http/http_proxy_client_socket.cc10
-rw-r--r--chromium/net/http/http_proxy_client_socket.h6
-rw-r--r--chromium/net/http/http_proxy_client_socket_fuzzer.cc3
-rw-r--r--chromium/net/http/http_proxy_client_socket_pool.cc7
-rw-r--r--chromium/net/http/http_proxy_client_socket_pool.h8
-rw-r--r--chromium/net/http/http_proxy_client_socket_pool_unittest.cc3
-rw-r--r--chromium/net/http/http_proxy_client_socket_unittest.cc4
-rw-r--r--chromium/net/http/http_proxy_client_socket_wrapper.cc12
-rw-r--r--chromium/net/http/http_proxy_client_socket_wrapper.h4
-rw-r--r--chromium/net/http/http_proxy_client_socket_wrapper_unittest.cc7
-rw-r--r--chromium/net/http/http_response_body_drainer_unittest.cc2
-rw-r--r--chromium/net/http/http_response_info.cc18
-rw-r--r--chromium/net/http/http_response_info_unittest.cc29
-rw-r--r--chromium/net/http/http_server_properties_impl.cc5
-rw-r--r--chromium/net/http/http_server_properties_impl.h7
-rw-r--r--chromium/net/http/http_server_properties_impl_unittest.cc4
-rw-r--r--chromium/net/http/http_server_properties_manager.cc2
-rw-r--r--chromium/net/http/http_server_properties_manager.h4
-rw-r--r--chromium/net/http/http_server_properties_manager_unittest.cc9
-rw-r--r--chromium/net/http/http_status_code_list.h6
-rw-r--r--chromium/net/http/http_stream_factory.h160
-rw-r--r--chromium/net/http/http_stream_factory_impl.cc4
-rw-r--r--chromium/net/http/http_stream_factory_impl.h6
-rw-r--r--chromium/net/http/http_stream_factory_impl_job.cc70
-rw-r--r--chromium/net/http/http_stream_factory_impl_job.h25
-rw-r--r--chromium/net/http/http_stream_factory_impl_job_controller.cc29
-rw-r--r--chromium/net/http/http_stream_factory_impl_job_controller.h22
-rw-r--r--chromium/net/http/http_stream_factory_impl_job_controller_unittest.cc98
-rw-r--r--chromium/net/http/http_stream_factory_impl_request.h149
-rw-r--r--chromium/net/http/http_stream_factory_impl_unittest.cc199
-rw-r--r--chromium/net/http/http_stream_factory_test_util.h1
-rw-r--r--chromium/net/http/http_stream_request.cc (renamed from chromium/net/http/http_stream_factory_impl_request.cc)46
-rw-r--r--chromium/net/http/http_stream_request.h290
-rw-r--r--chromium/net/http/http_stream_request_unittest.cc (renamed from chromium/net/http/http_stream_factory_impl_request_unittest.cc)16
-rw-r--r--chromium/net/http/http_util.cc169
-rw-r--r--chromium/net/http/http_util.h4
-rw-r--r--chromium/net/http/http_util_unittest.cc130
-rw-r--r--chromium/net/http/mock_http_cache.cc4
-rw-r--r--chromium/net/http/mock_http_cache.h1
-rw-r--r--chromium/net/http/partial_data.cc65
-rw-r--r--chromium/net/http/partial_data.h20
-rw-r--r--chromium/net/http/proxy_fallback.cc64
-rw-r--r--chromium/net/http/proxy_fallback.h58
-rw-r--r--chromium/net/http/transport_security_state.cc130
-rw-r--r--chromium/net/http/transport_security_state.h27
-rw-r--r--chromium/net/http/transport_security_state_static.json3189
-rw-r--r--chromium/net/http/transport_security_state_unittest.cc158
-rw-r--r--chromium/net/http2/decoder/payload_decoders/payload_decoder_base_test_util.h5
-rw-r--r--chromium/net/http2/hpack/decoder/hpack_decoder_string_buffer.cc5
-rw-r--r--chromium/net/http2/hpack/decoder/hpack_decoder_test.cc2
-rw-r--r--chromium/net/http2/http2_constants.h8
-rw-r--r--chromium/net/http2/http2_constants_test_util.cc57
-rw-r--r--chromium/net/http2/http2_constants_test_util.h7
-rw-r--r--chromium/net/log/file_net_log_observer.cc105
-rw-r--r--chromium/net/log/net_log_event_type_list.h142
-rw-r--r--chromium/net/log/net_log_source_type_list.h6
-rw-r--r--chromium/net/log/net_log_util.cc7
-rw-r--r--chromium/net/network_error_logging/network_error_logging_end_to_end_test.cc72
-rw-r--r--chromium/net/network_error_logging/network_error_logging_service.cc219
-rw-r--r--chromium/net/network_error_logging/network_error_logging_service.h24
-rw-r--r--chromium/net/network_error_logging/network_error_logging_service_unittest.cc79
-rw-r--r--chromium/net/nqe/effective_connection_type.h9
-rw-r--r--chromium/net/nqe/network_quality_estimator.cc5
-rw-r--r--chromium/net/nqe/network_quality_estimator.h4
-rw-r--r--chromium/net/nqe/network_quality_estimator_unittest.cc15
-rw-r--r--chromium/net/nqe/network_quality_estimator_util.cc2
-rw-r--r--chromium/net/nqe/network_quality_observation.cc2
-rw-r--r--chromium/net/nqe/network_quality_observation_source.h3
-rw-r--r--chromium/net/nqe/observation_buffer.cc2
-rw-r--r--chromium/net/nqe/observation_buffer.h6
-rw-r--r--chromium/net/nqe/socket_watcher.cc4
-rw-r--r--chromium/net/nqe/socket_watcher.h4
-rw-r--r--chromium/net/nqe/socket_watcher_factory.cc5
-rw-r--r--chromium/net/nqe/socket_watcher_factory.h6
-rw-r--r--chromium/net/nqe/throughput_analyzer.cc8
-rw-r--r--chromium/net/nqe/throughput_analyzer.h6
-rw-r--r--chromium/net/nqe/throughput_analyzer_unittest.cc14
-rw-r--r--chromium/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.cc92
-rw-r--r--chromium/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.h33
-rw-r--r--chromium/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win_unittest.cc97
-rw-r--r--chromium/net/proxy_resolution/dhcp_pac_file_fetcher.cc25
-rw-r--r--chromium/net/proxy_resolution/dhcp_pac_file_fetcher.h31
-rw-r--r--chromium/net/proxy_resolution/dhcp_pac_file_fetcher_factory.cc10
-rw-r--r--chromium/net/proxy_resolution/dhcp_pac_file_fetcher_factory.h14
-rw-r--r--chromium/net/proxy_resolution/dhcp_pac_file_fetcher_factory_unittest.cc12
-rw-r--r--chromium/net/proxy_resolution/dhcp_pac_file_fetcher_win.cc306
-rw-r--r--chromium/net/proxy_resolution/dhcp_pac_file_fetcher_win.h74
-rw-r--r--chromium/net/proxy_resolution/dhcp_pac_file_fetcher_win_unittest.cc149
-rw-r--r--chromium/net/proxy_resolution/mock_pac_file_fetcher.cc29
-rw-r--r--chromium/net/proxy_resolution/mock_pac_file_fetcher.h14
-rw-r--r--chromium/net/proxy_resolution/mock_proxy_resolver.cc4
-rw-r--r--chromium/net/proxy_resolution/mock_proxy_resolver.h10
-rw-r--r--chromium/net/proxy_resolution/multi_threaded_proxy_resolver.cc16
-rw-r--r--chromium/net/proxy_resolution/multi_threaded_proxy_resolver.h9
-rw-r--r--chromium/net/proxy_resolution/multi_threaded_proxy_resolver_unittest.cc116
-rw-r--r--chromium/net/proxy_resolution/pac_file_data.cc37
-rw-r--r--chromium/net/proxy_resolution/pac_file_data.h24
-rw-r--r--chromium/net/proxy_resolution/pac_file_decider.cc160
-rw-r--r--chromium/net/proxy_resolution/pac_file_decider.h46
-rw-r--r--chromium/net/proxy_resolution/pac_file_decider_unittest.cc400
-rw-r--r--chromium/net/proxy_resolution/pac_file_fetcher.h10
-rw-r--r--chromium/net/proxy_resolution/pac_file_fetcher_impl.cc88
-rw-r--r--chromium/net/proxy_resolution/pac_file_fetcher_impl.h24
-rw-r--r--chromium/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc166
-rw-r--r--chromium/net/proxy_resolution/pac_js_library.h460
-rw-r--r--chromium/net/proxy_resolution/polling_proxy_config_service.cc30
-rw-r--r--chromium/net/proxy_resolution/polling_proxy_config_service.h10
-rw-r--r--chromium/net/proxy_resolution/proxy_config.cc10
-rw-r--r--chromium/net/proxy_resolution/proxy_config.h14
-rw-r--r--chromium/net/proxy_resolution/proxy_config_service.h7
-rw-r--r--chromium/net/proxy_resolution/proxy_config_service_android.cc49
-rw-r--r--chromium/net/proxy_resolution/proxy_config_service_android.h5
-rw-r--r--chromium/net/proxy_resolution/proxy_config_service_android_unittest.cc19
-rw-r--r--chromium/net/proxy_resolution/proxy_config_service_fixed.cc9
-rw-r--r--chromium/net/proxy_resolution/proxy_config_service_fixed.h9
-rw-r--r--chromium/net/proxy_resolution/proxy_config_service_ios.cc25
-rw-r--r--chromium/net/proxy_resolution/proxy_config_service_ios.h3
-rw-r--r--chromium/net/proxy_resolution/proxy_config_service_linux.cc186
-rw-r--r--chromium/net/proxy_resolution/proxy_config_service_linux.h49
-rw-r--r--chromium/net/proxy_resolution/proxy_config_service_linux_unittest.cc135
-rw-r--r--chromium/net/proxy_resolution/proxy_config_service_mac.cc59
-rw-r--r--chromium/net/proxy_resolution/proxy_config_service_mac.h14
-rw-r--r--chromium/net/proxy_resolution/proxy_config_service_win.cc23
-rw-r--r--chromium/net/proxy_resolution/proxy_config_service_win.h7
-rw-r--r--chromium/net/proxy_resolution/proxy_config_service_win_unittest.cc1
-rw-r--r--chromium/net/proxy_resolution/proxy_config_source.cc33
-rw-r--r--chromium/net/proxy_resolution/proxy_config_source.h36
-rw-r--r--chromium/net/proxy_resolution/proxy_config_with_annotation.cc51
-rw-r--r--chromium/net/proxy_resolution/proxy_config_with_annotation.h42
-rw-r--r--chromium/net/proxy_resolution/proxy_info.cc15
-rw-r--r--chromium/net/proxy_resolution/proxy_info.h19
-rw-r--r--chromium/net/proxy_resolution/proxy_list.cc7
-rw-r--r--chromium/net/proxy_resolution/proxy_list.h2
-rw-r--r--chromium/net/proxy_resolution/proxy_resolution_service.cc (renamed from chromium/net/proxy_resolution/proxy_service.cc)361
-rw-r--r--chromium/net/proxy_resolution/proxy_resolution_service.h (renamed from chromium/net/proxy_resolution/proxy_service.h)80
-rw-r--r--chromium/net/proxy_resolution/proxy_resolution_service_unittest.cc (renamed from chromium/net/proxy_resolution/proxy_service_unittest.cc)351
-rw-r--r--chromium/net/proxy_resolution/proxy_resolver_factory.h11
-rw-r--r--chromium/net/proxy_resolution/proxy_resolver_mac.cc14
-rw-r--r--chromium/net/proxy_resolution/proxy_resolver_mac.h9
-rw-r--r--chromium/net/proxy_resolution/proxy_resolver_v8.cc20
-rw-r--r--chromium/net/proxy_resolution/proxy_resolver_v8.h4
-rw-r--r--chromium/net/proxy_resolution/proxy_resolver_v8_tracing.cc24
-rw-r--r--chromium/net/proxy_resolution/proxy_resolver_v8_tracing.h2
-rw-r--r--chromium/net/proxy_resolution/proxy_resolver_v8_tracing_unittest.cc4
-rw-r--r--chromium/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper.cc2
-rw-r--r--chromium/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper.h9
-rw-r--r--chromium/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper_unittest.cc4
-rw-r--r--chromium/net/proxy_resolution/proxy_resolver_v8_unittest.cc14
-rw-r--r--chromium/net/proxy_resolution/proxy_resolver_winhttp.cc12
-rw-r--r--chromium/net/proxy_resolution/proxy_resolver_winhttp.h9
-rw-r--r--chromium/net/quic/chromium/bidirectional_stream_quic_impl.cc9
-rw-r--r--chromium/net/quic/chromium/bidirectional_stream_quic_impl.h3
-rw-r--r--chromium/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc105
-rw-r--r--chromium/net/quic/chromium/crypto/proof_verifier_chromium_test.cc31
-rw-r--r--chromium/net/quic/chromium/quic_chromium_client_session.cc172
-rw-r--r--chromium/net/quic/chromium/quic_chromium_client_session.h40
-rw-r--r--chromium/net/quic/chromium/quic_chromium_client_session_test.cc77
-rw-r--r--chromium/net/quic/chromium/quic_chromium_client_stream.cc7
-rw-r--r--chromium/net/quic/chromium/quic_chromium_client_stream_test.cc10
-rw-r--r--chromium/net/quic/chromium/quic_chromium_packet_writer.cc53
-rw-r--r--chromium/net/quic/chromium/quic_connection_logger.cc4
-rw-r--r--chromium/net/quic/chromium/quic_connection_logger.h2
-rw-r--r--chromium/net/quic/chromium/quic_connectivity_probing_manager_test.cc4
-rw-r--r--chromium/net/quic/chromium/quic_end_to_end_unittest.cc2
-rw-r--r--chromium/net/quic/chromium/quic_http_stream.cc4
-rw-r--r--chromium/net/quic/chromium/quic_http_stream_test.cc213
-rw-r--r--chromium/net/quic/chromium/quic_http_utils.cc1
-rw-r--r--chromium/net/quic/chromium/quic_http_utils.h1
-rw-r--r--chromium/net/quic/chromium/quic_network_transaction_unittest.cc149
-rw-r--r--chromium/net/quic/chromium/quic_proxy_client_socket_unittest.cc11
-rw-r--r--chromium/net/quic/chromium/quic_stream_factory.cc4
-rw-r--r--chromium/net/quic/chromium/quic_stream_factory.h20
-rw-r--r--chromium/net/quic/chromium/quic_stream_factory_test.cc16
-rw-r--r--chromium/net/quic/chromium/quic_test_packet_maker.cc90
-rw-r--r--chromium/net/quic/chromium/quic_test_packet_maker.h25
-rw-r--r--chromium/net/quic/core/congestion_control/bandwidth_sampler.h4
-rw-r--r--chromium/net/quic/core/congestion_control/bbr_sender.cc13
-rw-r--r--chromium/net/quic/core/congestion_control/bbr_sender.h2
-rw-r--r--chromium/net/quic/core/congestion_control/bbr_sender_test.cc6
-rw-r--r--chromium/net/quic/core/congestion_control/rtt_stats.cc8
-rw-r--r--chromium/net/quic/core/congestion_control/rtt_stats_test.cc28
-rw-r--r--chromium/net/quic/core/congestion_control/send_algorithm_interface.h4
-rw-r--r--chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.cc54
-rw-r--r--chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.h3
-rw-r--r--chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc7
-rw-r--r--chromium/net/quic/core/crypto/cert_compressor.cc6
-rw-r--r--chromium/net/quic/core/crypto/common_cert_set.cc5
-rw-r--r--chromium/net/quic/core/crypto/crypto_framer.cc24
-rw-r--r--chromium/net/quic/core/crypto/crypto_framer.h7
-rw-r--r--chromium/net/quic/core/crypto/crypto_handshake_message.cc7
-rw-r--r--chromium/net/quic/core/crypto/crypto_handshake_message.h4
-rw-r--r--chromium/net/quic/core/crypto/crypto_server_test.cc8
-rw-r--r--chromium/net/quic/core/crypto/crypto_utils.cc101
-rw-r--r--chromium/net/quic/core/crypto/crypto_utils.h44
-rw-r--r--chromium/net/quic/core/crypto/crypto_utils_test.cc14
-rw-r--r--chromium/net/quic/core/crypto/null_decrypter.cc18
-rw-r--r--chromium/net/quic/core/crypto/null_decrypter.h11
-rw-r--r--chromium/net/quic/core/crypto/null_encrypter.cc2
-rw-r--r--chromium/net/quic/core/crypto/quic_crypto_client_config.cc17
-rw-r--r--chromium/net/quic/core/crypto/quic_crypto_server_config.cc19
-rw-r--r--chromium/net/quic/core/crypto/quic_crypto_server_config_test.cc3
-rw-r--r--chromium/net/quic/core/crypto/quic_decrypter.cc27
-rw-r--r--chromium/net/quic/core/crypto/quic_decrypter.h3
-rw-r--r--chromium/net/quic/core/crypto/quic_encrypter.cc19
-rw-r--r--chromium/net/quic/core/crypto/quic_encrypter.h5
-rw-r--r--chromium/net/quic/core/crypto/quic_random.cc5
-rw-r--r--chromium/net/quic/core/frames/quic_connection_close_frame.cc4
-rw-r--r--chromium/net/quic/core/frames/quic_connection_close_frame.h1
-rw-r--r--chromium/net/quic/core/frames/quic_frame.h6
-rw-r--r--chromium/net/quic/core/frames/quic_ietf_blocked_frame.cc21
-rw-r--r--chromium/net/quic/core/frames/quic_ietf_blocked_frame.h32
-rw-r--r--chromium/net/quic/core/frames/quic_ietf_max_stream_id_frame.cc23
-rw-r--r--chromium/net/quic/core/frames/quic_ietf_max_stream_id_frame.h32
-rw-r--r--chromium/net/quic/core/frames/quic_ietf_stream_id_blocked_frame.cc23
-rw-r--r--chromium/net/quic/core/frames/quic_ietf_stream_id_blocked_frame.h33
-rw-r--r--chromium/net/quic/core/frames/quic_path_challenge_frame.cc35
-rw-r--r--chromium/net/quic/core/frames/quic_path_challenge_frame.h37
-rw-r--r--chromium/net/quic/core/frames/quic_path_response_frame.cc34
-rw-r--r--chromium/net/quic/core/frames/quic_path_response_frame.h37
-rw-r--r--chromium/net/quic/core/frames/quic_stop_sending_frame.cc27
-rw-r--r--chromium/net/quic/core/frames/quic_stop_sending_frame.h31
-rw-r--r--chromium/net/quic/core/frames/quic_window_update_frame.h4
-rw-r--r--chromium/net/quic/core/quic_buffered_packet_store.cc5
-rw-r--r--chromium/net/quic/core/quic_buffered_packet_store.h3
-rw-r--r--chromium/net/quic/core/quic_buffered_packet_store_test.cc84
-rw-r--r--chromium/net/quic/core/quic_client_promised_info_test.cc87
-rw-r--r--chromium/net/quic/core/quic_config.cc15
-rw-r--r--chromium/net/quic/core/quic_config.h22
-rw-r--r--chromium/net/quic/core/quic_config_test.cc4
-rw-r--r--chromium/net/quic/core/quic_connection.cc752
-rw-r--r--chromium/net/quic/core/quic_connection.h227
-rw-r--r--chromium/net/quic/core/quic_connection_test.cc1036
-rw-r--r--chromium/net/quic/core/quic_constants.h12
-rw-r--r--chromium/net/quic/core/quic_control_frame_manager.cc9
-rw-r--r--chromium/net/quic/core/quic_control_frame_manager_test.cc1
-rw-r--r--chromium/net/quic/core/quic_crypto_client_handshaker.cc12
-rw-r--r--chromium/net/quic/core/quic_crypto_client_stream_test.cc1
-rw-r--r--chromium/net/quic/core/quic_crypto_server_handshaker.cc8
-rw-r--r--chromium/net/quic/core/quic_crypto_server_stream.cc3
-rw-r--r--chromium/net/quic/core/quic_crypto_stream.cc2
-rw-r--r--chromium/net/quic/core/quic_crypto_stream_test.cc80
-rw-r--r--chromium/net/quic/core/quic_data_reader.cc14
-rw-r--r--chromium/net/quic/core/quic_data_reader.h9
-rw-r--r--chromium/net/quic/core/quic_data_writer.h1
-rw-r--r--chromium/net/quic/core/quic_data_writer_test.cc43
-rw-r--r--chromium/net/quic/core/quic_error_codes.h35
-rw-r--r--chromium/net/quic/core/quic_flags_list.h146
-rw-r--r--chromium/net/quic/core/quic_flow_controller.cc12
-rw-r--r--chromium/net/quic/core/quic_flow_controller_test.cc62
-rw-r--r--chromium/net/quic/core/quic_framer.cc448
-rw-r--r--chromium/net/quic/core/quic_framer.h141
-rw-r--r--chromium/net/quic/core/quic_framer_test.cc720
-rw-r--r--chromium/net/quic/core/quic_headers_stream.cc3
-rw-r--r--chromium/net/quic/core/quic_headers_stream_test.cc6
-rw-r--r--chromium/net/quic/core/quic_ietf_framer_test.cc727
-rw-r--r--chromium/net/quic/core/quic_packet_creator.cc44
-rw-r--r--chromium/net/quic/core/quic_packet_creator.h26
-rw-r--r--chromium/net/quic/core/quic_packet_creator_test.cc35
-rw-r--r--chromium/net/quic/core/quic_packet_generator.cc11
-rw-r--r--chromium/net/quic/core/quic_packet_generator.h4
-rw-r--r--chromium/net/quic/core/quic_packet_generator_test.cc32
-rw-r--r--chromium/net/quic/core/quic_packets.cc15
-rw-r--r--chromium/net/quic/core/quic_packets.h12
-rw-r--r--chromium/net/quic/core/quic_sent_packet_manager.cc224
-rw-r--r--chromium/net/quic/core/quic_sent_packet_manager.h80
-rw-r--r--chromium/net/quic/core/quic_sent_packet_manager_test.cc485
-rw-r--r--chromium/net/quic/core/quic_server_session_base_test.cc55
-rw-r--r--chromium/net/quic/core/quic_session.cc173
-rw-r--r--chromium/net/quic/core/quic_session.h43
-rw-r--r--chromium/net/quic/core/quic_session_test.cc1427
-rw-r--r--chromium/net/quic/core/quic_spdy_session.cc59
-rw-r--r--chromium/net/quic/core/quic_spdy_session.h9
-rw-r--r--chromium/net/quic/core/quic_spdy_session_test.cc395
-rw-r--r--chromium/net/quic/core/quic_spdy_stream.cc29
-rw-r--r--chromium/net/quic/core/quic_spdy_stream.h14
-rw-r--r--chromium/net/quic/core/quic_spdy_stream_test.cc30
-rw-r--r--chromium/net/quic/core/quic_stream.cc86
-rw-r--r--chromium/net/quic/core/quic_stream.h27
-rw-r--r--chromium/net/quic/core/quic_stream_send_buffer.cc152
-rw-r--r--chromium/net/quic/core/quic_stream_send_buffer.h23
-rw-r--r--chromium/net/quic/core/quic_stream_send_buffer_test.cc45
-rw-r--r--chromium/net/quic/core/quic_stream_sequencer_buffer.cc35
-rw-r--r--chromium/net/quic/core/quic_stream_sequencer_test.cc3
-rw-r--r--chromium/net/quic/core/quic_stream_test.cc60
-rw-r--r--chromium/net/quic/core/quic_types.h19
-rw-r--r--chromium/net/quic/core/quic_unacked_packet_map.cc6
-rw-r--r--chromium/net/quic/core/quic_unacked_packet_map.h6
-rw-r--r--chromium/net/quic/core/quic_utils.cc59
-rw-r--r--chromium/net/quic/core/quic_utils.h19
-rw-r--r--chromium/net/quic/core/quic_utils_test.cc10
-rw-r--r--chromium/net/quic/core/quic_versions.cc13
-rw-r--r--chromium/net/quic/core/quic_versions.h6
-rw-r--r--chromium/net/quic/core/quic_write_blocked_list.cc7
-rw-r--r--chromium/net/quic/core/quic_write_blocked_list.h180
-rw-r--r--chromium/net/quic/core/quic_write_blocked_list_test.cc95
-rw-r--r--chromium/net/quic/core/tls_client_handshaker.cc30
-rw-r--r--chromium/net/quic/core/tls_handshaker.cc45
-rw-r--r--chromium/net/quic/core/tls_handshaker.h6
-rw-r--r--chromium/net/quic/core/tls_handshaker_test.cc64
-rw-r--r--chromium/net/quic/core/tls_server_handshaker.cc30
-rw-r--r--chromium/net/quic/http/decoder/quic_http_frame_decoder_adapter.cc9
-rw-r--r--chromium/net/quic/http/quic_http_structures.h1
-rw-r--r--chromium/net/quic/http/tools/quic_http_random_util.cc16
-rw-r--r--chromium/net/quic/http/tools/quic_http_random_util.h9
-rw-r--r--chromium/net/quic/platform/api/quic_logging.h2
-rw-r--r--chromium/net/quic/platform/api/quic_mem_slice.h4
-rw-r--r--chromium/net/quic/platform/api/quic_singleton.h48
-rw-r--r--chromium/net/quic/platform/api/quic_singleton_test.cc32
-rw-r--r--chromium/net/quic/platform/api/quic_test.h2
-rw-r--r--chromium/net/quic/platform/api/quic_uint128.h19
-rw-r--r--chromium/net/quic/platform/impl/quic_logging_impl.h2
-rw-r--r--chromium/net/quic/platform/impl/quic_mem_slice_impl.cc5
-rw-r--r--chromium/net/quic/platform/impl/quic_mem_slice_impl.h4
-rw-r--r--chromium/net/quic/platform/impl/quic_singleton_impl.h20
-rw-r--r--chromium/net/quic/platform/impl/quic_test_impl.cc14
-rw-r--r--chromium/net/quic/platform/impl/quic_test_impl.h37
-rw-r--r--chromium/net/quic/platform/impl/quic_uint128_impl.h19
-rw-r--r--chromium/net/quic/quartc/quartc_factory.cc21
-rw-r--r--chromium/net/quic/quartc/quartc_factory_interface.h6
-rw-r--r--chromium/net/quic/quartc/quartc_session.cc28
-rw-r--r--chromium/net/quic/quartc/quartc_session.h2
-rw-r--r--chromium/net/quic/quartc/quartc_session_interface.h4
-rw-r--r--chromium/net/quic/quartc/quartc_session_test.cc16
-rw-r--r--chromium/net/quic/quartc/quartc_session_visitor_interface.h27
-rw-r--r--chromium/net/quic/quartc/quartc_stream.cc36
-rw-r--r--chromium/net/quic/quartc/quartc_stream.h16
-rw-r--r--chromium/net/quic/quartc/quartc_stream_interface.h18
-rw-r--r--chromium/net/quic/quartc/quartc_stream_test.cc89
-rw-r--r--chromium/net/quic/test_tools/crypto_test_utils.cc38
-rw-r--r--chromium/net/quic/test_tools/mock_crypto_client_stream.cc33
-rw-r--r--chromium/net/quic/test_tools/quic_config_peer.cc13
-rw-r--r--chromium/net/quic/test_tools/quic_config_peer.h6
-rw-r--r--chromium/net/quic/test_tools/quic_connection_peer.cc26
-rw-r--r--chromium/net/quic/test_tools/quic_connection_peer.h10
-rw-r--r--chromium/net/quic/test_tools/quic_framer_peer.cc199
-rw-r--r--chromium/net/quic/test_tools/quic_framer_peer.h95
-rw-r--r--chromium/net/quic/test_tools/quic_packet_creator_peer.cc4
-rw-r--r--chromium/net/quic/test_tools/quic_sent_packet_manager_peer.cc14
-rw-r--r--chromium/net/quic/test_tools/quic_sent_packet_manager_peer.h6
-rw-r--r--chromium/net/quic/test_tools/quic_stream_send_buffer_peer.cc11
-rw-r--r--chromium/net/quic/test_tools/quic_stream_send_buffer_peer.h2
-rw-r--r--chromium/net/quic/test_tools/quic_test_utils.cc33
-rw-r--r--chromium/net/quic/test_tools/quic_test_utils.h29
-rw-r--r--chromium/net/quic/test_tools/simple_quic_framer.cc11
-rw-r--r--chromium/net/quic/test_tools/simple_session_notifier.cc14
-rw-r--r--chromium/net/quic/test_tools/simple_session_notifier.h3
-rw-r--r--chromium/net/quic/test_tools/simple_session_notifier_test.cc7
-rw-r--r--chromium/net/quic/test_tools/simulator/quic_endpoint.cc4
-rw-r--r--chromium/net/quic/test_tools/simulator/quic_endpoint.h1
-rw-r--r--chromium/net/quic/test_tools/simulator/quic_endpoint_test.cc2
-rw-r--r--chromium/net/reporting/reporting_browsing_data_remover_unittest.cc2
-rw-r--r--chromium/net/reporting/reporting_cache.cc75
-rw-r--r--chromium/net/reporting/reporting_cache.h30
-rw-r--r--chromium/net/reporting/reporting_cache_unittest.cc18
-rw-r--r--chromium/net/reporting/reporting_context.cc2
-rw-r--r--chromium/net/reporting/reporting_context.h6
-rw-r--r--chromium/net/reporting/reporting_delegate.cc11
-rw-r--r--chromium/net/reporting/reporting_delivery_agent.cc19
-rw-r--r--chromium/net/reporting/reporting_delivery_agent_unittest.cc114
-rw-r--r--chromium/net/reporting/reporting_endpoint_manager.cc2
-rw-r--r--chromium/net/reporting/reporting_garbage_collector_unittest.cc8
-rw-r--r--chromium/net/reporting/reporting_header_parser.cc54
-rw-r--r--chromium/net/reporting/reporting_header_parser.h3
-rw-r--r--chromium/net/reporting/reporting_network_change_observer_unittest.cc8
-rw-r--r--chromium/net/reporting/reporting_report.cc8
-rw-r--r--chromium/net/reporting/reporting_report.h7
-rw-r--r--chromium/net/reporting/reporting_service.cc11
-rw-r--r--chromium/net/reporting/reporting_service.h9
-rw-r--r--chromium/net/reporting/reporting_service_unittest.cc34
-rw-r--r--chromium/net/reporting/reporting_test_util.cc20
-rw-r--r--chromium/net/reporting/reporting_test_util.h11
-rw-r--r--chromium/net/reporting/reporting_uploader.cc46
-rw-r--r--chromium/net/reporting/reporting_uploader.h3
-rw-r--r--chromium/net/reporting/reporting_uploader_unittest.cc31
-rw-r--r--chromium/net/server/http_server.cc3
-rw-r--r--chromium/net/socket/client_socket_factory.cc9
-rw-r--r--chromium/net/socket/client_socket_factory.h6
-rw-r--r--chromium/net/socket/client_socket_handle.h10
-rw-r--r--chromium/net/socket/client_socket_pool_base_unittest.cc5
-rw-r--r--chromium/net/socket/client_socket_pool_manager.cc30
-rw-r--r--chromium/net/socket/client_socket_pool_manager.h4
-rw-r--r--chromium/net/socket/client_socket_pool_manager_impl.cc2
-rw-r--r--chromium/net/socket/client_socket_pool_manager_impl.h2
-rw-r--r--chromium/net/socket/datagram_client_socket.h77
-rw-r--r--chromium/net/socket/datagram_socket.h4
-rw-r--r--chromium/net/socket/fuzzed_datagram_client_socket.cc29
-rw-r--r--chromium/net/socket/fuzzed_datagram_client_socket.h18
-rw-r--r--chromium/net/socket/fuzzed_socket.cc27
-rw-r--r--chromium/net/socket/fuzzed_socket.h15
-rw-r--r--chromium/net/socket/fuzzed_socket_factory.cc4
-rw-r--r--chromium/net/socket/fuzzed_socket_factory.h3
-rw-r--r--chromium/net/socket/socket_posix.cc9
-rw-r--r--chromium/net/socket/socket_posix.h13
-rw-r--r--chromium/net/socket/socket_test_util.cc228
-rw-r--r--chromium/net/socket/socket_test_util.h99
-rw-r--r--chromium/net/socket/ssl_client_socket.cc4
-rw-r--r--chromium/net/socket/ssl_client_socket.h34
-rw-r--r--chromium/net/socket/ssl_client_socket_impl.cc84
-rw-r--r--chromium/net/socket/ssl_client_socket_impl.h3
-rw-r--r--chromium/net/socket/ssl_client_socket_pool.cc110
-rw-r--r--chromium/net/socket/ssl_client_socket_pool.h12
-rw-r--r--chromium/net/socket/ssl_client_socket_pool_unittest.cc9
-rw-r--r--chromium/net/socket/ssl_client_socket_unittest.cc50
-rw-r--r--chromium/net/socket/tcp_client_socket.h9
-rw-r--r--chromium/net/socket/tcp_socket_unittest.cc108
-rw-r--r--chromium/net/socket/tcp_socket_win.cc94
-rw-r--r--chromium/net/socket/transport_client_socket.h27
-rw-r--r--chromium/net/socket/transport_client_socket_pool_test_util.cc45
-rw-r--r--chromium/net/socket/transport_client_socket_pool_test_util.h3
-rw-r--r--chromium/net/socket/transport_client_socket_pool_unittest.cc6
-rw-r--r--chromium/net/socket/udp_client_socket.cc52
-rw-r--r--chromium/net/socket/udp_client_socket.h27
-rw-r--r--chromium/net/socket/udp_server_socket.cc7
-rw-r--r--chromium/net/socket/udp_server_socket.h1
-rw-r--r--chromium/net/socket/udp_socket_perftest.cc5
-rw-r--r--chromium/net/socket/udp_socket_posix.cc419
-rw-r--r--chromium/net/socket/udp_socket_posix.h220
-rw-r--r--chromium/net/socket/udp_socket_posix_unittest.cc747
-rw-r--r--chromium/net/socket/udp_socket_unittest.cc196
-rw-r--r--chromium/net/socket/udp_socket_win.cc44
-rw-r--r--chromium/net/socket/udp_socket_win.h26
-rw-r--r--chromium/net/socket/websocket_endpoint_lock_manager.cc24
-rw-r--r--chromium/net/socket/websocket_endpoint_lock_manager.h12
-rw-r--r--chromium/net/socket/websocket_endpoint_lock_manager_unittest.cc145
-rw-r--r--chromium/net/socket/websocket_transport_client_socket_pool.cc20
-rw-r--r--chromium/net/socket/websocket_transport_client_socket_pool.h20
-rw-r--r--chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc79
-rw-r--r--chromium/net/socket/websocket_transport_connect_sub_job.cc21
-rw-r--r--chromium/net/socket/websocket_transport_connect_sub_job.h10
-rw-r--r--chromium/net/spdy/chromium/bidirectional_stream_spdy_impl.cc6
-rw-r--r--chromium/net/spdy/chromium/bidirectional_stream_spdy_impl.h3
-rw-r--r--chromium/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc4
-rw-r--r--chromium/net/spdy/chromium/buffered_spdy_framer.cc6
-rw-r--r--chromium/net/spdy/chromium/buffered_spdy_framer.h9
-rw-r--r--chromium/net/spdy/chromium/buffered_spdy_framer_unittest.cc2
-rw-r--r--chromium/net/spdy/chromium/spdy_http_stream.cc4
-rw-r--r--chromium/net/spdy/chromium/spdy_http_stream_unittest.cc33
-rw-r--r--chromium/net/spdy/chromium/spdy_http_utils.cc2
-rw-r--r--chromium/net/spdy/chromium/spdy_log_util.cc16
-rw-r--r--chromium/net/spdy/chromium/spdy_log_util.h7
-rw-r--r--chromium/net/spdy/chromium/spdy_network_transaction_unittest.cc272
-rw-r--r--chromium/net/spdy/chromium/spdy_session.cc41
-rw-r--r--chromium/net/spdy/chromium/spdy_session.h6
-rw-r--r--chromium/net/spdy/chromium/spdy_session_pool.cc30
-rw-r--r--chromium/net/spdy/chromium/spdy_session_pool.h13
-rw-r--r--chromium/net/spdy/chromium/spdy_session_pool_unittest.cc17
-rw-r--r--chromium/net/spdy/chromium/spdy_session_unittest.cc59
-rw-r--r--chromium/net/spdy/chromium/spdy_stream.cc17
-rw-r--r--chromium/net/spdy/chromium/spdy_stream.h19
-rw-r--r--chromium/net/spdy/chromium/spdy_stream_unittest.cc92
-rw-r--r--chromium/net/spdy/chromium/spdy_test_util_common.cc57
-rw-r--r--chromium/net/spdy/chromium/spdy_test_util_common.h36
-rw-r--r--chromium/net/spdy/core/hpack/hpack_encoder.cc6
-rw-r--r--chromium/net/spdy/core/hpack/hpack_encoder.h4
-rw-r--r--chromium/net/spdy/core/hpack/hpack_entry.cc10
-rw-r--r--chromium/net/spdy/core/http2_frame_decoder_adapter.cc12
-rw-r--r--chromium/net/spdy/core/http2_frame_decoder_adapter.h10
-rw-r--r--chromium/net/spdy/core/mock_spdy_framer_visitor.h3
-rw-r--r--chromium/net/spdy/core/spdy_deframer_visitor.cc25
-rw-r--r--chromium/net/spdy/core/spdy_framer.cc1
-rw-r--r--chromium/net/spdy/core/spdy_framer_test.cc52
-rw-r--r--chromium/net/spdy/core/spdy_header_block.cc19
-rw-r--r--chromium/net/spdy/core/spdy_header_block.h12
-rw-r--r--chromium/net/spdy/core/spdy_header_block_test.cc1
-rw-r--r--chromium/net/spdy/core/spdy_no_op_visitor.h3
-rw-r--r--chromium/net/spdy/core/spdy_protocol.cc35
-rw-r--r--chromium/net/spdy/core/spdy_protocol.h6
-rw-r--r--chromium/net/spdy/core/spdy_protocol_test.cc8
-rw-r--r--chromium/net/spdy/core/spdy_test_utils.cc52
-rw-r--r--chromium/net/spdy/core/spdy_test_utils.h32
-rw-r--r--chromium/net/spdy/platform/api/spdy_flags.h1
-rw-r--r--chromium/net/spdy/platform/impl/spdy_flags_impl.cc6
-rw-r--r--chromium/net/spdy/platform/impl/spdy_flags_impl.h6
-rw-r--r--chromium/net/ssl/client_cert_identity_unittest.cc8
-rw-r--r--chromium/net/ssl/client_cert_store_nss.cc3
-rw-r--r--chromium/net/ssl/ssl_client_session_cache_unittest.cc1
-rw-r--r--chromium/net/ssl/ssl_config.cc9
-rw-r--r--chromium/net/ssl/ssl_config.h12
-rw-r--r--chromium/net/ssl/ssl_config_unittest.cc36
-rw-r--r--chromium/net/ssl/ssl_info.cc37
-rw-r--r--chromium/net/ssl/ssl_info.h41
-rw-r--r--chromium/net/ssl/ssl_platform_key_android.cc10
-rw-r--r--chromium/net/test/embedded_test_server/controllable_http_response.cc38
-rw-r--r--chromium/net/test/embedded_test_server/controllable_http_response.h16
-rw-r--r--chromium/net/test/embedded_test_server/default_handlers.cc2
-rw-r--r--chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc46
-rw-r--r--chromium/net/test/net_test_suite.cc8
-rw-r--r--chromium/net/test/quic_simple_test_server.cc247
-rw-r--r--chromium/net/test/quic_simple_test_server.h60
-rw-r--r--chromium/net/tools/cert_verify_tool/cert_verify_tool.cc3
-rw-r--r--chromium/net/tools/cert_verify_tool/verify_using_cert_verify_proc.cc3
-rw-r--r--chromium/net/tools/cert_verify_tool/verify_using_path_builder.cc1
-rwxr-xr-xchromium/net/tools/ct_log_list/make_ct_known_logs_list.py4
-rwxr-xr-xchromium/net/tools/ct_log_list/make_ct_known_logs_list_unittest.py4
-rw-r--r--chromium/net/tools/net_watcher/net_watcher.cc16
-rw-r--r--chromium/net/tools/quic/chlo_extractor.cc35
-rw-r--r--chromium/net/tools/quic/chlo_extractor_test.cc24
-rw-r--r--chromium/net/tools/quic/crypto_message_printer_bin.cc1
-rw-r--r--chromium/net/tools/quic/end_to_end_test.cc60
-rw-r--r--chromium/net/tools/quic/quic_client_base.cc3
-rw-r--r--chromium/net/tools/quic/quic_client_base.h2
-rw-r--r--chromium/net/tools/quic/quic_client_epoll_network_helper.h7
-rw-r--r--chromium/net/tools/quic/quic_client_message_loop_network_helper.cc5
-rw-r--r--chromium/net/tools/quic/quic_dispatcher.cc59
-rw-r--r--chromium/net/tools/quic/quic_dispatcher.h33
-rw-r--r--chromium/net/tools/quic/quic_dispatcher_test.cc231
-rw-r--r--chromium/net/tools/quic/quic_http_response_cache.cc8
-rw-r--r--chromium/net/tools/quic/quic_packet_printer_bin.cc8
-rw-r--r--chromium/net/tools/quic/quic_server_bin.cc6
-rw-r--r--chromium/net/tools/quic/quic_simple_client_bin.cc2
-rw-r--r--chromium/net/tools/quic/quic_simple_server_session.cc10
-rw-r--r--chromium/net/tools/quic/quic_simple_server_session_test.cc114
-rw-r--r--chromium/net/tools/quic/quic_simple_server_stream_test.cc5
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_base.cc2
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_session_test.cc136
-rw-r--r--chromium/net/tools/quic/quic_spdy_client_stream_test.cc22
-rw-r--r--chromium/net/tools/quic/quic_time_wait_list_manager.cc29
-rw-r--r--chromium/net/tools/quic/quic_time_wait_list_manager.h10
-rw-r--r--chromium/net/tools/quic/quic_time_wait_list_manager_test.cc10
-rw-r--r--chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc4
-rw-r--r--chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h9
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_client.cc17
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_client.h4
-rwxr-xr-xchromium/net/tools/testserver/testserver.py9
-rw-r--r--chromium/net/tools/transport_security_state_generator/input_file_parsers.cc2
-rwxr-xr-xchromium/net/tools/update_ios_bundle_data.py1
-rw-r--r--chromium/net/traffic_annotation/network_traffic_annotation.h6
-rw-r--r--chromium/net/traffic_annotation/network_traffic_annotation_test_helper.h2
-rw-r--r--chromium/net/url_request/report_sender.cc8
-rw-r--r--chromium/net/url_request/report_sender.h2
-rw-r--r--chromium/net/url_request/static_http_user_agent_settings.h10
-rw-r--r--chromium/net/url_request/url_fetcher.h5
-rw-r--r--chromium/net/url_request/url_fetcher_impl_unittest.cc18
-rw-r--r--chromium/net/url_request/url_request.cc25
-rw-r--r--chromium/net/url_request/url_request.h10
-rw-r--r--chromium/net/url_request/url_request_context.cc3
-rw-r--r--chromium/net/url_request/url_request_context.h6
-rw-r--r--chromium/net/url_request/url_request_context_builder.cc41
-rw-r--r--chromium/net/url_request/url_request_context_builder.h48
-rw-r--r--chromium/net/url_request/url_request_context_builder_unittest.cc4
-rw-r--r--chromium/net/url_request/url_request_context_storage.cc4
-rw-r--r--chromium/net/url_request/url_request_context_storage.h5
-rw-r--r--chromium/net/url_request/url_request_context_unittest.cc5
-rw-r--r--chromium/net/url_request/url_request_data_job_fuzzer.cc27
-rw-r--r--chromium/net/url_request/url_request_ftp_job.h2
-rw-r--r--chromium/net/url_request/url_request_ftp_job_unittest.cc29
-rw-r--r--chromium/net/url_request/url_request_http_job.cc129
-rw-r--r--chromium/net/url_request/url_request_http_job.h2
-rw-r--r--chromium/net/url_request/url_request_http_job_histogram.h39
-rw-r--r--chromium/net/url_request/url_request_http_job_unittest.cc12
-rw-r--r--chromium/net/url_request/url_request_job_manager.cc4
-rw-r--r--chromium/net/url_request/url_request_test_util.h2
-rw-r--r--chromium/net/url_request/url_request_throttler_test_support.cc2
-rw-r--r--chromium/net/url_request/url_request_throttler_test_support.h2
-rw-r--r--chromium/net/url_request/url_request_unittest.cc918
-rw-r--r--chromium/net/websockets/OWNERS1
-rw-r--r--chromium/net/websockets/websocket_basic_handshake_stream.cc214
-rw-r--r--chromium/net/websockets/websocket_basic_handshake_stream.h15
-rw-r--r--chromium/net/websockets/websocket_basic_stream.cc16
-rw-r--r--chromium/net/websockets/websocket_basic_stream.h2
-rw-r--r--chromium/net/websockets/websocket_basic_stream_adapters_test.cc5
-rw-r--r--chromium/net/websockets/websocket_basic_stream_test.cc25
-rw-r--r--chromium/net/websockets/websocket_channel.cc190
-rw-r--r--chromium/net/websockets/websocket_channel.h23
-rw-r--r--chromium/net/websockets/websocket_channel_test.cc657
-rw-r--r--chromium/net/websockets/websocket_deflate_stream.cc11
-rw-r--r--chromium/net/websockets/websocket_deflate_stream_fuzzer.cc3
-rw-r--r--chromium/net/websockets/websocket_deflate_stream_test.cc15
-rw-r--r--chromium/net/websockets/websocket_deflater.cc4
-rw-r--r--chromium/net/websockets/websocket_deflater.h2
-rw-r--r--chromium/net/websockets/websocket_deflater_test.cc1
-rw-r--r--chromium/net/websockets/websocket_end_to_end_test.cc101
-rw-r--r--chromium/net/websockets/websocket_event_interface.h57
-rw-r--r--chromium/net/websockets/websocket_frame.cc2
-rw-r--r--chromium/net/websockets/websocket_frame.h2
-rw-r--r--chromium/net/websockets/websocket_frame_parser.cc10
-rw-r--r--chromium/net/websockets/websocket_frame_parser.h1
-rw-r--r--chromium/net/websockets/websocket_handshake_constants.cc2
-rw-r--r--chromium/net/websockets/websocket_handshake_constants.h8
-rw-r--r--chromium/net/websockets/websocket_handshake_response_info.cc1
-rw-r--r--chromium/net/websockets/websocket_handshake_response_info.h2
-rw-r--r--chromium/net/websockets/websocket_handshake_stream_base.cc154
-rw-r--r--chromium/net/websockets/websocket_handshake_stream_base.h98
-rw-r--r--chromium/net/websockets/websocket_handshake_stream_create_helper.cc7
-rw-r--r--chromium/net/websockets/websocket_handshake_stream_create_helper.h4
-rw-r--r--chromium/net/websockets/websocket_handshake_stream_create_helper_test.cc21
-rw-r--r--chromium/net/websockets/websocket_http2_handshake_stream.cc165
-rw-r--r--chromium/net/websockets/websocket_http2_handshake_stream.h2
-rw-r--r--chromium/net/websockets/websocket_inflater.cc7
-rw-r--r--chromium/net/websockets/websocket_inflater.h2
-rw-r--r--chromium/net/websockets/websocket_inflater_test.cc1
-rw-r--r--chromium/net/websockets/websocket_stream.cc66
-rw-r--r--chromium/net/websockets/websocket_stream.h2
-rw-r--r--chromium/net/websockets/websocket_stream_cookie_test.cc6
-rw-r--r--chromium/net/websockets/websocket_stream_create_test_base.cc16
-rw-r--r--chromium/net/websockets/websocket_stream_create_test_base.h4
-rw-r--r--chromium/net/websockets/websocket_stream_test.cc1138
-rw-r--r--chromium/net/websockets/websocket_test_util.cc30
-rw-r--r--chromium/net/websockets/websocket_test_util.h3
826 files changed, 34276 insertions, 17150 deletions
diff --git a/chromium/net/BUILD.gn b/chromium/net/BUILD.gn
index 081e0634169..a2d700e2ae9 100644
--- a/chromium/net/BUILD.gn
+++ b/chromium/net/BUILD.gn
@@ -37,8 +37,8 @@ posix_avoid_mmap = is_android && current_cpu != "x86"
use_v8_in_net = !is_ios && !is_proto_quic
enable_built_in_dns = !is_ios && !is_proto_quic
-# Unix sockets are not supported on iOS, Fuchsia or NaCl.
-enable_unix_sockets = is_posix && !is_ios && !is_fuchsia && !is_nacl
+# Unix sockets are not supported on iOS or NaCl.
+enable_unix_sockets = is_posix && !is_ios && !is_nacl
# Android and Fuchsia can't run testserver.py directly, so they use remote
# test server.
@@ -47,8 +47,8 @@ use_remote_test_server = is_android || is_fuchsia
# Python works only on Linux, MacOS and Windows.
enable_python_utils = !is_android && !is_fuchsia && !is_ios
-buildflag_header("features") {
- header = "net_features.h"
+buildflag_header("buildflags") {
+ header = "net_buildflags.h"
flags = [
"POSIX_AVOID_MMAP=$posix_avoid_mmap",
"DISABLE_FILE_SUPPORT=$disable_file_support",
@@ -109,6 +109,8 @@ component("net") {
"base/auth.h",
"base/completion_callback.h",
"base/completion_once_callback.h",
+ "base/datagram_buffer.cc",
+ "base/datagram_buffer.h",
"base/escape.cc",
"base/escape.h",
"base/hash_value.cc",
@@ -238,10 +240,6 @@ component("net") {
"cert/signed_certificate_timestamp_and_status.h",
"cert/signed_tree_head.cc",
"cert/signed_tree_head.h",
- "cert/sth_distributor.cc",
- "cert/sth_distributor.h",
- "cert/sth_observer.h",
- "cert/sth_reporter.h",
"cert/symantec_certs.cc",
"cert/symantec_certs.h",
"cert/x509_cert_types.cc",
@@ -306,6 +304,8 @@ component("net") {
"log/net_log_source_type_list.h",
"log/net_log_with_source.cc",
"log/net_log_with_source.h",
+ "quic/core/quic_error_codes.cc",
+ "quic/core/quic_error_codes.h",
"socket/client_socket_handle.cc",
"socket/client_socket_handle.h",
"socket/connection_attempts.h",
@@ -471,8 +471,6 @@ component("net") {
"base/network_delegate.h",
"base/network_delegate_impl.cc",
"base/network_delegate_impl.h",
- "base/network_interfaces_getifaddrs.cc",
- "base/network_interfaces_getifaddrs.h",
"base/network_interfaces_linux.cc",
"base/network_interfaces_linux.h",
"base/network_interfaces_nacl.cc",
@@ -480,11 +478,6 @@ component("net") {
"base/network_interfaces_posix.h",
"base/network_interfaces_win.cc",
"base/network_interfaces_win.h",
- "base/network_throttle_manager.h",
- "base/network_throttle_manager_impl.cc",
- "base/network_throttle_manager_impl.h",
- "base/percentile_estimator.cc",
- "base/percentile_estimator.h",
"base/platform_mime_util.h",
"base/platform_mime_util_linux.cc",
"base/platform_mime_util_mac.mm",
@@ -875,10 +868,10 @@ component("net") {
"http/http_stream_factory_impl_job.h",
"http/http_stream_factory_impl_job_controller.cc",
"http/http_stream_factory_impl_job_controller.h",
- "http/http_stream_factory_impl_request.cc",
- "http/http_stream_factory_impl_request.h",
"http/http_stream_parser.cc",
"http/http_stream_parser.h",
+ "http/http_stream_request.cc",
+ "http/http_stream_request.h",
"http/http_transaction.h",
"http/http_transaction_factory.h",
"http/http_version.h",
@@ -888,6 +881,8 @@ component("net") {
"http/proxy_client_socket.h",
"http/proxy_connect_redirect_http_stream.cc",
"http/proxy_connect_redirect_http_stream.h",
+ "http/proxy_fallback.cc",
+ "http/proxy_fallback.h",
"http/transport_security_persister.cc",
"http/transport_security_persister.h",
"http/url_security_manager.cc",
@@ -1077,12 +1072,14 @@ component("net") {
"proxy_resolution/proxy_config_service_mac.h",
"proxy_resolution/proxy_config_service_win.cc",
"proxy_resolution/proxy_config_service_win.h",
- "proxy_resolution/proxy_config_source.cc",
- "proxy_resolution/proxy_config_source.h",
+ "proxy_resolution/proxy_config_with_annotation.cc",
+ "proxy_resolution/proxy_config_with_annotation.h",
"proxy_resolution/proxy_info.cc",
"proxy_resolution/proxy_info.h",
"proxy_resolution/proxy_list.cc",
"proxy_resolution/proxy_list.h",
+ "proxy_resolution/proxy_resolution_service.cc",
+ "proxy_resolution/proxy_resolution_service.h",
"proxy_resolution/proxy_resolver.h",
"proxy_resolution/proxy_resolver_error_observer.h",
"proxy_resolution/proxy_resolver_factory.cc",
@@ -1092,8 +1089,6 @@ component("net") {
"proxy_resolution/proxy_resolver_winhttp.cc",
"proxy_resolution/proxy_resolver_winhttp.h",
"proxy_resolution/proxy_retry_info.h",
- "proxy_resolution/proxy_service.cc",
- "proxy_resolution/proxy_service.h",
"quic/chromium/bidirectional_stream_quic_impl.cc",
"quic/chromium/bidirectional_stream_quic_impl.h",
"quic/chromium/crypto/channel_id_chromium.cc",
@@ -1252,13 +1247,25 @@ component("net") {
"quic/core/frames/quic_frame.h",
"quic/core/frames/quic_goaway_frame.cc",
"quic/core/frames/quic_goaway_frame.h",
+ "quic/core/frames/quic_ietf_blocked_frame.cc",
+ "quic/core/frames/quic_ietf_blocked_frame.h",
+ "quic/core/frames/quic_ietf_max_stream_id_frame.cc",
+ "quic/core/frames/quic_ietf_max_stream_id_frame.h",
+ "quic/core/frames/quic_ietf_stream_id_blocked_frame.cc",
+ "quic/core/frames/quic_ietf_stream_id_blocked_frame.h",
"quic/core/frames/quic_mtu_discovery_frame.h",
"quic/core/frames/quic_padding_frame.cc",
"quic/core/frames/quic_padding_frame.h",
+ "quic/core/frames/quic_path_challenge_frame.cc",
+ "quic/core/frames/quic_path_challenge_frame.h",
+ "quic/core/frames/quic_path_response_frame.cc",
+ "quic/core/frames/quic_path_response_frame.h",
"quic/core/frames/quic_ping_frame.cc",
"quic/core/frames/quic_ping_frame.h",
"quic/core/frames/quic_rst_stream_frame.cc",
"quic/core/frames/quic_rst_stream_frame.h",
+ "quic/core/frames/quic_stop_sending_frame.cc",
+ "quic/core/frames/quic_stop_sending_frame.h",
"quic/core/frames/quic_stop_waiting_frame.cc",
"quic/core/frames/quic_stop_waiting_frame.h",
"quic/core/frames/quic_stream_frame.cc",
@@ -1310,8 +1317,6 @@ component("net") {
"quic/core/quic_data_reader.h",
"quic/core/quic_data_writer.cc",
"quic/core/quic_data_writer.h",
- "quic/core/quic_error_codes.cc",
- "quic/core/quic_error_codes.h",
"quic/core/quic_flags_list.h",
"quic/core/quic_flow_controller.cc",
"quic/core/quic_flow_controller.h",
@@ -1461,6 +1466,7 @@ component("net") {
"quic/platform/api/quic_ptr_util.h",
"quic/platform/api/quic_reconstruct_object.h",
"quic/platform/api/quic_reference_counted.h",
+ "quic/platform/api/quic_singleton.h",
"quic/platform/api/quic_socket_address.cc",
"quic/platform/api/quic_socket_address.h",
"quic/platform/api/quic_stack_trace.h",
@@ -1504,6 +1510,7 @@ component("net") {
"quic/platform/impl/quic_ptr_util_impl.h",
"quic/platform/impl/quic_reconstruct_object_impl.h",
"quic/platform/impl/quic_reference_counted_impl.h",
+ "quic/platform/impl/quic_singleton_impl.h",
"quic/platform/impl/quic_socket_address_impl.cc",
"quic/platform/impl/quic_socket_address_impl.h",
"quic/platform/impl/quic_stack_trace_impl.h",
@@ -1577,6 +1584,7 @@ component("net") {
"socket/tcp_socket_posix.h",
"socket/tcp_socket_win.cc",
"socket/tcp_socket_win.h",
+ "socket/transport_client_socket.h",
"socket/transport_client_socket_pool.cc",
"socket/transport_client_socket_pool.h",
"socket/udp_client_socket.cc",
@@ -1767,6 +1775,7 @@ component("net") {
"url_request/url_request_filter.h",
"url_request/url_request_http_job.cc",
"url_request/url_request_http_job.h",
+ "url_request/url_request_http_job_histogram.h",
"url_request/url_request_intercepting_job_factory.cc",
"url_request/url_request_intercepting_job_factory.h",
"url_request/url_request_interceptor.cc",
@@ -1798,10 +1807,6 @@ component("net") {
"url_request/view_cache_helper.h",
"url_request/websocket_handshake_userdata_key.cc",
"url_request/websocket_handshake_userdata_key.h",
- "websockets/websocket_handshake_request_info.h",
- "websockets/websocket_handshake_response_info.h",
- "websockets/websocket_handshake_stream_base.h",
- "websockets/websocket_stream.h",
]
deps += [
"//base/third_party/dynamic_annotations",
@@ -1854,7 +1859,7 @@ component("net") {
]
}
- if (is_posix) {
+ if (is_posix || is_fuchsia) {
if (posix_avoid_mmap) {
sources -= [ "disk_cache/blockfile/mapped_file_posix.cc" ]
} else {
@@ -1899,8 +1904,8 @@ component("net") {
}
# Use getifaddrs() on POSIX platforms, except Linux and Android.
- if (!is_posix || is_linux || is_android || is_fuchsia) {
- sources -= [
+ if (is_posix && !is_linux && !is_android) {
+ sources += [
"base/network_interfaces_getifaddrs.cc",
"base/network_interfaces_getifaddrs.h",
]
@@ -2061,7 +2066,7 @@ component("net") {
configs += net_configs
public_deps += [
- ":features",
+ ":buildflags",
"//url",
]
@@ -2189,6 +2194,7 @@ component("net") {
"websockets/websocket_handshake_request_info.h",
"websockets/websocket_handshake_response_info.cc",
"websockets/websocket_handshake_response_info.h",
+ "websockets/websocket_handshake_stream_base.cc",
"websockets/websocket_handshake_stream_base.h",
"websockets/websocket_handshake_stream_create_helper.cc",
"websockets/websocket_handshake_stream_create_helper.h",
@@ -2362,6 +2368,7 @@ bundle_data("test_support_bundle_data") {
"data/ssl/certificates/2048-rsa-intermediate.pem",
"data/ssl/certificates/2048-rsa-root.pem",
"data/ssl/certificates/39_months_after_2015_04.pem",
+ "data/ssl/certificates/39_months_based_on_last_day.pem",
"data/ssl/certificates/40_months_after_2015_04.pem",
"data/ssl/certificates/60_months_after_2012_07.pem",
"data/ssl/certificates/61_months_after_2012_07.pem",
@@ -2409,6 +2416,7 @@ bundle_data("test_support_bundle_data") {
"data/ssl/certificates/client_6_ca.pem",
"data/ssl/certificates/client_root_ca.pem",
"data/ssl/certificates/common_name_only.pem",
+ "data/ssl/certificates/comodo-chain.pem",
"data/ssl/certificates/crit-codeSigning-chain.pem",
"data/ssl/certificates/crlset_by_intermediate_serial.raw",
"data/ssl/certificates/crlset_by_leaf_spki.raw",
@@ -2568,6 +2576,8 @@ static_library("test_support") {
"cert/mock_client_cert_verifier.cc",
"cert/mock_client_cert_verifier.h",
"cookies/canonical_cookie_test_helpers.h",
+ "cookies/cookie_change_dispatcher_test_helpers.cc",
+ "cookies/cookie_change_dispatcher_test_helpers.h",
"cookies/cookie_monster_store_test.cc",
"cookies/cookie_monster_store_test.h",
"cookies/cookie_store_change_unittest.h",
@@ -2646,6 +2656,8 @@ static_library("test_support") {
"test/keychain_test_util_mac.h",
"test/net_test_suite.cc",
"test/net_test_suite.h",
+ "test/quic_simple_test_server.cc",
+ "test/quic_simple_test_server.h",
"test/scoped_disable_exit_on_dfatal.cc",
"test/scoped_disable_exit_on_dfatal.h",
"test/tcp_socket_proxy.cc",
@@ -2685,6 +2697,7 @@ static_library("test_support") {
]
deps = [
+ ":simple_quic_tools",
"//third_party/zlib",
]
@@ -3558,6 +3571,22 @@ bundle_data("net_unittests_bundle_data") {
"data/ocsp_unittest/revoke_response.pem",
"data/ocsp_unittest/revoke_response_reason.pem",
"data/ocsp_unittest/unknown_response.pem",
+ "data/ov_name_constraints/int-bmp-o1.pem",
+ "data/ov_name_constraints/int-cn.pem",
+ "data/ov_name_constraints/int-o1-o2.pem",
+ "data/ov_name_constraints/int-o1-plus-o2.pem",
+ "data/ov_name_constraints/int-o2-o1.pem",
+ "data/ov_name_constraints/int-o3.pem",
+ "data/ov_name_constraints/leaf-no-o.pem",
+ "data/ov_name_constraints/leaf-o1-o2.pem",
+ "data/ov_name_constraints/leaf-o1.pem",
+ "data/ov_name_constraints/nc-int-exclude-o1.pem",
+ "data/ov_name_constraints/nc-int-permit-bmp-o1.pem",
+ "data/ov_name_constraints/nc-int-permit-cn.pem",
+ "data/ov_name_constraints/nc-int-permit-dns.pem",
+ "data/ov_name_constraints/nc-int-permit-o1.pem",
+ "data/ov_name_constraints/nc-int-permit-o2-o1-o3.pem",
+ "data/ov_name_constraints/root.pem",
"data/parse_certificate_unittest/bad_key_usage.pem",
"data/parse_certificate_unittest/bad_policy_qualifiers.pem",
"data/parse_certificate_unittest/bad_signature_algorithm_oid.pem",
@@ -4667,6 +4696,7 @@ test("net_unittests") {
"base/backoff_entry_unittest.cc",
"base/chunked_upload_data_stream_unittest.cc",
"base/data_url_unittest.cc",
+ "base/datagram_buffer_unittest.cc",
"base/directory_lister_unittest.cc",
"base/directory_listing_unittest.cc",
"base/elements_upload_data_stream_unittest.cc",
@@ -4691,13 +4721,10 @@ test("net_unittests") {
"base/network_activity_monitor_unittest.cc",
"base/network_change_notifier_unittest.cc",
"base/network_change_notifier_win_unittest.cc",
- "base/network_interfaces_getifaddrs_unittest.cc",
"base/network_interfaces_linux_unittest.cc",
"base/network_interfaces_unittest.cc",
"base/network_interfaces_win_unittest.cc",
- "base/network_throttle_manager_impl_unittest.cc",
"base/parse_number_unittest.cc",
- "base/percentile_estimator_unittest.cc",
"base/port_util_unittest.cc",
"base/prioritized_dispatcher_unittest.cc",
"base/priority_queue_unittest.cc",
@@ -4712,7 +4739,7 @@ test("net_unittests") {
"cert/caching_cert_verifier_unittest.cc",
"cert/cert_verifier_unittest.cc",
"cert/cert_verify_proc_android_unittest.cc",
- "cert/cert_verify_proc_ios_unittest.cc",
+ "cert/cert_verify_proc_ios_unittest.mm",
"cert/cert_verify_proc_mac_unittest.cc",
"cert/cert_verify_proc_unittest.cc",
"cert/crl_set_unittest.cc",
@@ -4763,7 +4790,6 @@ test("net_unittests") {
"cert/nss_profile_filter_chromeos_unittest.cc",
"cert/pem_tokenizer_unittest.cc",
"cert/signed_certificate_timestamp_unittest.cc",
- "cert/sth_distributor_unittest.cc",
"cert/symantec_certs_unittest.cc",
"cert/test_root_certs_unittest.cc",
"cert/x509_cert_types_unittest.cc",
@@ -4878,9 +4904,9 @@ test("net_unittests") {
"http/http_server_properties_manager_unittest.cc",
"http/http_status_code_unittest.cc",
"http/http_stream_factory_impl_job_controller_unittest.cc",
- "http/http_stream_factory_impl_request_unittest.cc",
"http/http_stream_factory_impl_unittest.cc",
"http/http_stream_parser_unittest.cc",
+ "http/http_stream_request_unittest.cc",
"http/http_util_unittest.cc",
"http/http_vary_data_unittest.cc",
"http/mock_allow_http_auth_preferences.cc",
@@ -5001,11 +5027,11 @@ test("net_unittests") {
"proxy_resolution/proxy_config_unittest.cc",
"proxy_resolution/proxy_info_unittest.cc",
"proxy_resolution/proxy_list_unittest.cc",
+ "proxy_resolution/proxy_resolution_service_unittest.cc",
"proxy_resolution/proxy_resolver_v8_tracing_unittest.cc",
"proxy_resolution/proxy_resolver_v8_tracing_wrapper_unittest.cc",
"proxy_resolution/proxy_resolver_v8_unittest.cc",
"proxy_resolution/proxy_server_unittest.cc",
- "proxy_resolution/proxy_service_unittest.cc",
"quic/chromium/bidirectional_stream_quic_impl_unittest.cc",
"quic/chromium/crypto/proof_test_chromium.cc",
"quic/chromium/crypto/proof_verifier_chromium_test.cc",
@@ -5152,6 +5178,7 @@ test("net_unittests") {
"quic/core/quic_sent_packet_manager_test.cc",
"quic/core/quic_server_id_test.cc",
"quic/core/quic_server_session_base_test.cc",
+ "quic/core/quic_session_test.cc",
"quic/core/quic_simple_buffer_allocator_test.cc",
"quic/core/quic_socket_address_coder_test.cc",
"quic/core/quic_spdy_session_test.cc",
@@ -5175,6 +5202,7 @@ test("net_unittests") {
"quic/platform/api/quic_mem_slice_span_test.cc",
"quic/platform/api/quic_mem_slice_test.cc",
"quic/platform/api/quic_reference_counted_test.cc",
+ "quic/platform/api/quic_singleton_test.cc",
"quic/platform/api/quic_str_cat_test.cc",
"quic/platform/api/quic_test_random.h",
"quic/platform/api/quic_text_utils_test.cc",
@@ -5205,6 +5233,7 @@ test("net_unittests") {
"socket/transport_client_socket_pool_test_util.h",
"socket/transport_client_socket_pool_unittest.cc",
"socket/transport_client_socket_unittest.cc",
+ "socket/udp_socket_posix_unittest.cc",
"socket/udp_socket_unittest.cc",
"socket/websocket_endpoint_lock_manager_unittest.cc",
"socket/websocket_transport_client_socket_pool_unittest.cc",
@@ -5579,7 +5608,7 @@ test("net_unittests") {
deps += [
":net_browser_services",
":net_utility_services",
- "//mojo/edk/system",
+ "//mojo/edk",
]
} else {
sources -= [
@@ -5626,9 +5655,9 @@ test("net_unittests") {
]
}
- # Use getifaddrs() on POSIX platforms, except Linux, Android and Fuchsia.
- if (!is_posix || is_linux || is_android || is_fuchsia) {
- sources -= [ "base/network_interfaces_getifaddrs_unittest.cc" ]
+ # Use getifaddrs() on POSIX platforms, except Linux and Android.
+ if (is_posix && !is_linux && !is_android) {
+ sources += [ "base/network_interfaces_getifaddrs_unittest.cc" ]
}
# Unit tests that aren't supported by the current ICU alternatives on Android.
@@ -6222,6 +6251,10 @@ fuzzer_test("net_url_request_fuzzer") {
"//net",
]
dict = "data/fuzzer_dictionaries/net_url_request_fuzzer.dict"
+
+ # TODO(crbug.com/820089): Figure out why this fuzzer's corpus explodes to
+ # 10 GB. For now, disable it on ClusterFuzz.
+ additional_configs = [ "//testing/libfuzzer:no_clusterfuzz" ]
}
fuzzer_test("net_auth_challenge_tokenizer_fuzzer") {
diff --git a/chromium/net/OWNERS b/chromium/net/OWNERS
index 28514a7112f..a7eb9b6fc01 100644
--- a/chromium/net/OWNERS
+++ b/chromium/net/OWNERS
@@ -11,7 +11,6 @@ mmenke@chromium.org
nharper@chromium.org
pauljensen@chromium.org
rch@chromium.org
-rdsmith@chromium.org
rsleevi@chromium.org
xunjieli@chromium.org
zhongyi@chromium.org
diff --git a/chromium/net/android/keystore.cc b/chromium/net/android/keystore.cc
index 2115730103d..8104682ecf4 100644
--- a/chromium/net/android/keystore.cc
+++ b/chromium/net/android/keystore.cc
@@ -35,7 +35,7 @@ bool SignWithPrivateKey(const base::android::JavaRef<jobject>& private_key_ref,
// Convert message to byte[] array.
ScopedJavaLocalRef<jbyteArray> input_ref =
- ToJavaByteArray(env, input.data(), input.length());
+ ToJavaByteArray(env, input.data(), input.size());
DCHECK(!input_ref.is_null());
// Invoke platform API
diff --git a/chromium/net/android/network_library.h b/chromium/net/android/network_library.h
index ce5afd1668b..651600d11b4 100644
--- a/chromium/net/android/network_library.h
+++ b/chromium/net/android/network_library.h
@@ -77,8 +77,11 @@ NET_EXPORT bool GetIsRoaming();
// Marshmallow and later versions. Returns false on earlier versions.
NET_EXPORT bool GetIsCaptivePortal();
-// Gets the SSID of the currently associated WiFi access point if there is one.
-// Otherwise, returns empty string.
+// Gets the SSID of the currently associated WiFi access point if there is one,
+// and it is available. SSID may not be available if the app does not have
+// permissions to access it. On Android M+, the app accessing SSID needs to have
+// ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION. If there is no WiFi access
+// point or its SSID is unavailable, an empty string is returned.
NET_EXPORT_PRIVATE std::string GetWifiSSID();
// Gets the DNS servers and puts them in |dns_servers|.
diff --git a/chromium/net/base/address_tracker_linux.cc b/chromium/net/base/address_tracker_linux.cc
index 600e2c7d541..be8da1aa986 100644
--- a/chromium/net/base/address_tracker_linux.cc
+++ b/chromium/net/base/address_tracker_linux.cc
@@ -231,7 +231,7 @@ void AddressTrackerLinux::Init() {
if (tracking_) {
rv = base::MessageLoopForIO::current()->WatchFileDescriptor(
- netlink_fd_, true, base::MessageLoopForIO::WATCH_READ, &watcher_, this);
+ netlink_fd_, true, base::MessagePumpForIO::WATCH_READ, &watcher_, this);
if (rv < 0) {
PLOG(ERROR) << "Could not watch NETLINK socket";
AbortAndForceOnline();
diff --git a/chromium/net/base/address_tracker_linux.h b/chromium/net/base/address_tracker_linux.h
index c0c89173e68..751f994c60e 100644
--- a/chromium/net/base/address_tracker_linux.h
+++ b/chromium/net/base/address_tracker_linux.h
@@ -19,6 +19,7 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_pump_for_io.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_checker.h"
@@ -31,8 +32,8 @@ namespace internal {
// Keeps track of network interface addresses using rtnetlink. Used by
// NetworkChangeNotifier to provide signals to registered IPAddressObservers.
-class NET_EXPORT_PRIVATE AddressTrackerLinux :
- public base::MessageLoopForIO::Watcher {
+class NET_EXPORT_PRIVATE AddressTrackerLinux
+ : public base::MessagePumpForIO::FdWatcher {
public:
typedef std::map<IPAddress, struct ifaddrmsg> AddressMap;
@@ -128,7 +129,7 @@ class NET_EXPORT_PRIVATE AddressTrackerLinux :
// Call when some part of initialization failed; forces online and unblocks.
void AbortAndForceOnline();
- // MessageLoopForIO::Watcher:
+ // MessagePumpForIO::FdWatcher:
void OnFileCanReadWithoutBlocking(int fd) override;
void OnFileCanWriteWithoutBlocking(int /* fd */) override;
@@ -158,7 +159,7 @@ class NET_EXPORT_PRIVATE AddressTrackerLinux :
base::Closure tunnel_callback_;
int netlink_fd_;
- base::MessageLoopForIO::FileDescriptorWatcher watcher_;
+ base::MessagePumpForIO::FdWatchController watcher_;
mutable base::Lock address_map_lock_;
AddressMap address_map_;
diff --git a/chromium/net/base/backoff_entry.cc b/chromium/net/base/backoff_entry.cc
index 5914711a288..db70d42726e 100644
--- a/chromium/net/base/backoff_entry.cc
+++ b/chromium/net/base/backoff_entry.cc
@@ -19,7 +19,7 @@ BackoffEntry::BackoffEntry(const BackoffEntry::Policy* policy)
: BackoffEntry(policy, nullptr) {}
BackoffEntry::BackoffEntry(const BackoffEntry::Policy* policy,
- base::TickClock* clock)
+ const base::TickClock* clock)
: policy_(policy), clock_(clock) {
DCHECK(policy_);
Reset();
diff --git a/chromium/net/base/backoff_entry.h b/chromium/net/base/backoff_entry.h
index db440207213..2c4cd180665 100644
--- a/chromium/net/base/backoff_entry.h
+++ b/chromium/net/base/backoff_entry.h
@@ -69,7 +69,7 @@ class NET_EXPORT BackoffEntry {
// Lifetime of policy and clock must enclose lifetime of BackoffEntry.
// |policy| pointer must be valid but isn't dereferenced during construction.
// |clock| pointer may be null.
- BackoffEntry(const Policy* policy, base::TickClock* clock);
+ BackoffEntry(const Policy* policy, const base::TickClock* clock);
virtual ~BackoffEntry();
// Inform this item that a request for the network resource it is
@@ -124,7 +124,7 @@ class NET_EXPORT BackoffEntry {
const Policy* const policy_; // Not owned.
- base::TickClock* const clock_; // Not owned.
+ const base::TickClock* const clock_; // Not owned.
THREAD_CHECKER(thread_checker_);
diff --git a/chromium/net/base/backoff_entry_serializer.cc b/chromium/net/base/backoff_entry_serializer.cc
index f2cbec753e0..57f5a3ee213 100644
--- a/chromium/net/base/backoff_entry_serializer.cc
+++ b/chromium/net/base/backoff_entry_serializer.cc
@@ -43,7 +43,7 @@ std::unique_ptr<base::Value> BackoffEntrySerializer::SerializeToValue(
std::unique_ptr<BackoffEntry> BackoffEntrySerializer::DeserializeFromValue(
const base::Value& serialized,
const BackoffEntry::Policy* policy,
- base::TickClock* tick_clock,
+ const base::TickClock* tick_clock,
base::Time time_now) {
const base::ListValue* serialized_list = nullptr;
if (!serialized.GetAsList(&serialized_list))
diff --git a/chromium/net/base/backoff_entry_serializer.h b/chromium/net/base/backoff_entry_serializer.h
index 1ecaf015d70..d5fde2c768d 100644
--- a/chromium/net/base/backoff_entry_serializer.h
+++ b/chromium/net/base/backoff_entry_serializer.h
@@ -45,7 +45,7 @@ class NET_EXPORT BackoffEntrySerializer {
static std::unique_ptr<BackoffEntry> DeserializeFromValue(
const base::Value& serialized,
const BackoffEntry::Policy* policy,
- base::TickClock* clock,
+ const base::TickClock* clock,
base::Time time_now);
private:
diff --git a/chromium/net/base/backoff_entry_serializer_unittest.cc b/chromium/net/base/backoff_entry_serializer_unittest.cc
index e5d22cfd469..748e22681a5 100644
--- a/chromium/net/base/backoff_entry_serializer_unittest.cc
+++ b/chromium/net/base/backoff_entry_serializer_unittest.cc
@@ -34,7 +34,7 @@ class TestTickClock : public base::TickClock {
TestTickClock() = default;
~TestTickClock() override = default;
- TimeTicks NowTicks() override { return now_ticks_; }
+ TimeTicks NowTicks() const override { return now_ticks_; }
void set_now(TimeTicks now) { now_ticks_ = now; }
private:
diff --git a/chromium/net/base/backoff_entry_unittest.cc b/chromium/net/base/backoff_entry_unittest.cc
index 0bed782e098..191097a0ec6 100644
--- a/chromium/net/base/backoff_entry_unittest.cc
+++ b/chromium/net/base/backoff_entry_unittest.cc
@@ -22,7 +22,7 @@ class TestTickClock : public base::TickClock {
TestTickClock() = default;
~TestTickClock() override = default;
- TimeTicks NowTicks() override { return now_ticks_; }
+ TimeTicks NowTicks() const override { return now_ticks_; }
void set_now(TimeTicks now) { now_ticks_ = now; }
private:
diff --git a/chromium/net/base/datagram_buffer.cc b/chromium/net/base/datagram_buffer.cc
new file mode 100644
index 00000000000..c4f3eaa2dcf
--- /dev/null
+++ b/chromium/net/base/datagram_buffer.cc
@@ -0,0 +1,56 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/base/datagram_buffer.h"
+#include "net/quic/platform/api/quic_ptr_util.h"
+
+namespace net {
+
+DatagramBufferPool::DatagramBufferPool(size_t max_buffer_size)
+ : max_buffer_size_(max_buffer_size) {}
+
+DatagramBufferPool::~DatagramBufferPool() {}
+
+void DatagramBufferPool::Enqueue(const char* buffer,
+ size_t buf_len,
+ DatagramBuffers* buffers) {
+ DCHECK_LE(buf_len, max_buffer_size_);
+ std::unique_ptr<DatagramBuffer> datagram_buffer;
+ if (free_list_.empty()) {
+ datagram_buffer =
+ QuicWrapUnique<DatagramBuffer>(new DatagramBuffer(max_buffer_size_));
+ } else {
+ datagram_buffer = std::move(free_list_.front());
+ free_list_.pop_front();
+ }
+ datagram_buffer->Set(buffer, buf_len);
+ buffers->emplace_back(std::move(datagram_buffer));
+}
+
+void DatagramBufferPool::Dequeue(DatagramBuffers* buffers) {
+ if (buffers->size() == 0)
+ return;
+
+ free_list_.splice(free_list_.cend(), *buffers);
+}
+
+DatagramBuffer::DatagramBuffer(size_t max_buffer_size)
+ : data_(new char[max_buffer_size]), length_(0) {}
+
+DatagramBuffer::~DatagramBuffer() {}
+
+void DatagramBuffer::Set(const char* buffer, size_t buf_len) {
+ length_ = buf_len;
+ std::memcpy(data_.get(), buffer, buf_len);
+}
+
+char* DatagramBuffer::data() const {
+ return data_.get();
+}
+
+size_t DatagramBuffer::length() const {
+ return length_;
+}
+
+} // namespace net
diff --git a/chromium/net/base/datagram_buffer.h b/chromium/net/base/datagram_buffer.h
new file mode 100644
index 00000000000..a7622b831d0
--- /dev/null
+++ b/chromium/net/base/datagram_buffer.h
@@ -0,0 +1,102 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_BASE_DATAGRAM_BUFFER_H_
+#define NET_BASE_DATAGRAM_BUFFER_H_
+
+#include <list>
+
+#include "base/memory/weak_ptr.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+// An IO buffer, (at least initially) specifically for use with the
+// new DatagramClientSocket::WriteAsync method, with the following key
+// features:
+//
+// 1) Meant to be easily batched when that improves efficiency. The
+// primary goal of WriteAsync is to enable enlisting an
+// additional cpu core for the kernel part of socket write.
+// 2) Uses unique_ptr (with std::move) rather than reference
+// counting as in IOBuffers. The benefit is safer cancellation
+// semantics, IOBuffer used reference count to enforce unique
+// ownership in an idiomatic fashion. unique_ptr is ligher weight
+// as it doesn't use thread safe primitives as
+// RefCountedThreadSafe does.
+// 3) Provides a pooling allocator, which for datagram buffers is
+// much cheaper than using fully general allocator (e.g. malloc
+// etc.). The implementation takes advantage of
+// std::list::splice so that costs associated with allocations
+// and copies of pool metadata quickly amortize to zero, and all
+// common operations are O(1).
+
+class DatagramBuffer;
+
+// Batches of DatagramBuffers are treated as a FIFO queue, implemented
+// by |std::list|. Note that |std::list::splice()| is attractive for
+// this use case because it keeps most operations to O(1) and
+// minimizes allocations/frees and copies.
+typedef std::list<std::unique_ptr<DatagramBuffer>> DatagramBuffers;
+
+class NET_EXPORT_PRIVATE DatagramBufferPool {
+ public:
+ // |max_buffer_size| must be >= largest |buf_len| provided to
+ // ||New()|.
+ DatagramBufferPool(size_t max_buffer_size);
+ DatagramBufferPool(const DatagramBufferPool&) = delete;
+ DatagramBufferPool& operator=(const DatagramBufferPool&) = delete;
+ virtual ~DatagramBufferPool();
+ // Insert a new element (drawn from the pool) containing a copy of
+ // |buffer| to |buffers|. Caller retains owenership of |buffers| and |buffer|.
+ void Enqueue(const char* buffer, size_t buf_len, DatagramBuffers* buffers);
+ // Return all elements of |buffers| to the pool. Caller retains
+ // ownership of |buffers|.
+ void Dequeue(DatagramBuffers* buffers);
+
+ size_t max_buffer_size() { return max_buffer_size_; }
+
+ private:
+ const size_t max_buffer_size_;
+ DatagramBuffers free_list_;
+};
+
+// |DatagramBuffer|s can only be created via
+// |DatagramBufferPool::Enqueue()|.
+//
+
+// |DatagramBuffer|s should be recycled via
+// |DatagramBufferPool::Dequeue|. Care must be taken when a
+// |DatagramBuffer| is moved to another thread via
+// |PostTask|. |Dequeue| is not expected to be thread-safe, so it
+// is preferred to move the |DatagramBuffer|s back to the thread where
+// the pool lives (e.g. using |PostTaskAndReturnWithResult|) and
+// dequeuing them from there. In the exception of pathalogical
+// cancellation (e.g. due to thread tear-down), the destructor will
+// release its memory permanently rather than returning to the pool.
+class NET_EXPORT_PRIVATE DatagramBuffer {
+ public:
+ DatagramBuffer() = delete;
+ DatagramBuffer(const DatagramBuffer&) = delete;
+ DatagramBuffer& operator=(const DatagramBuffer&) = delete;
+ ~DatagramBuffer();
+
+ char* data() const;
+ size_t length() const;
+
+ protected:
+ DatagramBuffer(size_t max_packet_size);
+
+ private:
+ friend class DatagramBufferPool;
+
+ void Set(const char* buffer, size_t buf_len);
+
+ std::unique_ptr<char[]> data_;
+ size_t length_;
+};
+
+} // namespace net
+
+#endif // NET_BASE_DATAGRAM_BUFFER_H_
diff --git a/chromium/net/base/datagram_buffer_unittest.cc b/chromium/net/base/datagram_buffer_unittest.cc
new file mode 100644
index 00000000000..0f65ffd669c
--- /dev/null
+++ b/chromium/net/base/datagram_buffer_unittest.cc
@@ -0,0 +1,54 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/base/datagram_buffer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace test {
+
+const size_t kMaxBufferSize = 1024;
+
+class DatagramBufferTest : public testing::Test {
+ public:
+ DatagramBufferTest() : pool_(kMaxBufferSize) {}
+
+ DatagramBufferPool pool_;
+};
+
+TEST_F(DatagramBufferTest, EnqueueCopiesData) {
+ DatagramBuffers buffers;
+ const char data[] = "foo";
+ pool_.Enqueue(data, sizeof(data), &buffers);
+ EXPECT_EQ(sizeof(data), buffers.front()->length());
+ EXPECT_NE(data, buffers.front()->data());
+ EXPECT_EQ(0, memcmp(data, buffers.front()->data(), sizeof(data)));
+}
+
+TEST_F(DatagramBufferTest, DatgramBufferPoolRecycles) {
+ DatagramBuffers buffers;
+ const char data1[] = "foo";
+ pool_.Enqueue(data1, sizeof(data1), &buffers);
+ DatagramBuffer* buffer1_ptr = buffers.back().get();
+ EXPECT_EQ(1u, buffers.size());
+ const char data2[] = "bar";
+ pool_.Enqueue(data2, sizeof(data2), &buffers);
+ DatagramBuffer* buffer2_ptr = buffers.back().get();
+ EXPECT_EQ(2u, buffers.size());
+ pool_.Dequeue(&buffers);
+ EXPECT_EQ(0u, buffers.size());
+ const char data3[] = "baz";
+ pool_.Enqueue(data3, sizeof(data3), &buffers);
+ EXPECT_EQ(1u, buffers.size());
+ EXPECT_EQ(buffer1_ptr, buffers.back().get());
+ const char data4[] = "bag";
+ pool_.Enqueue(data4, sizeof(data4), &buffers);
+ EXPECT_EQ(2u, buffers.size());
+ EXPECT_EQ(buffer2_ptr, buffers.back().get());
+}
+
+} // namespace test
+
+} // namespace net
diff --git a/chromium/net/base/escape.cc b/chromium/net/base/escape.cc
index 65a23c1c395..7578bb67001 100644
--- a/chromium/net/base/escape.cc
+++ b/chromium/net/base/escape.cc
@@ -6,7 +6,9 @@
#include "base/logging.h"
#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversion_utils.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/third_party/icu/icu_utf.h"
namespace net {
@@ -101,18 +103,15 @@ const char kUrlUnescape[128] = {
// Attempts to unescape the sequence at |index| within |escaped_text|. If
// successful, sets |value| to the unescaped value. Returns whether
// unescaping succeeded.
-template <typename STR>
-bool UnescapeUnsignedCharAtIndex(STR escaped_text,
+bool UnescapeUnsignedByteAtIndex(base::StringPiece escaped_text,
size_t index,
unsigned char* value) {
if ((index + 2) >= escaped_text.size())
return false;
if (escaped_text[index] != '%')
return false;
- const typename STR::value_type most_sig_digit(
- static_cast<typename STR::value_type>(escaped_text[index + 1]));
- const typename STR::value_type least_sig_digit(
- static_cast<typename STR::value_type>(escaped_text[index + 2]));
+ char most_sig_digit(escaped_text[index + 1]);
+ char least_sig_digit(escaped_text[index + 2]);
if (base::IsHexDigit(most_sig_digit) && base::IsHexDigit(least_sig_digit)) {
*value = base::HexDigitToInt(most_sig_digit) * 16 +
base::HexDigitToInt(least_sig_digit);
@@ -121,74 +120,136 @@ bool UnescapeUnsignedCharAtIndex(STR escaped_text,
return false;
}
-// Returns true if there is an Arabic Language Mark at |index|. |first_byte|
-// is the byte at |index|.
-template <typename STR>
-bool HasArabicLanguageMarkAtIndex(STR escaped_text,
- unsigned char first_byte,
- size_t index) {
- if (first_byte != 0xD8)
+// Attempts to unescape and decode a UTF-8-encoded percent-escaped character at
+// the specified index. On success, returns true, sets |code_point_out| to be
+// the character's code point and |unescaped_out| to be the unescaped UTF-8
+// string. |unescaped_out| will always be 1/3rd the length of the substring of
+// |escaped_text| that corresponds to the unescaped character.
+bool UnescapeUTF8CharacterAtIndex(base::StringPiece escaped_text,
+ size_t index,
+ uint32_t* code_point_out,
+ std::string* unescaped_out) {
+ DCHECK(unescaped_out->empty());
+
+ unsigned char bytes[CBU8_MAX_LENGTH];
+ if (!UnescapeUnsignedByteAtIndex(escaped_text, index, &bytes[0]))
return false;
- unsigned char second_byte;
- if (!UnescapeUnsignedCharAtIndex(escaped_text, index + 3, &second_byte))
- return false;
- return second_byte == 0x9c;
-}
-// Returns true if there is a BiDi control char at |index|. |first_byte| is the
-// byte at |index|.
-template <typename STR>
-bool HasThreeByteBidiControlCharAtIndex(STR escaped_text,
- unsigned char first_byte,
- size_t index) {
- if (first_byte != 0xE2)
- return false;
- unsigned char second_byte;
- if (!UnescapeUnsignedCharAtIndex(escaped_text, index + 3, &second_byte))
- return false;
- if (second_byte != 0x80 && second_byte != 0x81)
- return false;
- unsigned char third_byte;
- if (!UnescapeUnsignedCharAtIndex(escaped_text, index + 6, &third_byte))
- return false;
- if (second_byte == 0x80) {
- return third_byte == 0x8E ||
- third_byte == 0x8F ||
- (third_byte >= 0xAA && third_byte <= 0xAE);
+ size_t num_bytes = 1;
+
+ // If this is a lead byte, need to collect trail bytes as well.
+ if (CBU8_IS_LEAD(bytes[0])) {
+ // Look for the last trail byte of the UTF-8 character. Give up once
+ // reach max character length number of bytes, or hit an unescaped
+ // character. No need to check length of escaped_text, as
+ // UnescapeUnsignedByteAtIndex checks lengths.
+ while (num_bytes < arraysize(bytes) &&
+ UnescapeUnsignedByteAtIndex(escaped_text, index + num_bytes * 3,
+ &bytes[num_bytes]) &&
+ CBU8_IS_TRAIL(bytes[num_bytes])) {
+ ++num_bytes;
+ }
}
- return third_byte >= 0xA6 && third_byte <= 0xA9;
-}
-
-// Returns true if there is a four-byte banned char at |index|. |first_byte| is
-// the byte at |index|.
-template <typename STR>
-bool HasFourByteBannedCharAtIndex(STR escaped_text,
- unsigned char first_byte,
- size_t index) {
- // The following characters are blacklisted for spoofability concerns.
- // U+1F50F LOCK WITH INK PEN (%F0%9F%94%8F)
- // U+1F510 CLOSED LOCK WITH KEY (%F0%9F%94%90)
- // U+1F512 LOCK (%F0%9F%94%92)
- // U+1F513 OPEN LOCK (%F0%9F%94%93)
- if (first_byte != 0xF0)
- return false;
- unsigned char second_byte;
- if (!UnescapeUnsignedCharAtIndex(escaped_text, index + 3, &second_byte) ||
- second_byte != 0x9F) {
+ int32_t char_index = 0;
+ // Check if the unicode "character" that was just unescaped is valid.
+ if (!base::ReadUnicodeCharacter(reinterpret_cast<char*>(bytes), num_bytes,
+ &char_index, code_point_out)) {
return false;
}
- unsigned char third_byte;
- if (!UnescapeUnsignedCharAtIndex(escaped_text, index + 6, &third_byte) ||
- third_byte != 0x94) {
- return false;
+ // It's possible that a prefix of |bytes| forms a valid UTF-8 character,
+ // and the rest are not valid UTF-8, so need to update |num_bytes| based
+ // on the result of ReadUnicodeCharacter().
+ num_bytes = char_index + 1;
+ *unescaped_out = std::string(reinterpret_cast<char*>(bytes), num_bytes);
+ return true;
+}
+
+// This method takes a Unicode code point and returns true if it should be
+// unescaped, based on |rules|.
+bool ShouldUnescapeCodePoint(UnescapeRule::Type rules, uint32_t code_point) {
+ // If this is an ASCII character, use the lookup table.
+ if (code_point < 0x80) {
+ return kUrlUnescape[code_point] ||
+ // Allow some additional unescaping when flags are set.
+ (code_point == ' ' && (rules & UnescapeRule::SPACES)) ||
+ // Allow any of the prohibited but non-control characters when doing
+ // "special" chars.
+ ((code_point == '/' || code_point == '\\') &&
+ (rules & UnescapeRule::PATH_SEPARATORS)) ||
+ (code_point > ' ' && code_point != '/' && code_point != '\\' &&
+ (rules & UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS)) ||
+ // Additionally allow non-display characters if requested.
+ (code_point < ' ' &&
+ (rules & UnescapeRule::SPOOFING_AND_CONTROL_CHARS));
}
- unsigned char fourth_byte;
- return UnescapeUnsignedCharAtIndex(escaped_text, index + 9, &fourth_byte) &&
- (fourth_byte == 0x8F || fourth_byte == 0x90 || fourth_byte == 0x92 ||
- fourth_byte == 0x93);
+ // Some schemes such as data: and file: need to parse the exact binary data
+ // when loading the URL. For that reason, SPOOFING_AND_CONTROL_CHARS allows
+ // unescaping UTF-8 byte sequences that are not safe to display. DO NOT use
+ // SPOOFING_AND_CONTROL_CHARS if the parsed URL is going to be displayed in
+ // the UI.
+ if (rules & UnescapeRule::SPOOFING_AND_CONTROL_CHARS)
+ return true;
+
+ // Compare the codepoint against a list of characters that can be used
+ // to spoof other URLs.
+ //
+ // Can't use icu to make this cleaner, because Cronet cannot depend on
+ // icu, and currently uses this file.
+ // TODO(https://crbug.com/829873): Try to make this use icu, both to
+ // protect against regressions as the Unicode stndard is updated and to
+ // reduce the number of long lists of characters.
+ // TODO(https://crbug.com/824715): Add default ignoreable and formatting
+ // codepoints.
+ return !(
+ // Per http://tools.ietf.org/html/rfc3987#section-4.1, certain BiDi
+ // control characters are not allowed to appear unescaped in URLs.
+ code_point == 0x200E || // LEFT-TO-RIGHT MARK (%E2%80%8E)
+ code_point == 0x200F || // RIGHT-TO-LEFT MARK (%E2%80%8F)
+ code_point == 0x202A || // LEFT-TO-RIGHT EMBEDDING (%E2%80%AA)
+ code_point == 0x202B || // RIGHT-TO-LEFT EMBEDDING (%E2%80%AB)
+ code_point == 0x202C || // POP DIRECTIONAL FORMATTING (%E2%80%AC)
+ code_point == 0x202D || // LEFT-TO-RIGHT OVERRIDE (%E2%80%AD)
+ code_point == 0x202E || // RIGHT-TO-LEFT OVERRIDE (%E2%80%AE)
+
+ // The Unicode Technical Report (TR9) as referenced by RFC 3987 above has
+ // since added some new BiDi control characters that are not safe to
+ // unescape. http://www.unicode.org/reports/tr9
+ code_point == 0x061C || // ARABIC LETTER MARK (%D8%9C)
+ code_point == 0x2066 || // LEFT-TO-RIGHT ISOLATE (%E2%81%A6)
+ code_point == 0x2067 || // RIGHT-TO-LEFT ISOLATE (%E2%81%A7)
+ code_point == 0x2068 || // FIRST STRONG ISOLATE (%E2%81%A8)
+ code_point == 0x2069 || // POP DIRECTIONAL ISOLATE (%E2%81%A9)
+
+ // The following spoofable characters are also banned in unescaped URLs,
+ // because they could be used to imitate parts of a web browser's UI.
+ code_point == 0x1F50F || // LOCK WITH INK PEN (%F0%9F%94%8F)
+ code_point == 0x1F510 || // CLOSED LOCK WITH KEY (%F0%9F%94%90)
+ code_point == 0x1F512 || // LOCK (%F0%9F%94%92)
+ code_point == 0x1F513 || // OPEN LOCK (%F0%9F%94%93)
+
+ // Spaces are also banned, as they can be used to scroll text out of view.
+ code_point == 0x0085 || // NEXT LINE (%C2%85)
+ code_point == 0x00A0 || // NO-BREAK SPACE (%C2%A0)
+ code_point == 0x1680 || // OGHAM SPACE MARK (%E1%9A%80)
+ code_point == 0x2000 || // EN QUAD (%E2%80%80)
+ code_point == 0x2001 || // EM QUAD (%E2%80%81)
+ code_point == 0x2002 || // EN SPACE (%E2%80%82)
+ code_point == 0x2003 || // EM SPACE (%E2%80%83)
+ code_point == 0x2004 || // THREE-PER-EM SPACE (%E2%80%84)
+ code_point == 0x2005 || // FOUR-PER-EM SPACE (%E2%80%85)
+ code_point == 0x2006 || // SIX-PER-EM SPACE (%E2%80%86)
+ code_point == 0x2007 || // FIGURE SPACE (%E2%80%87)
+ code_point == 0x2008 || // PUNCTUATION SPACE (%E2%80%88)
+ code_point == 0x2009 || // THIN SPACE (%E2%80%89)
+ code_point == 0x200A || // HAIR SPACE (%E2%80%8A)
+ code_point == 0x2028 || // LINE SEPARATOR (%E2%80%A8)
+ code_point == 0x2029 || // PARAGRAPH SEPARATOR (%E2%80%A9)
+ code_point == 0x202F || // NARROW NO-BREAK SPACE (%E2%80%AF)
+ code_point == 0x205F || // MEDIUM MATHEMATICAL SPACE (%E2%81%9F)
+ code_point == 0x3000); // IDEOGRAPHIC SPACE (%E3%80%80)
}
// Unescapes |escaped_text| according to |rules|, returning the resulting
@@ -196,9 +257,8 @@ bool HasFourByteBannedCharAtIndex(STR escaped_text,
// the alterations done to the string that are not one-character-to-one-
// character. The resulting |adjustments| will always be sorted by increasing
// offset.
-template <typename STR>
-STR UnescapeURLWithAdjustmentsImpl(
- base::BasicStringPiece<STR> escaped_text,
+std::string UnescapeURLWithAdjustmentsImpl(
+ base::StringPiece escaped_text,
UnescapeRule::Type rules,
base::OffsetAdjuster::Adjustments* adjustments) {
if (adjustments)
@@ -210,105 +270,64 @@ STR UnescapeURLWithAdjustmentsImpl(
// The output of the unescaping is always smaller than the input, so we can
// reserve the input size to make sure we have enough buffer and don't have
// to allocate in the loop below.
- STR result;
+ std::string result;
result.reserve(escaped_text.length());
// Locations of adjusted text.
- for (size_t i = 0, max = escaped_text.size(); i < max; ++i) {
- if (static_cast<unsigned char>(escaped_text[i]) >= 128) {
- // Non ASCII character, append as is.
- result.push_back(escaped_text[i]);
- continue;
- }
-
- unsigned char first_byte;
- if (UnescapeUnsignedCharAtIndex(escaped_text, i, &first_byte)) {
- // Per http://tools.ietf.org/html/rfc3987#section-4.1, the following BiDi
- // control characters are not allowed to appear unescaped in URLs:
- //
- // U+200E LEFT-TO-RIGHT MARK (%E2%80%8E)
- // U+200F RIGHT-TO-LEFT MARK (%E2%80%8F)
- // U+202A LEFT-TO-RIGHT EMBEDDING (%E2%80%AA)
- // U+202B RIGHT-TO-LEFT EMBEDDING (%E2%80%AB)
- // U+202C POP DIRECTIONAL FORMATTING (%E2%80%AC)
- // U+202D LEFT-TO-RIGHT OVERRIDE (%E2%80%AD)
- // U+202E RIGHT-TO-LEFT OVERRIDE (%E2%80%AE)
- //
- // Additionally, the Unicode Technical Report (TR9) as referenced by RFC
- // 3987 above has since added some new BiDi control characters.
- // http://www.unicode.org/reports/tr9
- //
- // U+061C ARABIC LETTER MARK (%D8%9C)
- // U+2066 LEFT-TO-RIGHT ISOLATE (%E2%81%A6)
- // U+2067 RIGHT-TO-LEFT ISOLATE (%E2%81%A7)
- // U+2068 FIRST STRONG ISOLATE (%E2%81%A8)
- // U+2069 POP DIRECTIONAL ISOLATE (%E2%81%A9)
- //
- // The following spoofable characters are also banned, because they could
- // be used to imitate parts of a web browser's UI.
+ for (size_t i = 0, max = escaped_text.size(); i < max;) {
+ // Try to unescape the character.
+ uint32_t code_point;
+ std::string unescaped;
+ if (!UnescapeUTF8CharacterAtIndex(escaped_text, i, &code_point,
+ &unescaped)) {
+ // Check if the next character can be unescaped, but not as a valid UTF-8
+ // character. In that case, just unescaped and write the non-sense
+ // character.
//
- // U+1F50F LOCK WITH INK PEN (%F0%9F%94%8F)
- // U+1F510 CLOSED LOCK WITH KEY (%F0%9F%94%90)
- // U+1F512 LOCK (%F0%9F%94%92)
- // U+1F513 OPEN LOCK (%F0%9F%94%93)
- //
- // However, some schemes such as data: and file: need to parse the exact
- // binary data when loading the URL. For that reason,
- // SPOOFING_AND_CONTROL_CHARS allows unescaping BiDi control characters.
- // DO NOT use SPOOFING_AND_CONTROL_CHARS if the parsed URL is going to be
- // displayed in the UI.
- if (!(rules & UnescapeRule::SPOOFING_AND_CONTROL_CHARS)) {
- if (HasArabicLanguageMarkAtIndex(escaped_text, first_byte, i)) {
- // Keep Arabic Language Mark escaped.
- escaped_text.substr(i, 6).AppendToString(&result);
- i += 5;
- continue;
- }
- if (HasThreeByteBidiControlCharAtIndex(escaped_text, first_byte, i)) {
- // Keep BiDi control char escaped.
- escaped_text.substr(i, 9).AppendToString(&result);
- i += 8;
- continue;
- }
- if (HasFourByteBannedCharAtIndex(escaped_text, first_byte, i)) {
- // Keep banned char escaped.
- escaped_text.substr(i, 12).AppendToString(&result);
- i += 11;
- continue;
- }
- }
-
- if (first_byte >= 0x80 || // Unescape all high-bit characters.
- // For 7-bit characters, the lookup table tells us all valid chars.
- (kUrlUnescape[first_byte] ||
- // ...and we allow some additional unescaping when flags are set.
- (first_byte == ' ' && (rules & UnescapeRule::SPACES)) ||
- // Allow any of the prohibited but non-control characters when
- // we're doing "special" chars.
- ((first_byte == '/' || first_byte == '\\') &&
- (rules & UnescapeRule::PATH_SEPARATORS)) ||
- (first_byte > ' ' && first_byte != '/' && first_byte != '\\' &&
- (rules & UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS)) ||
- // Additionally allow non-display characters if requested.
- (first_byte < ' ' &&
- (rules & UnescapeRule::SPOOFING_AND_CONTROL_CHARS)))) {
- // Use the unescaped version of the character.
+ // TODO(https://crbug.com/829868): Do not unescape illegal UTF-8 sequences
+ // unless SPOOFING_AND_CONTROL_CHARS is given. Should also split that
+ // behaviour off into a separate function.
+ unsigned char non_utf8_byte;
+ if (UnescapeUnsignedByteAtIndex(escaped_text, i, &non_utf8_byte)) {
+ result.push_back(non_utf8_byte);
if (adjustments)
adjustments->push_back(base::OffsetAdjuster::Adjustment(i, 3, 1));
- result.push_back(first_byte);
- i += 2;
+ i += 3;
+ continue;
+ }
+
+ // Character is not escaped, so append as is, unless it's a '+' and
+ // REPLACE_PLUS_WITH_SPACE is being applied.
+ if (escaped_text[i] == '+' &&
+ (rules & UnescapeRule::REPLACE_PLUS_WITH_SPACE)) {
+ result.push_back(' ');
} else {
- // Keep escaped. Append a percent and we'll get the following two
- // digits on the next loops through.
- result.push_back('%');
+ result.push_back(escaped_text[i]);
+ }
+ ++i;
+ continue;
+ }
+
+ DCHECK(!unescaped.empty());
+
+ if (!ShouldUnescapeCodePoint(rules, code_point)) {
+ // If it's a valid UTF-8 character, but not safe to unescape, copy all
+ // bytes directly.
+ result.append(escaped_text.begin() + i,
+ escaped_text.begin() + i + 3 * unescaped.length());
+ i += unescaped.length() * 3;
+ continue;
+ }
+
+ // If the code point is allowed, and append the entire unescaped character.
+ result.append(unescaped);
+ if (adjustments) {
+ for (size_t j = 0; j < unescaped.length(); ++j) {
+ adjustments->push_back(
+ base::OffsetAdjuster::Adjustment(i + j * 3, 3, 1));
}
- } else if ((rules & UnescapeRule::REPLACE_PLUS_WITH_SPACE) &&
- escaped_text[i] == '+') {
- result.push_back(' ');
- } else {
- // Normal case for unescaped characters.
- result.push_back(escaped_text[i]);
}
+ i += 3 * unescaped.length();
}
return result;
@@ -436,11 +455,6 @@ std::string UnescapeURLComponent(base::StringPiece escaped_text,
return UnescapeURLWithAdjustmentsImpl(escaped_text, rules, NULL);
}
-base::string16 UnescapeURLComponent(base::StringPiece16 escaped_text,
- UnescapeRule::Type rules) {
- return UnescapeURLWithAdjustmentsImpl(escaped_text, rules, NULL);
-}
-
base::string16 UnescapeAndDecodeUTF8URLComponent(base::StringPiece text,
UnescapeRule::Type rules) {
return UnescapeAndDecodeUTF8URLComponentWithAdjustments(text, rules, NULL);
diff --git a/chromium/net/base/escape.h b/chromium/net/base/escape.h
index 5d494045d22..af4edf0f790 100644
--- a/chromium/net/base/escape.h
+++ b/chromium/net/base/escape.h
@@ -81,7 +81,8 @@ class UnescapeRule {
// Convert %20 to spaces. In some places where we're showing URLs, we may
// want this. In places where the URL may be copied and pasted out, then
// you wouldn't want this since it might not be interpreted in one piece
- // by other applications.
+ // by other applications. Other unicode spaces will not be unescaped unless
+ // SPOOFING_AND_CONTROL_CHARS is used.
SPACES = 1 << 1,
// Unescapes '/' and '\\'. If these characters were unescaped, the resulting
@@ -116,17 +117,16 @@ class UnescapeRule {
// Unescapes |escaped_text| and returns the result.
// Unescaping consists of looking for the exact pattern "%XX", where each X is
// a hex digit, and converting to the character with the numerical value of
-// those digits. Thus "i%20=%203%3b" unescapes to "i = 3;".
+// those digits. Thus "i%20=%203%3b" unescapes to "i = 3;", if the
+// "UnescapeRule::SPACES" used.
//
-// Watch out: this doesn't necessarily result in the correct final result,
-// because the encoding may be unknown. For example, the input might be ASCII,
-// which, after unescaping, is supposed to be interpreted as UTF-8, and then
-// converted into full UTF-16 chars. This function won't tell you if any
-// conversions need to take place, it only unescapes.
+// This method does not ensure that the output is a valid string using any
+// character encoding. However, unless SPOOFING_AND_CONTROL_CHARS is set, it
+// does leave escaped certain byte sequences that would be dangerous to display
+// to the user, because if interpreted as UTF-8, they could be used to mislead
+// the user.
NET_EXPORT std::string UnescapeURLComponent(base::StringPiece escaped_text,
UnescapeRule::Type rules);
-NET_EXPORT base::string16 UnescapeURLComponent(base::StringPiece16 escaped_text,
- UnescapeRule::Type rules);
// Unescapes the given substring as a URL, and then tries to interpret the
// result as being encoded as UTF-8. If the result is convertable into UTF-8, it
diff --git a/chromium/net/base/escape_unittest.cc b/chromium/net/base/escape_unittest.cc
index b828d80b5fe..fb13613f56a 100644
--- a/chromium/net/base/escape_unittest.cc
+++ b/chromium/net/base/escape_unittest.cc
@@ -21,12 +21,6 @@ struct EscapeCase {
};
struct UnescapeURLCase {
- const wchar_t* input;
- UnescapeRule::Type rules;
- const wchar_t* output;
-};
-
-struct UnescapeURLCaseASCII {
const char* input;
UnescapeRule::Type rules;
const char* output;
@@ -148,8 +142,8 @@ TEST(EscapeTest, EscapeUrlEncodedDataSpace) {
ASSERT_EQ(EscapeUrlEncodedData("a b", false), "a%20b");
}
-TEST(EscapeTest, UnescapeURLComponentASCII) {
- const UnescapeURLCaseASCII unescape_cases[] = {
+TEST(EscapeTest, UnescapeURLComponent) {
+ const UnescapeURLCase kUnescapeCases[] = {
{"", UnescapeRule::NORMAL, ""},
{"%2", UnescapeRule::NORMAL, "%2"},
{"%%%%%%", UnescapeRule::NORMAL, "%%%%%%"},
@@ -159,6 +153,115 @@ TEST(EscapeTest, UnescapeURLComponentASCII) {
"Some%20random text %25%2dOK"},
{"Some%20random text %25%2dOK", UnescapeRule::NORMAL,
"Some%20random text %25-OK"},
+ {"Some%20random text %25%E1%A6", UnescapeRule::NORMAL,
+ "Some%20random text %25\xE1\xA6"},
+ {"Some%20random text %25%E1%A6OK", UnescapeRule::NORMAL,
+ "Some%20random text %25\xE1\xA6OK"},
+ {"Some%20random text %25%E1%A6%99OK", UnescapeRule::NORMAL,
+ "Some%20random text %25\xE1\xA6\x99OK"},
+
+ // BiDi Control characters should not be unescaped unless explicity told
+ // to
+ // do so with UnescapeRule::SPOOFING_AND_CONTROL_CHARS
+ {"Some%20random text %25%D8%9COK", UnescapeRule::NORMAL,
+ "Some%20random text %25%D8%9COK"},
+ {"Some%20random text %25%E2%80%8EOK", UnescapeRule::NORMAL,
+ "Some%20random text %25%E2%80%8EOK"},
+ {"Some%20random text %25%E2%80%8FOK", UnescapeRule::NORMAL,
+ "Some%20random text %25%E2%80%8FOK"},
+ {"Some%20random text %25%E2%80%AAOK", UnescapeRule::NORMAL,
+ "Some%20random text %25%E2%80%AAOK"},
+ {"Some%20random text %25%E2%80%ABOK", UnescapeRule::NORMAL,
+ "Some%20random text %25%E2%80%ABOK"},
+ {"Some%20random text %25%E2%80%AEOK", UnescapeRule::NORMAL,
+ "Some%20random text %25%E2%80%AEOK"},
+ {"Some%20random text %25%E2%81%A6OK", UnescapeRule::NORMAL,
+ "Some%20random text %25%E2%81%A6OK"},
+ {"Some%20random text %25%E2%81%A9OK", UnescapeRule::NORMAL,
+ "Some%20random text %25%E2%81%A9OK"},
+ // UnescapeRule::SPOOFING_AND_CONTROL_CHARS should unescape BiDi Control
+ // characters.
+ {"Some%20random text %25%D8%9COK",
+ UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
+ "Some%20random text %25\xD8\x9COK"},
+ {"Some%20random text %25%E2%80%8EOK",
+ UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
+ "Some%20random text %25\xE2\x80\x8EOK"},
+ {"Some%20random text %25%E2%80%8FOK",
+ UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
+ "Some%20random text %25\xE2\x80\x8FOK"},
+ {"Some%20random text %25%E2%80%AAOK",
+ UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
+ "Some%20random text %25\xE2\x80\xAAOK"},
+ {"Some%20random text %25%E2%80%ABOK",
+ UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
+ "Some%20random text %25\xE2\x80\xABOK"},
+ {"Some%20random text %25%E2%80%AEOK",
+ UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
+ "Some%20random text %25\xE2\x80\xAEOK"},
+ {"Some%20random text %25%E2%81%A6OK",
+ UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
+ "Some%20random text %25\xE2\x81\xA6OK"},
+ {"Some%20random text %25%E2%81%A9OK",
+ UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
+ "Some%20random text %25\xE2\x81\xA9OK"},
+
+ // Certain banned characters should not be unescaped unless explicitly
+ // told
+ // to do so with UnescapeRule::SPOOFING_AND_CONTROL_CHARS.
+ // U+1F50F LOCK WITH INK PEN
+ {"Some%20random text %25%F0%9F%94%8FOK", UnescapeRule::NORMAL,
+ "Some%20random text %25%F0%9F%94%8FOK"},
+ // U+1F510 CLOSED LOCK WITH KEY
+ {"Some%20random text %25%F0%9F%94%90OK", UnescapeRule::NORMAL,
+ "Some%20random text %25%F0%9F%94%90OK"},
+ // U+1F512 LOCK
+ {"Some%20random text %25%F0%9F%94%92OK", UnescapeRule::NORMAL,
+ "Some%20random text %25%F0%9F%94%92OK"},
+ // U+1F513 OPEN LOCK
+ {"Some%20random text %25%F0%9F%94%93OK", UnescapeRule::NORMAL,
+ "Some%20random text %25%F0%9F%94%93OK"},
+ // UnescapeRule::SPOOFING_AND_CONTROL_CHARS should unescape banned
+ // characters.
+ {"Some%20random text %25%F0%9F%94%8FOK",
+ UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
+ "Some%20random text %25\xF0\x9F\x94\x8FOK"},
+ {"Some%20random text %25%F0%9F%94%90OK",
+ UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
+ "Some%20random text %25\xF0\x9F\x94\x90OK"},
+ {"Some%20random text %25%F0%9F%94%92OK",
+ UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
+ "Some%20random text %25\xF0\x9F\x94\x92OK"},
+ {"Some%20random text %25%F0%9F%94%93OK",
+ UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
+ "Some%20random text %25\xF0\x9F\x94\x93OK"},
+
+ // Spaces
+ {"(%C2%85)(%C2%A0)(%E1%9A%80)(%E2%80%80)", UnescapeRule::NORMAL,
+ "(%C2%85)(%C2%A0)(%E1%9A%80)(%E2%80%80)"},
+ {"(%E2%80%81)(%E2%80%82)(%E2%80%83)(%E2%80%84)", UnescapeRule::NORMAL,
+ "(%E2%80%81)(%E2%80%82)(%E2%80%83)(%E2%80%84)"},
+ {"(%E2%80%85)(%E2%80%86)(%E2%80%87)(%E2%80%88)", UnescapeRule::NORMAL,
+ "(%E2%80%85)(%E2%80%86)(%E2%80%87)(%E2%80%88)"},
+ {"(%E2%80%89)(%E2%80%8A)(%E2%80%A8)(%E2%80%A9)", UnescapeRule::NORMAL,
+ "(%E2%80%89)(%E2%80%8A)(%E2%80%A8)(%E2%80%A9)"},
+ {"(%E2%80%AF)(%E2%81%9F)(%E3%80%80)", UnescapeRule::NORMAL,
+ "(%E2%80%AF)(%E2%81%9F)(%E3%80%80)"},
+
+ // Two spoofing characters in a row should not be unescaped.
+ {"%D8%9C%D8%9C", UnescapeRule::NORMAL, "%D8%9C%D8%9C"},
+ // Non-spoofing characters surrounded by spoofing characters should be
+ // unescaped.
+ {"%D8%9C%C2%A1%D8%9C%C2%A1", UnescapeRule::NORMAL,
+ "%D8%9C\xC2\xA1%D8%9C\xC2\xA1"},
+ // Invalid UTF-8 characters surrounded by spoofing characters should be
+ // unescaped.
+ {"%D8%9C%85%D8%9C%85", UnescapeRule::NORMAL, "%D8%9C\x85%D8%9C\x85"},
+ // Test with enough trail bytes to overflow the CBU8_MAX_LENGTH-byte
+ // buffer. The first two bytes are a spoofing character as well.
+ {"%D8%9C%9C%9C%9C%9C%9C%9C%9C%9C%9C", UnescapeRule::NORMAL,
+ "%D8%9C\x9C\x9C\x9C\x9C\x9C\x9C\x9C\x9C\x9C"},
+
{"Some%20random text %25%2dOK", UnescapeRule::SPACES,
"Some random text %25-OK"},
{"Some%20random text %25%2dOK", UnescapeRule::PATH_SEPARATORS,
@@ -192,19 +295,22 @@ TEST(EscapeTest, UnescapeURLComponentASCII) {
{"Hello%20%13%10%02", UnescapeRule::SPACES, "Hello %13%10%02"},
{"Hello%20%13%10%02", UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
"Hello%20\x13\x10\x02"},
+ {"Hello\xE9\xA0\xA4\xE9\xA0\xA7",
+ UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
+ "Hello\xE9\xA0\xA4\xE9\xA0\xA7"},
// '/' and '\\' should only be unescaped by PATH_SEPARATORS.
{"%2F%5C", UnescapeRule::PATH_SEPARATORS, "/\\"},
- {"%2F%5C", UnescapeRule::SPACES |
- UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS |
- UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
+ {"%2F%5C",
+ UnescapeRule::SPACES |
+ UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS |
+ UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
"%2F%5C"},
};
- for (size_t i = 0; i < arraysize(unescape_cases); i++) {
- std::string str(unescape_cases[i].input);
- EXPECT_EQ(std::string(unescape_cases[i].output),
- UnescapeURLComponent(str, unescape_cases[i].rules));
+ for (const auto unescape_case : kUnescapeCases) {
+ EXPECT_EQ(unescape_case.output,
+ UnescapeURLComponent(unescape_case.input, unescape_case.rules));
}
// Test the NULL character unescaping (which wouldn't work above since those
@@ -228,166 +334,6 @@ TEST(EscapeTest, UnescapeURLComponentASCII) {
EXPECT_EQ(expected, UnescapeURLComponent(input, UnescapeRule::NORMAL));
}
-TEST(EscapeTest, UnescapeURLComponent) {
- const UnescapeURLCase unescape_cases[] = {
- {L"", UnescapeRule::NORMAL, L""},
- {L"%2", UnescapeRule::NORMAL, L"%2"},
- {L"%%%%%%", UnescapeRule::NORMAL, L"%%%%%%"},
- {L"Don't escape anything", UnescapeRule::NORMAL,
- L"Don't escape anything"},
- {L"Invalid %escape %2", UnescapeRule::NORMAL, L"Invalid %escape %2"},
- {L"Some%20random text %25%2dOK", UnescapeRule::NONE,
- L"Some%20random text %25%2dOK"},
- {L"Some%20random text %25%2dOK", UnescapeRule::NORMAL,
- L"Some%20random text %25-OK"},
- {L"Some%20random text %25%E2%80", UnescapeRule::NORMAL,
- L"Some%20random text %25\xE2\x80"},
- {L"Some%20random text %25%E2%80OK", UnescapeRule::NORMAL,
- L"Some%20random text %25\xE2\x80OK"},
- {L"Some%20random text %25%E2%80%84OK", UnescapeRule::NORMAL,
- L"Some%20random text %25\xE2\x80\x84OK"},
-
- // BiDi Control characters should not be unescaped unless explicity told
- // to
- // do so with UnescapeRule::SPOOFING_AND_CONTROL_CHARS
- {L"Some%20random text %25%D8%9COK", UnescapeRule::NORMAL,
- L"Some%20random text %25%D8%9COK"},
- {L"Some%20random text %25%E2%80%8EOK", UnescapeRule::NORMAL,
- L"Some%20random text %25%E2%80%8EOK"},
- {L"Some%20random text %25%E2%80%8FOK", UnescapeRule::NORMAL,
- L"Some%20random text %25%E2%80%8FOK"},
- {L"Some%20random text %25%E2%80%AAOK", UnescapeRule::NORMAL,
- L"Some%20random text %25%E2%80%AAOK"},
- {L"Some%20random text %25%E2%80%ABOK", UnescapeRule::NORMAL,
- L"Some%20random text %25%E2%80%ABOK"},
- {L"Some%20random text %25%E2%80%AEOK", UnescapeRule::NORMAL,
- L"Some%20random text %25%E2%80%AEOK"},
- {L"Some%20random text %25%E2%81%A6OK", UnescapeRule::NORMAL,
- L"Some%20random text %25%E2%81%A6OK"},
- {L"Some%20random text %25%E2%81%A9OK", UnescapeRule::NORMAL,
- L"Some%20random text %25%E2%81%A9OK"},
- // UnescapeRule::SPOOFING_AND_CONTROL_CHARS should unescape BiDi Control
- // characters.
- {L"Some%20random text %25%D8%9COK",
- UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
- L"Some%20random text %25\xD8\x9COK"},
- {L"Some%20random text %25%E2%80%8EOK",
- UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
- L"Some%20random text %25\xE2\x80\x8EOK"},
- {L"Some%20random text %25%E2%80%8FOK",
- UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
- L"Some%20random text %25\xE2\x80\x8FOK"},
- {L"Some%20random text %25%E2%80%AAOK",
- UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
- L"Some%20random text %25\xE2\x80\xAAOK"},
- {L"Some%20random text %25%E2%80%ABOK",
- UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
- L"Some%20random text %25\xE2\x80\xABOK"},
- {L"Some%20random text %25%E2%80%AEOK",
- UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
- L"Some%20random text %25\xE2\x80\xAEOK"},
- {L"Some%20random text %25%E2%81%A6OK",
- UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
- L"Some%20random text %25\xE2\x81\xA6OK"},
- {L"Some%20random text %25%E2%81%A9OK",
- UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
- L"Some%20random text %25\xE2\x81\xA9OK"},
-
- // Certain banned characters should not be unescaped unless explicitly
- // told
- // to do so with UnescapeRule::SPOOFING_AND_CONTROL_CHARS.
- // U+1F50F LOCK WITH INK PEN
- {L"Some%20random text %25%F0%9F%94%8FOK", UnescapeRule::NORMAL,
- L"Some%20random text %25%F0%9F%94%8FOK"},
- // U+1F510 CLOSED LOCK WITH KEY
- {L"Some%20random text %25%F0%9F%94%90OK", UnescapeRule::NORMAL,
- L"Some%20random text %25%F0%9F%94%90OK"},
- // U+1F512 LOCK
- {L"Some%20random text %25%F0%9F%94%92OK", UnescapeRule::NORMAL,
- L"Some%20random text %25%F0%9F%94%92OK"},
- // U+1F513 OPEN LOCK
- {L"Some%20random text %25%F0%9F%94%93OK", UnescapeRule::NORMAL,
- L"Some%20random text %25%F0%9F%94%93OK"},
- // UnescapeRule::SPOOFING_AND_CONTROL_CHARS should unescape banned
- // characters.
- {L"Some%20random text %25%F0%9F%94%8FOK",
- UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
- L"Some%20random text %25\xF0\x9F\x94\x8FOK"},
- {L"Some%20random text %25%F0%9F%94%90OK",
- UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
- L"Some%20random text %25\xF0\x9F\x94\x90OK"},
- {L"Some%20random text %25%F0%9F%94%92OK",
- UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
- L"Some%20random text %25\xF0\x9F\x94\x92OK"},
- {L"Some%20random text %25%F0%9F%94%93OK",
- UnescapeRule::NORMAL | UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
- L"Some%20random text %25\xF0\x9F\x94\x93OK"},
-
- {L"Some%20random text %25%2dOK", UnescapeRule::SPACES,
- L"Some random text %25-OK"},
- {L"Some%20random text %25%2dOK",
- UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS,
- L"Some%20random text %-OK"},
- {L"Some%20random text %25%2dOK",
- UnescapeRule::SPACES |
- UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS,
- L"Some random text %-OK"},
- {L"%A0%B1%C2%D3%E4%F5", UnescapeRule::NORMAL,
- L"\xA0\xB1\xC2\xD3\xE4\xF5"},
- {L"%Aa%Bb%Cc%Dd%Ee%Ff", UnescapeRule::NORMAL,
- L"\xAa\xBb\xCc\xDd\xEe\xFf"},
- // Certain URL-sensitive characters should not be unescaped unless asked.
- {L"Hello%20%13%10world %23# %3F? %3D= %26& %25% %2B+",
- UnescapeRule::SPACES,
- L"Hello %13%10world %23# %3F? %3D= %26& %25% %2B+"},
- {L"Hello%20%13%10world %23# %3F? %3D= %26& %25% %2B+",
- UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS,
- L"Hello%20%13%10world ## ?? == && %% ++"},
- // We can neither escape nor unescape '@' since some websites expect it to
- // be preserved as either '@' or "%40".
- // See http://b/996720 and http://crbug.com/23933 .
- {L"me@my%40example", UnescapeRule::NORMAL, L"me@my%40example"},
- // Control characters.
- {L"%01%02%03%04%05%06%07%08%09 %25",
- UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS,
- L"%01%02%03%04%05%06%07%08%09 %"},
- {L"%01%02%03%04%05%06%07%08%09 %25",
- UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
- L"\x01\x02\x03\x04\x05\x06\x07\x08\x09 %25"},
- {L"Hello%20%13%10%02", UnescapeRule::SPACES, L"Hello %13%10%02"},
- {L"Hello%20%13%10%02", UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
- L"Hello%20\x13\x10\x02"},
- {L"Hello\x9824\x9827", UnescapeRule::SPOOFING_AND_CONTROL_CHARS,
- L"Hello\x9824\x9827"},
- };
-
- for (size_t i = 0; i < arraysize(unescape_cases); i++) {
- base::string16 str(base::WideToUTF16(unescape_cases[i].input));
- EXPECT_EQ(base::WideToUTF16(unescape_cases[i].output),
- UnescapeURLComponent(str, unescape_cases[i].rules));
- }
-
- // Test the NULL character unescaping (which wouldn't work above since those
- // are just char pointers).
- base::string16 input(base::WideToUTF16(L"Null"));
- input.push_back(0); // Also have a NULL in the input.
- input.append(base::WideToUTF16(L"%00%39Test"));
-
- // When we're unescaping NULLs
- base::string16 expected(base::WideToUTF16(L"Null"));
- expected.push_back(0);
- expected.push_back(0);
- expected.append(base::ASCIIToUTF16("9Test"));
- EXPECT_EQ(expected, UnescapeURLComponent(
- input, UnescapeRule::SPOOFING_AND_CONTROL_CHARS));
-
- // When we're not unescaping NULLs.
- expected = base::WideToUTF16(L"Null");
- expected.push_back(0);
- expected.append(base::WideToUTF16(L"%009Test"));
- EXPECT_EQ(expected, UnescapeURLComponent(input, UnescapeRule::NORMAL));
-}
-
TEST(EscapeTest, UnescapeAndDecodeUTF8URLComponent) {
const UnescapeAndDecodeCase unescape_cases[] = {
{ "%",
@@ -450,44 +396,45 @@ TEST(EscapeTest, UnescapeAndDecodeUTF8URLComponent) {
TEST(EscapeTest, AdjustOffset) {
const AdjustOffsetCase adjust_cases[] = {
- {"", 0, 0},
- {"test", 0, 0},
- {"test", 2, 2},
- {"test", 4, 4},
- {"test", std::string::npos, std::string::npos},
- {"%2dtest", 6, 4},
- {"%2dtest", 3, 1},
- {"%2dtest", 2, std::string::npos},
- {"%2dtest", 1, std::string::npos},
- {"%2dtest", 0, 0},
- {"test%2d", 2, 2},
- {"%E4%BD%A0+%E5%A5%BD", 9, 1},
- {"%E4%BD%A0+%E5%A5%BD", 6, std::string::npos},
- {"%E4%BD%A0+%E5%A5%BD", 0, 0},
- {"%E4%BD%A0+%E5%A5%BD", 10, 2},
- {"%E4%BD%A0+%E5%A5%BD", 19, 3},
-
- {"hi%41test%E4%BD%A0+%E5%A5%BD", 18, 8},
- {"hi%41test%E4%BD%A0+%E5%A5%BD", 15, std::string::npos},
- {"hi%41test%E4%BD%A0+%E5%A5%BD", 9, 7},
- {"hi%41test%E4%BD%A0+%E5%A5%BD", 19, 9},
- {"hi%41test%E4%BD%A0+%E5%A5%BD", 28, 10},
- {"hi%41test%E4%BD%A0+%E5%A5%BD", 0, 0},
- {"hi%41test%E4%BD%A0+%E5%A5%BD", 2, 2},
- {"hi%41test%E4%BD%A0+%E5%A5%BD", 3, std::string::npos},
- {"hi%41test%E4%BD%A0+%E5%A5%BD", 5, 3},
-
- {"%E4%BD%A0+%E5%A5%BDhi%41test", 9, 1},
- {"%E4%BD%A0+%E5%A5%BDhi%41test", 6, std::string::npos},
- {"%E4%BD%A0+%E5%A5%BDhi%41test", 0, 0},
- {"%E4%BD%A0+%E5%A5%BDhi%41test", 10, 2},
- {"%E4%BD%A0+%E5%A5%BDhi%41test", 19, 3},
- {"%E4%BD%A0+%E5%A5%BDhi%41test", 21, 5},
- {"%E4%BD%A0+%E5%A5%BDhi%41test", 22, std::string::npos},
- {"%E4%BD%A0+%E5%A5%BDhi%41test", 24, 6},
- {"%E4%BD%A0+%E5%A5%BDhi%41test", 28, 10},
-
- {"%ED%B0%80+%E5%A5%BD", 6, 6}, // not convertable to UTF-8
+ {"", 0, 0},
+ {"test", 0, 0},
+ {"test", 2, 2},
+ {"test", 4, 4},
+ {"test", std::string::npos, std::string::npos},
+ {"%2dtest", 6, 4},
+ {"%2dtest", 3, 1},
+ {"%2dtest", 2, std::string::npos},
+ {"%2dtest", 1, std::string::npos},
+ {"%2dtest", 0, 0},
+ {"test%2d", 2, 2},
+ {"test%2e", 2, 2},
+ {"%E4%BD%A0+%E5%A5%BD", 9, 1},
+ {"%E4%BD%A0+%E5%A5%BD", 6, std::string::npos},
+ {"%E4%BD%A0+%E5%A5%BD", 0, 0},
+ {"%E4%BD%A0+%E5%A5%BD", 10, 2},
+ {"%E4%BD%A0+%E5%A5%BD", 19, 3},
+
+ {"hi%41test%E4%BD%A0+%E5%A5%BD", 18, 8},
+ {"hi%41test%E4%BD%A0+%E5%A5%BD", 15, std::string::npos},
+ {"hi%41test%E4%BD%A0+%E5%A5%BD", 9, 7},
+ {"hi%41test%E4%BD%A0+%E5%A5%BD", 19, 9},
+ {"hi%41test%E4%BD%A0+%E5%A5%BD", 28, 10},
+ {"hi%41test%E4%BD%A0+%E5%A5%BD", 0, 0},
+ {"hi%41test%E4%BD%A0+%E5%A5%BD", 2, 2},
+ {"hi%41test%E4%BD%A0+%E5%A5%BD", 3, std::string::npos},
+ {"hi%41test%E4%BD%A0+%E5%A5%BD", 5, 3},
+
+ {"%E4%BD%A0+%E5%A5%BDhi%41test", 9, 1},
+ {"%E4%BD%A0+%E5%A5%BDhi%41test", 6, std::string::npos},
+ {"%E4%BD%A0+%E5%A5%BDhi%41test", 0, 0},
+ {"%E4%BD%A0+%E5%A5%BDhi%41test", 10, 2},
+ {"%E4%BD%A0+%E5%A5%BDhi%41test", 19, 3},
+ {"%E4%BD%A0+%E5%A5%BDhi%41test", 21, 5},
+ {"%E4%BD%A0+%E5%A5%BDhi%41test", 22, std::string::npos},
+ {"%E4%BD%A0+%E5%A5%BDhi%41test", 24, 6},
+ {"%E4%BD%A0+%E5%A5%BDhi%41test", 28, 10},
+
+ {"%ED%B0%80+%E5%A5%BD", 6, 6}, // not convertable to UTF-8
};
for (size_t i = 0; i < arraysize(adjust_cases); i++) {
diff --git a/chromium/net/base/file_stream_context.cc b/chromium/net/base/file_stream_context.cc
index ecb497b0345..75dcfb97d2a 100644
--- a/chromium/net/base/file_stream_context.cc
+++ b/chromium/net/base/file_stream_context.cc
@@ -6,7 +6,6 @@
#include <utility>
-#include "base/debug/alias.h"
#include "base/files/file_path.h"
#include "base/location.h"
#include "base/task_runner.h"
@@ -82,7 +81,7 @@ void FileStream::Context::Orphan() {
void FileStream::Context::Open(const base::FilePath& path,
int open_flags,
CompletionOnceCallback callback) {
- CheckNoAsyncInProgress();
+ DCHECK(!async_in_progress_);
bool posted = base::PostTaskAndReplyWithResult(
task_runner_.get(), FROM_HERE,
@@ -92,12 +91,12 @@ void FileStream::Context::Open(const base::FilePath& path,
std::move(callback)));
DCHECK(posted);
- last_operation_ = OPEN;
async_in_progress_ = true;
}
void FileStream::Context::Close(CompletionOnceCallback callback) {
- CheckNoAsyncInProgress();
+ DCHECK(!async_in_progress_);
+
bool posted = base::PostTaskAndReplyWithResult(
task_runner_.get(), FROM_HERE,
base::BindOnce(&Context::CloseFileImpl, base::Unretained(this)),
@@ -105,13 +104,12 @@ void FileStream::Context::Close(CompletionOnceCallback callback) {
IntToInt64(std::move(callback))));
DCHECK(posted);
- last_operation_ = CLOSE;
async_in_progress_ = true;
}
void FileStream::Context::Seek(int64_t offset,
Int64CompletionOnceCallback callback) {
- CheckNoAsyncInProgress();
+ DCHECK(!async_in_progress_);
bool posted = base::PostTaskAndReplyWithResult(
task_runner_.get(), FROM_HERE,
@@ -120,14 +118,11 @@ void FileStream::Context::Seek(int64_t offset,
std::move(callback)));
DCHECK(posted);
- last_operation_ = SEEK;
async_in_progress_ = true;
}
void FileStream::Context::GetFileInfo(base::File::Info* file_info,
CompletionOnceCallback callback) {
- CheckNoAsyncInProgress();
-
base::PostTaskAndReplyWithResult(
task_runner_.get(), FROM_HERE,
base::BindOnce(&Context::GetFileInfoImpl, base::Unretained(this),
@@ -139,7 +134,7 @@ void FileStream::Context::GetFileInfo(base::File::Info* file_info,
}
void FileStream::Context::Flush(CompletionOnceCallback callback) {
- CheckNoAsyncInProgress();
+ DCHECK(!async_in_progress_);
bool posted = base::PostTaskAndReplyWithResult(
task_runner_.get(), FROM_HERE,
@@ -148,7 +143,6 @@ void FileStream::Context::Flush(CompletionOnceCallback callback) {
IntToInt64(std::move(callback))));
DCHECK(posted);
- last_operation_ = FLUSH;
async_in_progress_ = true;
}
@@ -156,16 +150,6 @@ bool FileStream::Context::IsOpen() const {
return file_.IsValid();
}
-void FileStream::Context::CheckNoAsyncInProgress() const {
- if (!async_in_progress_)
- return;
- LastOperation state = last_operation_;
- base::debug::Alias(&state);
- // TODO(xunjieli): Once https://crbug.com/732321 is fixed, use
- // DCHECK(!async_in_progress_) directly at call places.
- CHECK(!async_in_progress_);
-}
-
FileStream::Context::OpenResult FileStream::Context::OpenFileImpl(
const base::FilePath& path, int open_flags) {
#if defined(OS_POSIX)
@@ -230,10 +214,7 @@ void FileStream::Context::OnOpenCompleted(CompletionOnceCallback callback,
}
void FileStream::Context::CloseAndDelete() {
- // TODO(ananta)
- // Replace this CHECK with a DCHECK once we figure out the root cause of
- // http://crbug.com/455066
- CheckNoAsyncInProgress();
+ DCHECK(!async_in_progress_);
if (file_.IsValid()) {
bool posted = task_runner_.get()->PostTask(
@@ -256,7 +237,6 @@ void FileStream::Context::OnAsyncCompleted(Int64CompletionOnceCallback callback,
// should be reset before Close() because it shouldn't run if any async
// operation is in progress.
async_in_progress_ = false;
- last_operation_ = NONE;
if (orphaned_) {
CloseAndDelete();
} else {
diff --git a/chromium/net/base/file_stream_context.h b/chromium/net/base/file_stream_context.h
index 7a34aad19f8..46f0ce36549 100644
--- a/chromium/net/base/file_stream_context.h
+++ b/chromium/net/base/file_stream_context.h
@@ -32,7 +32,7 @@
#include "base/files/file.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_pump_for_io.h"
#include "base/single_thread_task_runner.h"
#include "base/task_runner.h"
#include "net/base/completion_once_callback.h"
@@ -51,7 +51,7 @@ namespace net {
class IOBuffer;
#if defined(OS_WIN)
-class FileStream::Context : public base::MessageLoopForIO::IOHandler {
+class FileStream::Context : public base::MessagePumpForIO::IOHandler {
#elif defined(OS_POSIX)
class FileStream::Context {
#endif
@@ -124,27 +124,6 @@ class FileStream::Context {
DISALLOW_COPY_AND_ASSIGN(OpenResult);
};
- // TODO(xunjieli): Remove after crbug.com/732321 is fixed.
- enum LastOperation {
- // FileStream has a pending Open().
- OPEN,
- // FileStream has a pending Write().
- WRITE,
- // FileStream has a pending Read().
- READ,
- // FileStream has a pending Seek().
- SEEK,
- // FileStream has a pending Flush().
- FLUSH,
- // FileStream has a pending Close().
- CLOSE,
- // FileStream doesn't have any pending operation.
- NONE
- };
-
- // TODO(xunjieli): Remove after crbug.com/732321 is fixed.
- void CheckNoAsyncInProgress() const;
-
////////////////////////////////////////////////////////////////////////////
// Platform-independent methods implemented in file_stream_context.cc.
////////////////////////////////////////////////////////////////////////////
@@ -181,8 +160,8 @@ class FileStream::Context {
#if defined(OS_WIN)
void IOCompletionIsPending(CompletionOnceCallback callback, IOBuffer* buf);
- // Implementation of MessageLoopForIO::IOHandler.
- void OnIOCompleted(base::MessageLoopForIO::IOContext* context,
+ // Implementation of MessagePumpForIO::IOHandler.
+ void OnIOCompleted(base::MessagePumpForIO::IOContext* context,
DWORD bytes_read,
DWORD error) override;
@@ -239,14 +218,11 @@ class FileStream::Context {
base::File file_;
bool async_in_progress_;
- // TODO(xunjieli): Remove after crbug.com/732321 is fixed.
- LastOperation last_operation_;
-
bool orphaned_;
scoped_refptr<base::TaskRunner> task_runner_;
#if defined(OS_WIN)
- base::MessageLoopForIO::IOContext io_context_;
+ base::MessagePumpForIO::IOContext io_context_;
CompletionOnceCallback callback_;
scoped_refptr<IOBuffer> in_flight_buf_;
// This flag is set to true when we receive a Read request which is queued to
diff --git a/chromium/net/base/file_stream_context_posix.cc b/chromium/net/base/file_stream_context_posix.cc
index 1880b95a529..b15c6511aca 100644
--- a/chromium/net/base/file_stream_context_posix.cc
+++ b/chromium/net/base/file_stream_context_posix.cc
@@ -31,7 +31,6 @@ FileStream::Context::Context(base::File file,
const scoped_refptr<base::TaskRunner>& task_runner)
: file_(std::move(file)),
async_in_progress_(false),
- last_operation_(NONE),
orphaned_(false),
task_runner_(task_runner) {}
@@ -40,7 +39,7 @@ FileStream::Context::~Context() = default;
int FileStream::Context::Read(IOBuffer* in_buf,
int buf_len,
CompletionOnceCallback callback) {
- CheckNoAsyncInProgress();
+ DCHECK(!async_in_progress_);
scoped_refptr<IOBuffer> buf = in_buf;
const bool posted = base::PostTaskAndReplyWithResult(
@@ -52,14 +51,13 @@ int FileStream::Context::Read(IOBuffer* in_buf,
DCHECK(posted);
async_in_progress_ = true;
- last_operation_ = READ;
return ERR_IO_PENDING;
}
int FileStream::Context::Write(IOBuffer* in_buf,
int buf_len,
CompletionOnceCallback callback) {
- CheckNoAsyncInProgress();
+ DCHECK(!async_in_progress_);
scoped_refptr<IOBuffer> buf = in_buf;
const bool posted = base::PostTaskAndReplyWithResult(
@@ -71,7 +69,6 @@ int FileStream::Context::Write(IOBuffer* in_buf,
DCHECK(posted);
async_in_progress_ = true;
- last_operation_ = WRITE;
return ERR_IO_PENDING;
}
diff --git a/chromium/net/base/file_stream_context_win.cc b/chromium/net/base/file_stream_context_win.cc
index cf4947fda5f..61118ad1f28 100644
--- a/chromium/net/base/file_stream_context_win.cc
+++ b/chromium/net/base/file_stream_context_win.cc
@@ -11,6 +11,7 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_pump_for_io.h"
#include "base/single_thread_task_runner.h"
#include "base/task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -38,7 +39,6 @@ void IncrementOffset(OVERLAPPED* overlapped, DWORD count) {
FileStream::Context::Context(const scoped_refptr<base::TaskRunner>& task_runner)
: async_in_progress_(false),
- last_operation_(NONE),
orphaned_(false),
task_runner_(task_runner),
async_read_initiated_(false),
@@ -50,7 +50,6 @@ FileStream::Context::Context(base::File file,
const scoped_refptr<base::TaskRunner>& task_runner)
: file_(std::move(file)),
async_in_progress_(false),
- last_operation_(NONE),
orphaned_(false),
task_runner_(task_runner),
async_read_initiated_(false),
@@ -69,13 +68,12 @@ FileStream::Context::~Context() {
int FileStream::Context::Read(IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback) {
- CheckNoAsyncInProgress();
+ DCHECK(!async_in_progress_);
DCHECK(!async_read_initiated_);
DCHECK(!async_read_completed_);
DCHECK(!io_complete_for_read_received_);
- last_operation_ = READ;
IOCompletionIsPending(std::move(callback), buf);
async_read_initiated_ = true;
@@ -92,9 +90,8 @@ int FileStream::Context::Read(IOBuffer* buf,
int FileStream::Context::Write(IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback) {
- CheckNoAsyncInProgress();
+ DCHECK(!async_in_progress_);
- last_operation_ = WRITE;
result_ = 0;
DWORD bytes_written = 0;
@@ -135,17 +132,15 @@ void FileStream::Context::IOCompletionIsPending(CompletionOnceCallback callback,
}
void FileStream::Context::OnIOCompleted(
- base::MessageLoopForIO::IOContext* context,
+ base::MessagePumpForIO::IOContext* context,
DWORD bytes_read,
DWORD error) {
DCHECK_EQ(&io_context_, context);
DCHECK(!callback_.is_null());
DCHECK(async_in_progress_);
- if (!async_read_initiated_) {
- last_operation_ = NONE;
+ if (!async_read_initiated_)
async_in_progress_ = false;
- }
if (orphaned_) {
io_complete_for_read_received_ = true;
@@ -185,7 +180,6 @@ void FileStream::Context::InvokeUserCallback() {
async_read_initiated_ = false;
io_complete_for_read_received_ = false;
async_read_completed_ = false;
- last_operation_ = NONE;
async_in_progress_ = false;
}
scoped_refptr<IOBuffer> temp_buf = in_flight_buf_;
@@ -194,7 +188,6 @@ void FileStream::Context::InvokeUserCallback() {
}
void FileStream::Context::DeleteOrphanedContext() {
- last_operation_ = NONE;
async_in_progress_ = false;
callback_.Reset();
in_flight_buf_ = NULL;
diff --git a/chromium/net/base/filename_util_unittest.cc b/chromium/net/base/filename_util_unittest.cc
index a38c110396d..5b40aeeddcd 100644
--- a/chromium/net/base/filename_util_unittest.cc
+++ b/chromium/net/base/filename_util_unittest.cc
@@ -9,6 +9,8 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_file_util.h"
+#include "build/build_config.h"
+#include "net/base/mime_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -283,507 +285,217 @@ TEST(FilenameUtilTest, FileURLConversion) {
EXPECT_FALSE(FileURLToFilePath(GURL("filefoobar"), &output));
}
-#if defined(OS_WIN)
-#define JPEG_EXT L".jpg"
-#define HTML_EXT L".htm"
-#else
-#define JPEG_EXT L".jpeg"
-#define HTML_EXT L".html"
-#endif
-#define TXT_EXT L".txt"
-#define TAR_EXT L".tar"
-
TEST(FilenameUtilTest, GenerateSafeFileName) {
const struct {
+ int line;
const char* mime_type;
- const base::FilePath::CharType* filename;
- const base::FilePath::CharType* expected_filename;
+ const char* filename;
+ const char* expected_filename;
} safe_tests[] = {
-#if defined(OS_WIN)
- {"text/html",
- FILE_PATH_LITERAL("C:\\foo\\bar.htm"),
- FILE_PATH_LITERAL("C:\\foo\\bar.htm")},
- {"text/html",
- FILE_PATH_LITERAL("C:\\foo\\bar.html"),
- FILE_PATH_LITERAL("C:\\foo\\bar.html")},
- {"text/html",
- FILE_PATH_LITERAL("C:\\foo\\bar"),
- FILE_PATH_LITERAL("C:\\foo\\bar.htm")},
- {"image/png",
- FILE_PATH_LITERAL("C:\\bar.html"),
- FILE_PATH_LITERAL("C:\\bar.html")},
- {"image/png",
- FILE_PATH_LITERAL("C:\\bar"),
- FILE_PATH_LITERAL("C:\\bar.png")},
- {"text/html",
- FILE_PATH_LITERAL("C:\\foo\\bar.exe"),
- FILE_PATH_LITERAL("C:\\foo\\bar.exe")},
- {"image/gif",
- FILE_PATH_LITERAL("C:\\foo\\bar.exe"),
- FILE_PATH_LITERAL("C:\\foo\\bar.exe")},
- {"text/html",
- FILE_PATH_LITERAL("C:\\foo\\google.com"),
- FILE_PATH_LITERAL("C:\\foo\\google.com")},
- {"text/html",
- FILE_PATH_LITERAL("C:\\foo\\con.htm"),
- FILE_PATH_LITERAL("C:\\foo\\_con.htm")},
- {"text/html",
- FILE_PATH_LITERAL("C:\\foo\\con"),
- FILE_PATH_LITERAL("C:\\foo\\_con.htm")},
- {"text/html",
- FILE_PATH_LITERAL("C:\\foo\\harmless.{not-really-this-may-be-a-guid}"),
- FILE_PATH_LITERAL("C:\\foo\\harmless.download")},
- {"text/html",
- FILE_PATH_LITERAL("C:\\foo\\harmless.local"),
- FILE_PATH_LITERAL("C:\\foo\\harmless.download")},
- {"text/html",
- FILE_PATH_LITERAL("C:\\foo\\harmless.lnk"),
- FILE_PATH_LITERAL("C:\\foo\\harmless.download")},
- {"text/html",
- FILE_PATH_LITERAL("C:\\foo\\harmless.{mismatched-"),
- FILE_PATH_LITERAL("C:\\foo\\harmless.{mismatched-")},
- // Allow extension synonyms.
- {"image/jpeg",
- FILE_PATH_LITERAL("C:\\foo\\bar.jpg"),
- FILE_PATH_LITERAL("C:\\foo\\bar.jpg")},
- {"image/jpeg",
- FILE_PATH_LITERAL("C:\\foo\\bar.jpeg"),
- FILE_PATH_LITERAL("C:\\foo\\bar.jpeg")},
-#else // !defined(OS_WIN)
- {"text/html",
- FILE_PATH_LITERAL("/foo/bar.htm"),
- FILE_PATH_LITERAL("/foo/bar.htm")},
- {"text/html",
- FILE_PATH_LITERAL("/foo/bar.html"),
- FILE_PATH_LITERAL("/foo/bar.html")},
- {"text/html",
- FILE_PATH_LITERAL("/foo/bar"),
- FILE_PATH_LITERAL("/foo/bar.html")},
- {"image/png",
- FILE_PATH_LITERAL("/bar.html"),
- FILE_PATH_LITERAL("/bar.html")},
- {"image/png", FILE_PATH_LITERAL("/bar"), FILE_PATH_LITERAL("/bar.png")},
- {"image/gif",
- FILE_PATH_LITERAL("/foo/bar.exe"),
- FILE_PATH_LITERAL("/foo/bar.exe")},
- {"text/html",
- FILE_PATH_LITERAL("/foo/google.com"),
- FILE_PATH_LITERAL("/foo/google.com")},
- {"text/html",
- FILE_PATH_LITERAL("/foo/con.htm"),
- FILE_PATH_LITERAL("/foo/con.htm")},
- {"text/html",
- FILE_PATH_LITERAL("/foo/con"),
- FILE_PATH_LITERAL("/foo/con.html")},
+ {__LINE__, "text/html", "bar.htm", "bar.htm"},
+ {__LINE__, "text/html", "bar.html", "bar.html"},
+ {__LINE__, "application/x-chrome-extension", "bar", "bar.crx"},
+ {__LINE__, "image/png", "bar.html", "bar.html"},
+ {__LINE__, "text/html", "bar.exe", "bar.exe"},
+ {__LINE__, "image/gif", "bar.exe", "bar.exe"},
+ {__LINE__, "text/html", "google.com", "google.com"},
// Allow extension synonyms.
- {"image/jpeg",
- FILE_PATH_LITERAL("/bar.jpg"),
- FILE_PATH_LITERAL("/bar.jpg")},
- {"image/jpeg",
- FILE_PATH_LITERAL("/bar.jpeg"),
- FILE_PATH_LITERAL("/bar.jpeg")},
+ {__LINE__, "image/jpeg", "bar.jpg", "bar.jpg"},
+ {__LINE__, "image/jpeg", "bar.jpeg", "bar.jpeg"},
+
+#if defined(OS_WIN)
+ // Device names
+ {__LINE__, "text/html", "con.htm", "_con.htm"},
+ {__LINE__, "text/html", "lpt1.htm", "_lpt1.htm"},
+ {__LINE__, "application/x-chrome-extension", "con", "_con.crx"},
+
+ // Looks like foo.{GUID} which get treated as namespace mounts on Windows.
+ {__LINE__, "text/html", "harmless.{not-really-this-may-be-a-guid}",
+ "harmless.download"},
+ {__LINE__, "text/html", "harmless.{mismatched-", "harmless.{mismatched-"},
+
+ // Dangerous extensions
+ {__LINE__, "text/html", "harmless.local", "harmless.download"},
+ {__LINE__, "text/html", "harmless.lnk", "harmless.download"},
+#else // OS_WIN
+ // On Posix, none of the above set is particularly dangerous.
+ {__LINE__, "text/html", "con.htm", "con.htm"},
+ {__LINE__, "text/html", "lpt1.htm", "lpt1.htm"},
+ {__LINE__, "application/x-chrome-extension", "con", "con.crx"},
+ {__LINE__, "text/html", "harmless.{not-really-this-may-be-a-guid}",
+ "harmless.{not-really-this-may-be-a-guid}"},
+ {__LINE__, "text/html", "harmless.{mismatched-", "harmless.{mismatched-"},
+ {__LINE__, "text/html", "harmless.local", "harmless.local"},
+ {__LINE__, "text/html", "harmless.lnk", "harmless.lnk"},
#endif // !defined(OS_WIN)
};
- for (size_t i = 0; i < arraysize(safe_tests); ++i) {
- base::FilePath file_path(safe_tests[i].filename);
- GenerateSafeFileName(safe_tests[i].mime_type, false, &file_path);
- EXPECT_EQ(safe_tests[i].expected_filename, file_path.value())
- << "Iteration " << i;
+#if defined(OS_WIN)
+ base::FilePath base_path(L"C:\\foo");
+#else
+ base::FilePath base_path("/foo");
+#endif
+
+ for (const auto& test : safe_tests) {
+ base::FilePath file_path = base_path.AppendASCII(test.filename);
+ base::FilePath expected_path =
+ base_path.AppendASCII(test.expected_filename);
+ GenerateSafeFileName(test.mime_type, false, &file_path);
+ EXPECT_EQ(expected_path.value(), file_path.value())
+ << "Test case at line " << test.line;
}
}
+TEST(FilenameUtilTest, GenerateFileName_Assumptions) {
+ base::FilePath::StringType extension;
+ EXPECT_TRUE(GetPreferredExtensionForMimeType("application/x-chrome-extension",
+ &extension));
+ EXPECT_EQ(base::FilePath::StringType(FILE_PATH_LITERAL("crx")), extension);
+}
+
TEST(FilenameUtilTest, GenerateFileName) {
// Tests whether the correct filename is selected from the the given
// parameters and that Content-Disposition headers are properly
// handled including failovers when the header is malformed.
const GenerateFilenameCase selection_tests[] = {
- {__LINE__,
- "http://www.google.com/",
- "attachment; filename=test.html",
- "",
- "",
- "",
- L"",
- L"test.html"},
- {__LINE__,
- "http://www.google.com/",
- "attachment; filename=\"test.html\"",
- "",
- "",
- "",
- L"",
- L"test.html"},
- {__LINE__,
- "http://www.google.com/",
- "attachment; filename= \"test.html\"",
- "",
- "",
- "",
- L"",
- L"test.html"},
- {__LINE__,
- "http://www.google.com/",
- "attachment; filename = \"test.html\"",
- "",
- "",
- "",
- L"",
- L"test.html"},
- {// filename is whitespace. Should failover to URL host
- __LINE__,
- "http://www.google.com/",
- "attachment; filename= ",
- "",
- "",
- "",
- L"",
- L"www.google.com"},
- {// No filename.
- __LINE__,
- "http://www.google.com/path/test.html",
- "attachment",
- "",
- "",
- "",
- L"",
- L"test.html"},
- {// Ditto
- __LINE__,
- "http://www.google.com/path/test.html",
- "attachment;",
- "",
- "",
- "",
- L"",
- L"test.html"},
- {// No C-D
- __LINE__,
- "http://www.google.com/",
- "",
- "",
- "",
- "",
- L"",
- L"www.google.com"},
- {__LINE__,
- "http://www.google.com/test.html",
- "",
- "",
- "",
- "",
- L"",
- L"test.html"},
- {// Now that we use src/url's ExtractFileName, this case falls back to
- // the hostname. If this behavior is not desirable, we'd better change
- // ExtractFileName (in url_parse.cc).
- __LINE__,
- "http://www.google.com/path/",
- "",
- "",
- "",
- "",
- L"",
- L"www.google.com"},
- {__LINE__, "http://www.google.com/path", "", "", "", "", L"", L"path"},
- {__LINE__, "file:///", "", "", "", "", L"", L"download"},
- {__LINE__, "file:///path/testfile", "", "", "", "", L"", L"testfile"},
- {__LINE__, "non-standard-scheme:", "", "", "", "", L"", L"download"},
- {// C-D should override default
- __LINE__,
- "http://www.google.com/",
- "attachment; filename =\"test.html\"",
- "",
- "",
- "",
- L"download",
- L"test.html"},
- {// But the URL shouldn't
- __LINE__,
- "http://www.google.com/",
- "",
- "",
- "",
- "",
- L"download",
- L"download"},
- {__LINE__,
- "http://www.google.com/",
- "attachment; filename=\"../test.html\"",
- "",
- "",
- "",
- L"",
- L"_test.html"},
- {__LINE__,
- "http://www.google.com/",
- "attachment; filename=\"..\\test.html\"",
- "",
- "",
- "",
- L"",
- L"test.html"},
- {__LINE__,
- "http://www.google.com/",
- "attachment; filename=\"..\\\\test.html\"",
- "",
- "",
- "",
- L"",
- L"_test.html"},
- {// Filename disappears after leading and trailing periods are removed.
- __LINE__,
- "http://www.google.com/",
- "attachment; filename=\"..\"",
- "",
- "",
- "",
- L"default",
- L"default"},
- {// C-D specified filename disappears. Failover to final filename.
- __LINE__,
- "http://www.google.com/test.html",
- "attachment; filename=\"..\"",
- "",
- "",
- "",
- L"default",
- L"default"},
- // Below is a small subset of cases taken from HttpContentDisposition tests.
- {__LINE__,
- "http://www.google.com/",
- "attachment; filename=\"%EC%98%88%EC%88%A0%20"
- "%EC%98%88%EC%88%A0.jpg\"",
- "",
- "",
- "",
- L"",
- L"\uc608\uc220 \uc608\uc220.jpg"},
- {__LINE__,
- "http://www.google.com/%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg",
- "",
- "",
- "",
- "",
- L"download",
- L"\uc608\uc220 \uc608\uc220.jpg"},
- {__LINE__,
- "http://www.google.com/",
- "attachment;",
- "",
- "",
- "",
- L"\uB2E4\uC6B4\uB85C\uB4DC",
- L"\uB2E4\uC6B4\uB85C\uB4DC"},
- {__LINE__,
- "http://www.google.com/",
- "attachment; filename=\"=?EUC-JP?Q?=B7=DD=BD="
- "D13=2Epng?=\"",
- "",
- "",
- "",
- L"download",
- L"\u82b8\u88533.png"},
- {__LINE__,
- "http://www.example.com/images?id=3",
- "attachment; filename=caf\xc3\xa9.png",
- "iso-8859-1",
- "",
- "",
- L"",
- L"caf\u00e9.png"},
- {__LINE__,
- "http://www.example.com/images?id=3",
- "attachment; filename=caf\xe5.png",
- "windows-1253",
- "",
- "",
- L"",
- L"caf\u03b5.png"},
- {// Invalid C-D header. Name value is skipped now.
- __LINE__,
- "http://www.example.com/file?id=3",
- "attachment; name=\xcf\xc2\xd4\xd8.zip",
- "GBK",
- "",
- "",
- L"",
- L"file"},
- {// Invalid C-D header. Extracts filename from url.
- __LINE__,
- "http://www.google.com/test.html",
- "attachment; filename==?iiso88591?Q?caf=EG?=",
- "",
- "",
- "",
- L"",
- L"test.html"},
- // about: and data: URLs
- {__LINE__, "about:chrome", "", "", "", "", L"", L"download"},
- {__LINE__, "data:,looks/like/a.path", "", "", "", "", L"", L"download"},
- {__LINE__,
- "data:text/plain;base64,VG8gYmUgb3Igbm90IHRvIGJlLg=",
- "",
- "",
- "",
- "",
- L"",
- L"download"},
- {__LINE__,
- "data:,looks/like/a.path",
- "",
- "",
- "",
- "",
- L"default_filename_is_given",
- L"default_filename_is_given"},
- {__LINE__,
- "data:,looks/like/a.path",
- "",
- "",
- "",
- "",
- L"\u65e5\u672c\u8a9e", // Japanese Kanji.
- L"\u65e5\u672c\u8a9e"},
- {// The filename encoding is specified by the referrer charset.
- __LINE__,
- "http://example.com/V%FDvojov%E1%20psychologie.doc",
- "",
- "iso-8859-1",
- "",
- "",
- L"",
- L"V\u00fdvojov\u00e1 psychologie.doc"},
- {// Suggested filename takes precedence over URL
- __LINE__,
- "http://www.google.com/test",
- "",
- "",
- "suggested",
- "",
- L"",
- L"suggested"},
- {// The content-disposition has higher precedence over the suggested name.
- __LINE__,
- "http://www.google.com/test",
- "attachment; filename=test.html",
- "",
- "suggested",
- "",
- L"",
- L"test.html"},
- {__LINE__,
- "http://www.google.com/test",
- "attachment; filename=test",
- "utf-8",
- "",
- "image/png",
- L"",
- L"test"},
-#if 0
- { // The filename encoding doesn't match the referrer charset, the system
- // charset, or UTF-8.
- // TODO(jshin): we need to handle this case.
- __LINE__,
- "http://example.com/V%FDvojov%E1%20psychologie.doc",
- "",
- "utf-8",
- "",
- "",
- L"",
- L"V\u00fdvojov\u00e1 psychologie.doc",
- },
-#endif
- // Raw 8bit characters in C-D
- {__LINE__,
- "http://www.example.com/images?id=3",
- "attachment; filename=caf\xc3\xa9.png",
- "iso-8859-1",
- "",
- "image/png",
- L"",
- L"caf\u00e9.png"},
- {__LINE__,
- "http://www.example.com/images?id=3",
- "attachment; filename=caf\xe5.png",
- "windows-1253",
- "",
- "image/png",
- L"",
- L"caf\u03b5.png"},
- {// No 'filename' keyword in the disposition, use the URL
- __LINE__,
- "http://www.evil.com/my_download.txt",
- "a_file_name.txt",
- "",
- "",
- "text/plain",
- L"download",
- L"my_download.txt"},
- {// Spaces in the disposition file name
- __LINE__,
- "http://www.frontpagehacker.com/a_download.exe",
- "filename=My Downloaded File.exe",
- "",
- "",
- "application/octet-stream",
- L"download",
- L"My Downloaded File.exe"},
- {// % encoded
- __LINE__,
- "http://www.examples.com/",
- "attachment; "
- "filename=\"%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg\"",
- "",
- "",
- "image/jpeg",
- L"download",
- L"\uc608\uc220 \uc608\uc220.jpg"},
- {// Invalid C-D header. Name value is skipped now.
- __LINE__,
- "http://www.examples.com/q.cgi?id=abc",
- "attachment; name=abc de.pdf",
- "",
- "",
- "application/octet-stream",
- L"download",
- L"q.cgi"},
- {__LINE__,
- "http://www.example.com/path",
- "filename=\"=?EUC-JP?Q?=B7=DD=BD=D13=2Epng?=\"",
- "",
- "",
- "image/png",
- L"download",
- L"\x82b8\x8853"
- L"3.png"},
- {// The following two have invalid CD headers and filenames come from the
- // URL.
- __LINE__,
- "http://www.example.com/test%20123",
- "attachment; filename==?iiso88591?Q?caf=EG?=",
- "",
- "",
- "image/jpeg",
- L"download",
- L"test 123" JPEG_EXT},
- {__LINE__,
- "http://www.google.com/%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg",
- "malformed_disposition",
- "",
- "",
- "image/jpeg",
- L"download",
- L"\uc608\uc220 \uc608\uc220.jpg"},
- {// Invalid C-D. No filename from URL. Falls back to 'download'.
- __LINE__,
- "http://www.google.com/path1/path2/",
- "attachment; filename==?iso88591?Q?caf=E3?",
- "",
- "",
- "image/jpeg",
- L"download",
- L"download" JPEG_EXT},
+ {// Picks the filename from the C-D header.
+ __LINE__, "http://www.google.com/", "attachment; filename=test.html", "",
+ "", "", L"", L"test.html"},
+ {// Ditto. The C-D header uses a quoted string.
+ __LINE__, "http://www.google.com/", "attachment; filename=\"test.html\"",
+ "", "", "", L"", L"test.html"},
+ {// Ditto. Extra whilespace after the '=' sign.
+ __LINE__, "http://www.google.com/",
+ "attachment; filename= \"test.html\"", "", "", "", L"", L"test.html"},
+ {// Ditto. Whitespace before and after '=' sign.
+ __LINE__, "http://www.google.com/",
+ "attachment; filename = \"test.html\"", "", "", "", L"",
+ L"test.html"},
+ {// Filename is whitespace. Should failover to URL host
+ __LINE__, "http://www.google.com/", "attachment; filename= ", "", "",
+ "", L"", L"www.google.com"},
+ {// No filename.
+ __LINE__, "http://www.google.com/path/test.html", "attachment", "", "",
+ "", L"", L"test.html"},
+ {// Ditto
+ __LINE__, "http://www.google.com/path/test.html", "attachment;", "", "",
+ "", L"", L"test.html"},
+ {// No C-D, and no URL path.
+ __LINE__, "http://www.google.com/", "", "", "", "", L"",
+ L"www.google.com"},
+ {// No C-D. URL has a path.
+ __LINE__, "http://www.google.com/test.html", "", "", "", "", L"",
+ L"test.html"},
+ {// No C-D. URL's path ends in a slash which results in an empty final
+ // component.
+ __LINE__, "http://www.google.com/path/", "", "", "", "", L"",
+ L"www.google.com"},
+ {// No C-D. URL has a path, but the path has no extension.
+ __LINE__, "http://www.google.com/path", "", "", "", "", L"", L"path"},
+ {// No C-D. URL gives no filename hints.
+ __LINE__, "file:///", "", "", "", "", L"", L"download"},
+ {// file:// URL.
+ __LINE__, "file:///path/testfile", "", "", "", "", L"", L"testfile"},
+ {// Unknown scheme.
+ __LINE__, "non-standard-scheme:", "", "", "", "", L"", L"download"},
+ {// C-D overrides default
+ __LINE__, "http://www.google.com/",
+ "attachment; filename =\"test.html\"", "", "", "", L"download",
+ L"test.html"},
+ {// But the URL doesn't
+ __LINE__, "http://www.google.com/", "", "", "", "", L"download",
+ L"download"},
+ // Below is a small subset of cases taken from HttpContentDisposition
+ // tests.
+ {__LINE__, "http://www.google.com/",
+ "attachment; filename=\"%EC%98%88%EC%88%A0%20"
+ "%EC%98%88%EC%88%A0.jpg\"",
+ "", "", "", L"", L"\uc608\uc220 \uc608\uc220.jpg"},
+ {__LINE__,
+ "http://www.google.com/%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg", "",
+ "", "", "", L"download", L"\uc608\uc220 \uc608\uc220.jpg"},
+ {__LINE__, "http://www.google.com/", "attachment;", "", "", "",
+ L"\uB2E4\uC6B4\uB85C\uB4DC", L"\uB2E4\uC6B4\uB85C\uB4DC"},
+ {__LINE__, "http://www.google.com/",
+ "attachment; filename=\"=?EUC-JP?Q?=B7=DD=BD="
+ "D13=2Epng?=\"",
+ "", "", "", L"download", L"\u82b8\u88533.png"},
+ {__LINE__, "http://www.example.com/images?id=3",
+ "attachment; filename=caf\xc3\xa9.png", "iso-8859-1", "", "", L"",
+ L"caf\u00e9.png"},
+ {__LINE__, "http://www.example.com/images?id=3",
+ "attachment; filename=caf\xe5.png", "windows-1253", "", "", L"",
+ L"caf\u03b5.png"},
+ {// Invalid C-D header. Name value is skipped now.
+ __LINE__, "http://www.example.com/file?id=3",
+ "attachment; name=\xcf\xc2\xd4\xd8.zip", "GBK", "", "", L"", L"file"},
+ {// Invalid C-D header. Extracts filename from url.
+ __LINE__, "http://www.google.com/test.html",
+ "attachment; filename==?iiso88591?Q?caf=EG?=", "", "", "", L"",
+ L"test.html"},
+ // about: and data: URLs
+ {__LINE__, "about:chrome", "", "", "", "", L"", L"download"},
+ {__LINE__, "data:,looks/like/a.path", "", "", "", "", L"", L"download"},
+ {__LINE__, "data:text/plain;base64,VG8gYmUgb3Igbm90IHRvIGJlLg=", "", "",
+ "", "", L"", L"download"},
+ {__LINE__, "data:,looks/like/a.path", "", "", "", "",
+ L"default_filename_is_given", L"default_filename_is_given"},
+ {__LINE__, "data:,looks/like/a.path", "", "", "", "",
+ L"\u65e5\u672c\u8a9e", // Japanese Kanji.
+ L"\u65e5\u672c\u8a9e"},
+ {// The filename encoding is specified by the referrer charset.
+ __LINE__, "http://example.com/V%FDvojov%E1%20psychologie.doc", "",
+ "iso-8859-1", "", "", L"", L"V\u00fdvojov\u00e1 psychologie.doc"},
+ {// Suggested filename takes precedence over URL
+ __LINE__, "http://www.google.com/test", "", "", "suggested", "", L"",
+ L"suggested"},
+ {// The content-disposition has higher precedence over the suggested name.
+ __LINE__, "http://www.google.com/test", "attachment; filename=test.html",
+ "", "suggested", "", L"", L"test.html"},
+ {__LINE__, "http://www.google.com/test", "attachment; filename=test",
+ "utf-8", "", "image/png", L"", L"test"},
+ // Raw 8bit characters in C-D
+ {__LINE__, "http://www.example.com/images?id=3",
+ "attachment; filename=caf\xc3\xa9.png", "iso-8859-1", "", "image/png",
+ L"", L"caf\u00e9.png"},
+ {__LINE__, "http://www.example.com/images?id=3",
+ "attachment; filename=caf\xe5.png", "windows-1253", "", "image/png", L"",
+ L"caf\u03b5.png"},
+ {// No 'filename' keyword in the disposition, use the URL
+ __LINE__, "http://www.evil.com/my_download.txt", "a_file_name.txt", "",
+ "", "text/plain", L"download", L"my_download.txt"},
+ {// Spaces in the disposition file name
+ __LINE__, "http://www.frontpagehacker.com/a_download.exe",
+ "filename=My Downloaded File.exe", "", "", "application/octet-stream",
+ L"download", L"My Downloaded File.exe"},
+ {// % encoded
+ __LINE__, "http://www.examples.com/",
+ "attachment; "
+ "filename=\"%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg\"",
+ "", "", "application/x-chrome-extension", L"download",
+ L"\uc608\uc220 \uc608\uc220.jpg"},
+ {// Invalid C-D header. Name value is skipped now.
+ __LINE__, "http://www.examples.com/q.cgi?id=abc",
+ "attachment; name=abc de.pdf", "", "", "application/octet-stream",
+ L"download", L"q.cgi"},
+ {__LINE__, "http://www.example.com/path",
+ "filename=\"=?EUC-JP?Q?=B7=DD=BD=D13=2Epng?=\"", "", "", "image/png",
+ L"download",
+ L"\x82b8\x8853"
+ L"3.png"},
+ {// The following two have invalid CD headers and filenames come from the
+ // URL.
+ __LINE__, "http://www.example.com/test%20123",
+ "attachment; filename==?iiso88591?Q?caf=EG?=", "", "", "", L"download",
+ L"test 123"},
+ {__LINE__,
+ "http://www.google.com/%EC%98%88%EC%88%A0%20%EC%98%88%EC%88%A0.jpg",
+ "malformed_disposition", "", "", "", L"download",
+ L"\uc608\uc220 \uc608\uc220.jpg"},
+ {// Invalid C-D. No filename from URL. Falls back to 'download'.
+ __LINE__, "http://www.google.com/path1/path2/",
+ "attachment; filename==?iso88591?Q?caf=E3?", "", "", "", L"download",
+ L"download"},
};
// Tests filename generation. Once the correct filename is
@@ -796,148 +508,92 @@ TEST(FilenameUtilTest, GenerateFileName) {
{__LINE__, "http://www.google.com/.test", "", "", "", "", L"", L"test"},
{__LINE__, "http://www.google.com/..test", "", "", "", "", L"", L"test"},
{// Disposition has relative paths, remove directory separators
- __LINE__, "http://www.evil.com/my_download.txt",
- "filename=../../../../././../a_file_name.txt", "", "", "text/plain",
- L"download", L"_.._.._.._._._.._a_file_name.txt"},
+ __LINE__, "", "filename=../../../../././../a_file_name.txt", "", "",
+ "text/plain", L"download", L"_.._.._.._._._.._a_file_name.txt"},
{// Disposition has parent directories, remove directory separators
- __LINE__, "http://www.evil.com/my_download.txt",
- "filename=dir1/dir2/a_file_name.txt", "", "", "text/plain", L"download",
- L"dir1_dir2_a_file_name.txt"},
+ __LINE__, "", "filename=dir1/dir2/a_file_name.txt", "", "", "text/plain",
+ L"download", L"dir1_dir2_a_file_name.txt"},
{// Disposition has relative paths, remove directory separators
- __LINE__, "http://www.evil.com/my_download.txt",
- "filename=..\\..\\..\\..\\.\\.\\..\\a_file_name.txt", "", "", "text/plain",
- L"download", L"_.._.._.._._._.._a_file_name.txt"},
+ __LINE__, "", "filename=..\\..\\..\\..\\.\\.\\..\\a_file_name.txt", "", "",
+ "text/plain", L"download", L"_.._.._.._._._.._a_file_name.txt"},
{// Disposition has parent directories, remove directory separators
- __LINE__, "http://www.evil.com/my_download.txt",
- "filename=dir1\\dir2\\a_file_name.txt", "", "", "text/plain", L"download",
- L"dir1_dir2_a_file_name.txt"},
- {// No useful information in disposition or URL, use default
- __LINE__, "http://www.truncated.com/path/", "", "", "", "text/plain",
- L"download", L"download" TXT_EXT},
+ __LINE__, "", "filename=dir1\\dir2\\a_file_name.txt", "", "", "text/plain",
+ L"download", L"dir1_dir2_a_file_name.txt"},
{// Filename looks like HTML?
- __LINE__, "http://www.evil.com/get/malware/here",
- "filename=\"<blink>Hello kitty</blink>\"", "", "", "text/plain",
- L"default", L"_blink_Hello kitty__blink_"},
+ __LINE__, "", "filename=\"<blink>Hello kitty</blink>\"", "", "",
+ "text/plain", L"default", L"_blink_Hello kitty__blink_"},
{// A normal avi should get .avi and not .avi.avi
- __LINE__, "https://blah.google.com/misc/2.avi", "", "", "",
- "video/x-msvideo", L"download", L"2.avi"},
+ __LINE__, "https://example.com/misc/2.avi", "", "", "", "video/x-msvideo",
+ L"download", L"2.avi"},
{// Shouldn't unescape slashes.
- __LINE__, "http://www.example.com/foo%2f..%2fbar.jpg", "", "", "",
+ __LINE__, "http://example.com/foo%2f..%2fbar.jpg", "", "", "",
"text/plain", L"download", L"foo%2f..%2fbar.jpg"},
- {// Extension generation
- __LINE__, "http://www.example.com/my-cat", "filename=my-cat", "", "",
- "image/jpeg", L"download", L"my-cat"},
- {__LINE__, "http://www.example.com/my-cat", "filename=my-cat", "", "",
- "text/plain", L"download", L"my-cat"},
- {__LINE__, "http://www.example.com/my-cat", "filename=my-cat", "", "",
- "text/html", L"download", L"my-cat"},
+ {// Extension generation for C-D derived filenames.
+ __LINE__, "", "filename=my-cat", "", "", "image/jpeg", L"download",
+ L"my-cat"},
{// Unknown MIME type
- __LINE__, "http://www.example.com/my-cat", "filename=my-cat", "", "",
- "dance/party", L"download", L"my-cat"},
- {__LINE__, "http://www.example.com/my-cat.jpg", "filename=my-cat.jpg", "",
- "", "text/plain", L"download", L"my-cat.jpg"},
-// Windows specific tests
-#if defined(OS_WIN)
- {__LINE__, "http://www.goodguy.com/evil.exe", "filename=evil.exe", "", "",
- "image/jpeg", L"download", L"evil.exe"},
- {__LINE__, "http://www.goodguy.com/ok.exe", "filename=ok.exe", "", "",
- "binary/octet-stream", L"download", L"ok.exe"},
- {__LINE__, "http://www.goodguy.com/evil.dll", "filename=evil.dll", "", "",
- "dance/party", L"download", L"evil.dll"},
- {__LINE__, "http://www.goodguy.com/evil.exe", "filename=evil", "", "",
- "application/rss+xml", L"download", L"evil"},
- // Test truncation of trailing dots and spaces
- {__LINE__, "http://www.goodguy.com/evil.exe ", "filename=evil.exe ", "", "",
- "binary/octet-stream", L"download", L"evil.exe"},
- {__LINE__, "http://www.goodguy.com/evil.exe.", "filename=evil.exe.", "", "",
- "binary/octet-stream", L"download", L"evil.exe_"},
- {__LINE__, "http://www.goodguy.com/evil.exe. . .",
- "filename=evil.exe. . .", "", "", "binary/octet-stream", L"download",
- L"evil.exe_______"},
- {__LINE__, "http://www.goodguy.com/evil.", "filename=evil.", "", "",
- "binary/octet-stream", L"download", L"evil_"},
- {__LINE__, "http://www.goodguy.com/. . . . .", "filename=. . . . .", "", "",
- "binary/octet-stream", L"download", L"download"},
- {__LINE__, "http://www.badguy.com/attachment?name=meh.exe%C2%A0",
- "attachment; filename=\"meh.exe\xC2\xA0\"", "", "", "binary/octet-stream",
- L"", L"meh.exe_"},
-#endif // OS_WIN
- {__LINE__, "http://www.goodguy.com/utils.js", "filename=utils.js", "", "",
- "application/x-javascript", L"download", L"utils.js"},
- {__LINE__, "http://www.goodguy.com/contacts.js", "filename=contacts.js", "",
- "", "application/json", L"download", L"contacts.js"},
- {__LINE__, "http://www.goodguy.com/utils.js", "filename=utils.js", "", "",
- "text/javascript", L"download", L"utils.js"},
- {__LINE__, "http://www.goodguy.com/utils.js", "filename=utils.js", "", "",
- "text/javascript;version=2", L"download", L"utils.js"},
- {__LINE__, "http://www.goodguy.com/utils.js", "filename=utils.js", "", "",
- "application/ecmascript", L"download", L"utils.js"},
- {__LINE__, "http://www.goodguy.com/utils.js", "filename=utils.js", "", "",
- "application/ecmascript;version=4", L"download", L"utils.js"},
- {__LINE__, "http://www.goodguy.com/program.exe", "filename=program.exe", "",
- "", "application/foo-bar", L"download", L"program.exe"},
- {__LINE__, "http://www.evil.com/../foo.txt", "filename=../foo.txt", "", "",
- "text/plain", L"download", L"_foo.txt"},
- {__LINE__, "http://www.evil.com/..\\foo.txt", "filename=..\\foo.txt", "",
- "", "text/plain", L"download", L"_foo.txt"},
- {__LINE__, "http://www.evil.com/.hidden", "filename=.hidden", "", "",
- "text/plain", L"download", L"hidden"},
- {__LINE__, "http://www.evil.com/trailing.", "filename=trailing.", "", "",
- "dance/party", L"download",
-#if defined(OS_WIN)
- L"trailing_"
-#else
- L"trailing"
-#endif
- },
- {__LINE__, "http://www.evil.com/trailing.", "filename=trailing.", "", "",
- "text/plain", L"download",
+ __LINE__, "", "filename=my-cat", "", "", "dance/party", L"download",
+ L"my-cat"},
+ {// Known MIME type.
+ __LINE__, "", "filename=my-cat.jpg", "", "", "text/plain", L"download",
+ L"my-cat.jpg"},
#if defined(OS_WIN)
- L"trailing_"
-#else
- L"trailing"
-#endif
- },
- {__LINE__, "http://www.evil.com/.", "filename=.", "", "", "dance/party",
- L"download", L"download"},
- {__LINE__, "http://www.evil.com/..", "filename=..", "", "", "dance/party",
- L"download", L"download"},
- {__LINE__, "http://www.evil.com/...", "filename=...", "", "", "dance/party",
+ // Test truncation of trailing dots and spaces (Windows)
+ {__LINE__, "", "filename=evil.exe ", "", "", "binary/octet-stream",
+ L"download", L"evil.exe"},
+ {__LINE__, "", "filename=evil.exe.", "", "", "binary/octet-stream",
+ L"download", L"evil.exe_"},
+ {__LINE__, "", "filename=evil.exe. . .", "", "", "binary/octet-stream",
+ L"download", L"evil.exe_______"},
+ {__LINE__, "", "filename=evil.", "", "", "binary/octet-stream", L"download",
+ L"evil_"},
+ {__LINE__, "", "filename=. . . . .", "", "", "binary/octet-stream",
L"download", L"download"},
- {// Note that this one doesn't have "filename=" on it.
- __LINE__, "http://www.evil.com/", "a_file_name.txt", "", "", "image/jpeg",
- L"download", L"download" JPEG_EXT},
- {__LINE__, "http://www.evil.com/", "filename=", "", "", "image/jpeg",
- L"download", L"download" JPEG_EXT},
- {__LINE__, "http://www.example.com/simple", "filename=simple", "", "",
- "application/octet-stream", L"download", L"simple"},
+#else // OS_WIN
+ // Test truncation of trailing dots and spaces (non-Windows)
+ {__LINE__, "", "filename=evil.exe ", "", "", "binary/octet-stream",
+ L"download", L"evil.exe"},
+ {__LINE__, "", "filename=evil.exe.", "", "", "binary/octet-stream",
+ L"download", L"evil.exe"},
+ {__LINE__, "", "filename=evil.exe. . .", "", "", "binary/octet-stream",
+ L"download", L"evil.exe. . _"},
+ {__LINE__, "", "filename=evil.", "", "", "binary/octet-stream", L"download",
+ L"evil"},
+ {__LINE__, "", "filename=. . . . .", "", "", "binary/octet-stream",
+ L"download", L"_. . ._"},
+#endif
+ {__LINE__, "", "attachment; filename=\"meh.exe\xC2\xA0\"", "", "",
+ "binary/octet-stream", L"", L"meh.exe_"},
+ // Disappearing directory references:
+ {__LINE__, "", "filename=.", "", "", "dance/party", L"download",
+ L"download"},
+ {__LINE__, "", "filename=..", "", "", "dance/party", L"download",
+ L"download"},
+ {__LINE__, "", "filename=...", "", "", "dance/party", L"download",
+ L"download"},
// Reserved words on Windows
- {__LINE__, "http://www.goodguy.com/COM1", "filename=COM1", "", "",
- "application/foo-bar", L"download",
+ {__LINE__, "", "filename=COM1", "", "", "application/foo-bar", L"download",
#if defined(OS_WIN)
L"_COM1"
#else
L"COM1"
#endif
},
- {__LINE__, "http://www.goodguy.com/COM4.txt", "filename=COM4.txt", "", "",
- "text/plain", L"download",
+ {__LINE__, "", "filename=COM4.txt", "", "", "text/plain", L"download",
#if defined(OS_WIN)
L"_COM4.txt"
#else
L"COM4.txt"
#endif
},
- {__LINE__, "http://www.goodguy.com/lpt1.TXT", "filename=lpt1.TXT", "", "",
- "text/plain", L"download",
+ {__LINE__, "", "filename=lpt1.TXT", "", "", "text/plain", L"download",
#if defined(OS_WIN)
L"_lpt1.TXT"
#else
L"lpt1.TXT"
#endif
},
- {__LINE__, "http://www.goodguy.com/clock$.txt", "filename=clock$.txt", "",
- "", "text/plain", L"download",
+ {__LINE__, "", "filename=clock$.txt", "", "", "text/plain", L"download",
#if defined(OS_WIN)
L"_clock$.txt"
#else
@@ -945,59 +601,53 @@ TEST(FilenameUtilTest, GenerateFileName) {
#endif
},
{// Validation should also apply to sugested name
- __LINE__, "http://www.goodguy.com/blah$.txt", "filename=clock$.txt", "",
- "clock$.txt", "text/plain", L"download",
+ __LINE__, "", "", "", "clock$.txt", "text/plain", L"download",
#if defined(OS_WIN)
L"_clock$.txt"
#else
L"clock$.txt"
#endif
},
- {__LINE__, "http://www.goodguy.com/mycom1.foo", "filename=mycom1.foo", "",
- "", "text/plain", L"download", L"mycom1.foo"},
- {__LINE__, "http://www.badguy.com/Setup.exe.local",
- "filename=Setup.exe.local", "", "", "application/foo-bar", L"download",
+ {// Device names only work when present at the start of the string.
+ __LINE__, "", "filename=mycom1.foo", "", "", "", L"download",
+ L"mycom1.foo"},
+ {__LINE__, "", "filename=Setup.exe.local", "", "", "", L"download",
#if defined(OS_WIN)
L"Setup.exe.download"
#else
L"Setup.exe.local"
#endif
},
- {__LINE__, "http://www.badguy.com/Setup.exe.local",
- "filename=Setup.exe.local.local", "", "", "application/foo-bar",
- L"download",
+ {__LINE__, "", "filename=Setup.exe.local.local", "", "", "", L"download",
#if defined(OS_WIN)
L"Setup.exe.local.download"
#else
L"Setup.exe.local.local"
#endif
},
- {__LINE__, "http://www.badguy.com/Setup.exe.lnk", "filename=Setup.exe.lnk",
- "", "", "application/foo-bar", L"download",
+ {__LINE__, "", "filename=Setup.exe.lnk", "", "", "", L"download",
#if defined(OS_WIN)
L"Setup.exe.download"
#else
L"Setup.exe.lnk"
#endif
},
- {__LINE__, "http://www.badguy.com/Desktop.ini", "filename=Desktop.ini", "",
- "", "application/foo-bar", L"download",
+ {__LINE__, "", "filename=Desktop.ini", "", "", "", L"download",
#if defined(OS_WIN)
L"_Desktop.ini"
#else
L"Desktop.ini"
#endif
},
- {__LINE__, "http://www.badguy.com/Thumbs.db", "filename=Thumbs.db", "", "",
- "application/foo-bar", L"download",
+ {__LINE__, "", "filename=Thumbs.db", "", "", "", L"download",
#if defined(OS_WIN)
L"_Thumbs.db"
#else
L"Thumbs.db"
#endif
},
- {__LINE__, "http://www.hotmail.com", "filename=source.jpg", "", "",
- "application/x-javascript", L"download", L"source.jpg"},
+
+ // Regression tests for older issues:
{// http://crbug.com/5772.
__LINE__, "http://www.example.com/foo.tar.gz", "", "", "",
"application/x-tar", L"download", L"foo.tar.gz"},
@@ -1019,13 +669,13 @@ TEST(FilenameUtilTest, GenerateFileName) {
L"download", L"bar.sh"},
{// http://crbug.com/61571
__LINE__, "http://www.example.com/npdf.php?fn=foobar.pdf", "", "", "",
- "text/plain", L"download", L"npdf" TXT_EXT},
+ "application/x-chrome-extension", L"download", L"npdf.crx"},
{// Shouldn't overwrite C-D specified extension.
__LINE__, "http://www.example.com/npdf.php?fn=foobar.pdf",
"filename=foobar.jpg", "", "", "text/plain", L"download", L"foobar.jpg"},
{// http://crbug.com/87719
__LINE__, "http://www.example.com/image.aspx?id=blargh", "", "", "",
- "image/jpeg", L"download", L"image" JPEG_EXT},
+ "application/x-chrome-extension", L"download", L"image.crx"},
{__LINE__, "http://www.example.com/image.aspx?id=blargh", "", "", " .foo",
"", L"download", L"_.foo"},
diff --git a/chromium/net/base/ip_address.cc b/chromium/net/base/ip_address.cc
index 544320617ce..84578bcba3b 100644
--- a/chromium/net/base/ip_address.cc
+++ b/chromium/net/base/ip_address.cc
@@ -47,14 +47,14 @@ bool IPAddressPrefixCheck(const IPAddressBytes& ip_address,
return true;
}
-// Returns true if |ip_address| matches any of the reserved IPv4 ranges. This
+// Returns false if |ip_address| matches any of the reserved IPv4 ranges. This
// method operates on a blacklist of reserved IPv4 ranges. Some ranges are
// consolidated.
// Sources for info:
// www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xhtml
// www.iana.org/assignments/iana-ipv4-special-registry/
// iana-ipv4-special-registry.xhtml
-bool IsReservedIPv4(const IPAddressBytes& ip_address) {
+bool IsPubliclyRoutableIPv4(const IPAddressBytes& ip_address) {
// Different IP versions have different range reservations.
DCHECK_EQ(IPAddress::kIPv4AddressSize, ip_address.size());
struct {
@@ -70,39 +70,46 @@ bool IsReservedIPv4(const IPAddressBytes& ip_address) {
for (const auto& range : kReservedIPv4Ranges) {
if (IPAddressPrefixCheck(ip_address, range.address,
range.prefix_length_in_bits)) {
- return true;
+ return false;
}
}
- return false;
+ return true;
}
-// Returns true if |ip_address| matches any of the reserved IPv6 ranges. This
-// method operates on a whitelist of non-reserved IPv6 ranges. All IPv6
-// addresses outside these ranges are reserved.
+// Returns false if |ip_address| matches any of the IPv6 ranges IANA reserved
+// for local networks. This method operates on a whitelist of non-reserved
+// IPv6 ranges, plus the blacklist of reserved IPv4 ranges mapped to IPv6.
// Sources for info:
// www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
-bool IsReservedIPv6(const IPAddressBytes& ip_address) {
- // Different IP versions have different range reservations.
+bool IsPubliclyRoutableIPv6(const IPAddressBytes& ip_address,
+ bool include_mapped_ipv4) {
DCHECK_EQ(IPAddress::kIPv6AddressSize, ip_address.size());
struct {
const uint8_t address_prefix[2];
size_t prefix_length_in_bits;
- } static const kPublicIPv6Ranges[] = {
- // 2000::/3 -- Global Unicast
- {{0x20, 0}, 3},
- // ff00::/8 -- Multicast
- {{0xff, 0}, 8},
- };
+ } static const kPublicIPv6Ranges[] = {// 2000::/3 -- Global Unicast
+ {{0x20, 0}, 3},
+ // ff00::/8 -- Multicast
+ {{0xff, 0}, 8}};
for (const auto& range : kPublicIPv6Ranges) {
if (IPAddressPrefixCheck(ip_address, range.address_prefix,
range.prefix_length_in_bits)) {
- return false;
+ return true;
}
}
- return true;
+ if (!include_mapped_ipv4)
+ return false;
+
+ IPAddress addr(ip_address);
+ if (addr.IsIPv4MappedIPv6()) {
+ IPAddress ipv4 = ConvertIPv4MappedIPv6ToIPv4(addr);
+ return IsPubliclyRoutableIPv4(ipv4.bytes());
+ }
+
+ return false;
}
bool ParseIPLiteralToBytes(const base::StringPiece& ip_literal,
@@ -229,13 +236,23 @@ bool IPAddress::IsValid() const {
bool IPAddress::IsReserved() const {
if (IsIPv4()) {
- return IsReservedIPv4(ip_address_);
+ return !IsPubliclyRoutableIPv4(ip_address_);
} else if (IsIPv6()) {
- return IsReservedIPv6(ip_address_);
+ return !IsPubliclyRoutableIPv6(ip_address_,
+ false /* include_mapped_ipv4 */);
}
return false;
}
+bool IPAddress::IsPubliclyRoutable() const {
+ if (IsIPv4()) {
+ return IsPubliclyRoutableIPv4(ip_address_);
+ } else if (IsIPv6()) {
+ return IsPubliclyRoutableIPv6(ip_address_, true /* include_mapped_ipv4 */);
+ }
+ return true;
+}
+
bool IPAddress::IsZero() const {
for (auto x : ip_address_) {
if (x != 0)
@@ -250,15 +267,10 @@ bool IPAddress::IsIPv4MappedIPv6() const {
}
bool IPAddress::AssignFromIPLiteral(const base::StringPiece& ip_literal) {
- IPAddressBytes number;
-
- // TODO(rch): change the contract so ip_address_ is cleared on failure,
- // to avoid needing this temporary at all.
- if (!ParseIPLiteralToBytes(ip_literal, &number))
- return false;
-
- ip_address_ = number;
- return true;
+ bool success = ParseIPLiteralToBytes(ip_literal, &ip_address_);
+ if (!success)
+ ip_address_.Resize(0);
+ return success;
}
std::vector<uint8_t> IPAddress::CopyBytesToVector() const {
diff --git a/chromium/net/base/ip_address.h b/chromium/net/base/ip_address.h
index 72f9d75c210..32ac195d839 100644
--- a/chromium/net/base/ip_address.h
+++ b/chromium/net/base/ip_address.h
@@ -155,8 +155,14 @@ class NET_EXPORT IPAddress {
// Returns true if the IP is in a range reserved by the IANA.
// Works with both IPv4 and IPv6 addresses, and only compares against a given
// protocols's reserved ranges.
+ // DEPRECATED. Use !IsPubliclyRoutable(). https://crbug.com/755418
bool IsReserved() const;
+ // Returns true if the IP is not in a range reserved by the IANA for
+ // local networks. Works with both IPv4 and IPv6 addresses.
+ // IPv4-mapped-to-IPv6 addresses are considered publicly routable.
+ bool IsPubliclyRoutable() const;
+
// Returns true if the IP is "zero" (e.g. the 0.0.0.0 IPv4 address).
bool IsZero() const;
@@ -176,6 +182,9 @@ class NET_EXPORT IPAddress {
// Parses an IP address literal (either IPv4 or IPv6) to its numeric value.
// Returns true on success and fills |ip_address_| with the numeric value.
+ //
+ // When parsing fails, the original value of |this| will be overwritten such
+ // that |this->empty()| and |!this->IsValid()|.
bool AssignFromIPLiteral(const base::StringPiece& ip_literal)
WARN_UNUSED_RESULT;
@@ -248,7 +257,8 @@ NET_EXPORT bool IPAddressMatchesPrefix(const IPAddress& ip_address,
// Parses an IP block specifier from CIDR notation to an
// (IP address, prefix length) pair. Returns true on success and fills
// |*ip_address| with the numeric value of the IP address and sets
-// |*prefix_length_in_bits| with the length of the prefix.
+// |*prefix_length_in_bits| with the length of the prefix. On failure,
+// |ip_address| will be cleared to an empty value.
//
// CIDR notation literals can use either IPv4 or IPv6 literals. Some examples:
//
@@ -262,7 +272,8 @@ NET_EXPORT bool ParseCIDRBlock(const std::string& cidr_literal,
// Parses a URL-safe IP literal (see RFC 3986, Sec 3.2.2) to its numeric value.
// Returns true on success, and fills |ip_address| with the numeric value.
// In other words, |hostname| must be an IPv4 literal, or an IPv6 literal
-// surrounded by brackets as in [::1].
+// surrounded by brackets as in [::1]. On failure |ip_address| may have been
+// overwritten and could contain an invalid IPAddress.
NET_EXPORT bool ParseURLHostnameToAddress(const base::StringPiece& hostname,
IPAddress* ip_address)
WARN_UNUSED_RESULT;
diff --git a/chromium/net/base/ip_address_unittest.cc b/chromium/net/base/ip_address_unittest.cc
index d8acf86b106..948e43e40df 100644
--- a/chromium/net/base/ip_address_unittest.cc
+++ b/chromium/net/base/ip_address_unittest.cc
@@ -107,7 +107,7 @@ enum IPAddressReservedResult : bool { NOT_RESERVED = false, RESERVED = true };
// Tests for the reserved IPv4 ranges and the (unreserved) blocks in between.
// The reserved ranges are tested by checking the first and last address of each
// range. The unreserved blocks are tested similarly. These tests cover the
-// entire IPv4 address range.
+// entire IPv4 address range, as well as this range mapped to IPv6.
TEST(IPAddressTest, IsReservedIPv4) {
struct {
const char* const address;
@@ -213,10 +213,18 @@ TEST(IPAddressTest, IsReservedIPv4) {
{"255.255.255.255", RESERVED}};
IPAddress address;
+ IPAddress mapped_address;
for (const auto& test : tests) {
EXPECT_TRUE(address.AssignFromIPLiteral(test.address));
ASSERT_TRUE(address.IsValid());
EXPECT_EQ(!!test.is_reserved, address.IsReserved());
+ EXPECT_EQ(!test.is_reserved, address.IsPubliclyRoutable());
+
+ // Check these IPv4 addresses when mapped to IPv6. This verifies we're
+ // properly unpacking mapped addresses.
+ IPAddress mapped_address = ConvertIPv4ToIPv4MappedIPv6(address);
+ EXPECT_TRUE(mapped_address.IsReserved());
+ EXPECT_EQ(!test.is_reserved, mapped_address.IsPubliclyRoutable());
}
}
@@ -228,7 +236,9 @@ TEST(IPAddressTest, IsReservedIPv6) {
struct {
const char* const address;
IPAddressReservedResult is_reserved;
- } tests[] = {// 0000::/8
+ } tests[] = {// 0000::/8.
+ // Skip testing ::ffff:/96 explicitly since it was tested
+ // in IsReservedIPv4
{"0:0:0:0:0:0:0:0", RESERVED},
{"ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", RESERVED},
// 0100::/8
@@ -290,6 +300,7 @@ TEST(IPAddressTest, IsReservedIPv6) {
for (const auto& test : tests) {
EXPECT_TRUE(address.AssignFromIPLiteral(test.address));
EXPECT_EQ(!!test.is_reserved, address.IsReserved());
+ EXPECT_EQ(!test.is_reserved, address.IsPubliclyRoutable());
}
}
@@ -395,6 +406,20 @@ TEST(IPAddressTest, AssignFromIPLiteral_FailParse) {
EXPECT_FALSE(address.AssignFromIPLiteral("[::1]"));
}
+// Test that a failure calling AssignFromIPLiteral() has the sideffect of
+// clearing the current value.
+TEST(IPAddressTest, AssignFromIPLiteral_ResetOnFailure) {
+ IPAddress address = IPAddress::IPv6Localhost();
+
+ EXPECT_TRUE(address.IsValid());
+ EXPECT_FALSE(address.empty());
+
+ EXPECT_FALSE(address.AssignFromIPLiteral("bad value"));
+
+ EXPECT_FALSE(address.IsValid());
+ EXPECT_TRUE(address.empty());
+}
+
// Test parsing an IPv4 literal.
TEST(IPAddressTest, AssignFromIPLiteral_IPv4) {
IPAddress address;
diff --git a/chromium/net/base/load_flags_list.h b/chromium/net/base/load_flags_list.h
index 76ff4fecac5..a342d761580 100644
--- a/chromium/net/base/load_flags_list.h
+++ b/chromium/net/base/load_flags_list.h
@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// This file intentionally does not have header guards, it's included
+// inside a macro to generate values. The following line silences a
+// presubmit warning that would otherwise be triggered by this:
+// no-include-guard-because-multiply-included
+
// This is the list of load flags and their values. For the enum values,
// include the file "net/base/load_flags.h".
//
@@ -11,10 +16,13 @@
LOAD_FLAG(NORMAL, 0)
-// This is "normal reload", meaning an if-none-match/if-modified-since query
+// This is "normal reload", meaning an if-none-match/if-modified-since query. It
+// has no effect on the host cache.
LOAD_FLAG(VALIDATE_CACHE, 1 << 0)
-// This is "shift-reload", meaning a "pragma: no-cache" end-to-end fetch
+// This is "shift-reload", meaning a "pragma: no-cache" end-to-end fetch. It
+// also disables use of the host cache for resolutions that go through the
+// socket pools.
LOAD_FLAG(BYPASS_CACHE, 1 << 1)
// This is a back/forward style navigation where the cached content should
@@ -26,7 +34,7 @@ LOAD_FLAG(SKIP_CACHE_VALIDATION, 1 << 2)
LOAD_FLAG(ONLY_FROM_CACHE, 1 << 3)
// This is a navigation that will not use the cache at all. It does not
-// impact the HTTP request headers.
+// impact the HTTP request headers or use of the host cache.
LOAD_FLAG(DISABLE_CACHE, 1 << 4)
// If present, causes certificate revocation checks to be skipped on secure
@@ -41,18 +49,15 @@ LOAD_FLAG(DO_NOT_SAVE_COOKIES, 1 << 6)
// to avoid having a circular dependency.
LOAD_FLAG(BYPASS_PROXY, 1 << 7)
-// Requires EV certificate verification.
-LOAD_FLAG(VERIFY_EV_CERT, 1 << 8)
-
// This load will not send any cookies.
-LOAD_FLAG(DO_NOT_SEND_COOKIES, 1 << 9)
+LOAD_FLAG(DO_NOT_SEND_COOKIES, 1 << 8)
// This load will not send authentication data (user name/password)
// to the server (as opposed to the proxy).
-LOAD_FLAG(DO_NOT_SEND_AUTH_DATA, 1 << 10)
+LOAD_FLAG(DO_NOT_SEND_AUTH_DATA, 1 << 9)
// This should only be used for testing (set by HttpNetworkTransaction).
-LOAD_FLAG(IGNORE_ALL_CERT_ERRORS, 1 << 11)
+LOAD_FLAG(IGNORE_ALL_CERT_ERRORS, 1 << 10)
// DO NOT USE THIS FLAG
// The network stack should not have frame level knowledge. Any pre-connect
@@ -61,29 +66,29 @@ LOAD_FLAG(IGNORE_ALL_CERT_ERRORS, 1 << 11)
// Indicate that this is a top level frame, so that we don't assume it is a
// subresource and speculatively pre-connect or pre-resolve when a referring
// page is loaded.
-LOAD_FLAG(MAIN_FRAME_DEPRECATED, 1 << 12)
+LOAD_FLAG(MAIN_FRAME_DEPRECATED, 1 << 11)
// Indicates that this load was motivated by the rel=prefetch feature,
// and is (in theory) not intended for the current frame.
-LOAD_FLAG(PREFETCH, 1 << 13)
+LOAD_FLAG(PREFETCH, 1 << 12)
// Indicates that this load could cause deadlock if it has to wait for another
// request. Overrides socket limits. Must always be used with MAXIMUM_PRIORITY.
-LOAD_FLAG(IGNORE_LIMITS, 1 << 14)
+LOAD_FLAG(IGNORE_LIMITS, 1 << 13)
// Indicates that the operation is somewhat likely to be due to an
// explicit user action. This can be used as a hint to treat the
// request with higher priority.
-LOAD_FLAG(MAYBE_USER_GESTURE, 1 << 15)
+LOAD_FLAG(MAYBE_USER_GESTURE, 1 << 14)
// Indicates that the username:password portion of the URL should not
// be honored, but that other forms of authority may be used.
-LOAD_FLAG(DO_NOT_USE_EMBEDDED_IDENTITY, 1 << 16)
+LOAD_FLAG(DO_NOT_USE_EMBEDDED_IDENTITY, 1 << 15)
// Indicates that this request is not to be migrated to a new network when QUIC
// connection migration is enabled.
-LOAD_FLAG(DISABLE_CONNECTION_MIGRATION, 1 << 17)
+LOAD_FLAG(DISABLE_CONNECTION_MIGRATION, 1 << 16)
// Indicates that the cache should not check that the request matches the
// response's vary header.
-LOAD_FLAG(SKIP_VARY_CHECK, 1 << 18)
+LOAD_FLAG(SKIP_VARY_CHECK, 1 << 17)
diff --git a/chromium/net/base/load_states_list.h b/chromium/net/base/load_states_list.h
index 5e850fb6222..4a88e0152a4 100644
--- a/chromium/net/base/load_states_list.h
+++ b/chromium/net/base/load_states_list.h
@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// This file intentionally does not have header guards, it's included
+// inside a macro to generate values. The following line silences a
+// presubmit warning that would otherwise be triggered by this:
+// no-include-guard-because-multiply-included
+
// This is the list of load states and their values. For the enum values,
// include the file "net/base/load_states.h".
//
@@ -15,88 +20,84 @@
// called Read yet).
LOAD_STATE(IDLE, 0)
-// This state corresponds to a resource load that is throttled by the
-// network layer waiting for some other resource load or loads to complete.
-LOAD_STATE(THROTTLED, 1)
-
// When a socket pool group is below the maximum number of sockets allowed per
// group, but a new socket cannot be created due to the per-pool socket limit,
// this state is returned by all requests for the group waiting on an idle
// connection, except those that may be serviced by a pending new connection.
-LOAD_STATE(WAITING_FOR_STALLED_SOCKET_POOL, 2)
+LOAD_STATE(WAITING_FOR_STALLED_SOCKET_POOL, 1)
// When a socket pool group has reached the maximum number of sockets allowed
// per group, this state is returned for all requests that don't have a socket,
// except those that correspond to a pending new connection.
-LOAD_STATE(WAITING_FOR_AVAILABLE_SOCKET, 3)
+LOAD_STATE(WAITING_FOR_AVAILABLE_SOCKET, 2)
// This state indicates that the URLRequest delegate has chosen to block this
// request before it was sent over the network. When in this state, the
// delegate should set a load state parameter on the URLRequest describing
// the nature of the delay (i.e. "Waiting for <description given by
// delegate>").
-LOAD_STATE(WAITING_FOR_DELEGATE, 4)
+LOAD_STATE(WAITING_FOR_DELEGATE, 3)
// This state corresponds to a resource load that is blocked waiting for
// access to a resource in the cache. If multiple requests are made for the
// same resource, the first request will be responsible for writing (or
// updating) the cache entry and the second request will be deferred until
// the first completes. This may be done to optimize for cache reuse.
-LOAD_STATE(WAITING_FOR_CACHE, 5)
+LOAD_STATE(WAITING_FOR_CACHE, 4)
// This state corresponds to a resource load that is blocked waiting for
// access to a resource in the AppCache.
// Note: This is a layering violation, but being the only one it's not that
// bad. TODO(rvargas): Reconsider what to do if we need to add more.
-LOAD_STATE(WAITING_FOR_APPCACHE, 6)
+LOAD_STATE(WAITING_FOR_APPCACHE, 5)
// This state corresponds to a resource being blocked waiting for the
// PAC script to be downloaded.
-LOAD_STATE(DOWNLOADING_PROXY_SCRIPT, 7)
+LOAD_STATE(DOWNLOADING_PAC_FILE, 6)
// This state corresponds to a resource load that is blocked waiting for a
// proxy autoconfig script to return a proxy server to use.
-LOAD_STATE(RESOLVING_PROXY_FOR_URL, 8)
+LOAD_STATE(RESOLVING_PROXY_FOR_URL, 7)
// This state corresponds to a resource load that is blocked waiting for a
// proxy autoconfig script to return a proxy server to use, but that proxy
// script is busy resolving the IP address of a host.
-LOAD_STATE(RESOLVING_HOST_IN_PROXY_SCRIPT, 9)
+LOAD_STATE(RESOLVING_HOST_IN_PAC_FILE, 8)
// This state indicates that we're in the process of establishing a tunnel
// through the proxy server.
-LOAD_STATE(ESTABLISHING_PROXY_TUNNEL, 10)
+LOAD_STATE(ESTABLISHING_PROXY_TUNNEL, 9)
// This state corresponds to a resource load that is blocked waiting for a
// host name to be resolved. This could either indicate resolution of the
// origin server corresponding to the resource or to the host name of a proxy
// server used to fetch the resource.
-LOAD_STATE(RESOLVING_HOST, 11)
+LOAD_STATE(RESOLVING_HOST, 10)
// This state corresponds to a resource load that is blocked waiting for a
// TCP connection (or other network connection) to be established. HTTP
// requests that reuse a keep-alive connection skip this state.
-LOAD_STATE(CONNECTING, 12)
+LOAD_STATE(CONNECTING, 11)
// This state corresponds to a resource load that is blocked waiting for the
// SSL handshake to complete.
-LOAD_STATE(SSL_HANDSHAKE, 13)
+LOAD_STATE(SSL_HANDSHAKE, 12)
// This state corresponds to a resource load that is blocked waiting to
// completely upload a request to a server. In the case of a HTTP POST
// request, this state includes the period of time during which the message
// body is being uploaded.
-LOAD_STATE(SENDING_REQUEST, 14)
+LOAD_STATE(SENDING_REQUEST, 13)
// This state corresponds to a resource load that is blocked waiting for the
// response to a network request. In the case of a HTTP transaction, this
// corresponds to the period after the request is sent and before all of the
// response headers have been received.
-LOAD_STATE(WAITING_FOR_RESPONSE, 15)
+LOAD_STATE(WAITING_FOR_RESPONSE, 14)
// This state corresponds to a resource load that is blocked waiting for a
// read to complete. In the case of a HTTP transaction, this corresponds to
// the period after the response headers have been received and before all of
// the response body has been downloaded. (NOTE: This state only applies for
// an URLRequest while there is an outstanding Read operation.)
-LOAD_STATE(READING_RESPONSE, 16)
+LOAD_STATE(READING_RESPONSE, 15)
diff --git a/chromium/net/base/load_timing_info.h b/chromium/net/base/load_timing_info.h
index d397e07ea8c..af743523abf 100644
--- a/chromium/net/base/load_timing_info.h
+++ b/chromium/net/base/load_timing_info.h
@@ -73,6 +73,9 @@ struct NET_EXPORT LoadTimingInfo {
// established, which results in unexpected event ordering.
// TODO(mmenke): The SOCKS4 event ordering could be refactored to allow
// these times to be non-null.
+ // Corresponds to |domainLookupStart| and |domainLookupEnd| in
+ // ResourceTiming (http://www.w3.org/TR/resource-timing/) for Web-surfacing
+ // requests.
base::TimeTicks dns_start;
base::TimeTicks dns_end;
@@ -87,12 +90,16 @@ struct NET_EXPORT LoadTimingInfo {
// handled at different levels, this may not be worth
// worrying about - backup jobs, reused socket failure,
// multiple round authentication.
+ // Corresponds to |connectStart| and |connectEnd| in ResourceTiming
+ // (http://www.w3.org/TR/resource-timing/) for Web-surfacing requests.
base::TimeTicks connect_start;
base::TimeTicks connect_end;
// The time when the SSL handshake started / completed. For non-HTTPS
// requests these are null. These times are only for the SSL connection to
// the final destination server, not an SSL/SPDY proxy.
+ // |ssl_start| corresponds to |secureConnectionStart| in ResourceTiming
+ // (http://www.w3.org/TR/resource-timing/) for Web-surfacing requests.
base::TimeTicks ssl_start;
base::TimeTicks ssl_end;
};
@@ -127,6 +134,8 @@ struct NET_EXPORT LoadTimingInfo {
// changes.
base::Time request_start_time;
+ // Corresponds to |fetchStart| in ResourceTiming
+ // (http://www.w3.org/TR/resource-timing/) for Web-surfacing requests.
base::TimeTicks request_start;
// The time spent determing which proxy to use. Null when there is no PAC.
@@ -136,10 +145,14 @@ struct NET_EXPORT LoadTimingInfo {
ConnectTiming connect_timing;
// The time that sending HTTP request started / ended.
+ // |send_start| corresponds to |requestStart| in ResourceTiming
+ // (http://www.w3.org/TR/resource-timing/) for Web-surfacing requests.
base::TimeTicks send_start;
base::TimeTicks send_end;
// The time at which the end of the HTTP headers were received.
+ // Corresponds to |responseStart| in ResourceTiming
+ // (http://www.w3.org/TR/resource-timing/) for Web-surfacing requests.
base::TimeTicks receive_headers_end;
// In case the resource was proactively pushed by the server, these are
diff --git a/chromium/net/base/mime_sniffer.cc b/chromium/net/base/mime_sniffer.cc
index 65fe885d04b..39d25ab6d1a 100644
--- a/chromium/net/base/mime_sniffer.cc
+++ b/chromium/net/base/mime_sniffer.cc
@@ -687,8 +687,8 @@ static bool SniffCRX(const char* content,
// sniffing gives us less room for error. If the version number ever changes,
// we can just add an entry to this list.
static const struct MagicNumber kCRXMagicNumbers[] = {
- MAGIC_NUMBER("application/x-chrome-extension", "Cr24\x02\x00\x00\x00")
- };
+ MAGIC_NUMBER("application/x-chrome-extension", "Cr24\x02\x00\x00\x00"),
+ MAGIC_NUMBER("application/x-chrome-extension", "Cr24\x03\x00\x00\x00")};
// Only consider files that have the extension ".crx".
if (!base::EndsWith(url.path_piece(), ".crx", base::CompareCase::SENSITIVE))
diff --git a/chromium/net/base/mime_sniffer_unittest.cc b/chromium/net/base/mime_sniffer_unittest.cc
index d2f8c703aa4..1d3a8696f87 100644
--- a/chromium/net/base/mime_sniffer_unittest.cc
+++ b/chromium/net/base/mime_sniffer_unittest.cc
@@ -95,66 +95,55 @@ TEST(MimeSnifferTest, BasicSniffingTest) {
TEST(MimeSnifferTest, ChromeExtensionsTest) {
SnifferTest tests[] = {
- // schemes
- { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1,
- "http://www.example.com/foo.crx",
- "", "application/x-chrome-extension" },
- { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1,
- "https://www.example.com/foo.crx",
- "", "application/x-chrome-extension" },
- { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1,
- "ftp://www.example.com/foo.crx",
- "", "application/x-chrome-extension" },
-
- // some other mimetypes that should get converted
- { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1,
- "http://www.example.com/foo.crx",
- "text/plain", "application/x-chrome-extension" },
- { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1,
- "http://www.example.com/foo.crx",
- "application/octet-stream", "application/x-chrome-extension" },
-
- // success edge cases
- { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1,
- "http://www.example.com/foo.crx?query=string",
- "", "application/x-chrome-extension" },
- { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1,
- "http://www.example.com/foo..crx",
- "", "application/x-chrome-extension" },
-
- // wrong file extension
- { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1,
- "http://www.example.com/foo.bin",
- "", "application/octet-stream" },
- { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1,
- "http://www.example.com/foo.bin?monkey",
- "", "application/octet-stream" },
- { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1,
- "invalid-url",
- "", "application/octet-stream" },
- { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1,
- "http://www.example.com",
- "", "application/octet-stream" },
- { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1,
- "http://www.example.com/",
- "", "application/octet-stream" },
- { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1,
- "http://www.example.com/foo",
- "", "application/octet-stream" },
- { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1,
- "http://www.example.com/foocrx",
- "", "application/octet-stream" },
- { "Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00")-1,
- "http://www.example.com/foo.crx.blech",
- "", "application/octet-stream" },
-
- // wrong magic
- { "Cr24\x02\x00\x00\x01", sizeof("Cr24\x02\x00\x00\x01")-1,
- "http://www.example.com/foo.crx?monkey",
- "", "application/octet-stream" },
- { "PADDING_Cr24\x02\x00\x00\x00", sizeof("PADDING_Cr24\x02\x00\x00\x00")-1,
- "http://www.example.com/foo.crx?monkey",
- "", "application/octet-stream" },
+ // schemes
+ {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1,
+ "http://www.example.com/foo.crx", "", "application/x-chrome-extension"},
+ {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1,
+ "https://www.example.com/foo.crx", "", "application/x-chrome-extension"},
+ {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1,
+ "ftp://www.example.com/foo.crx", "", "application/x-chrome-extension"},
+
+ // some other mimetypes that should get converted
+ {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1,
+ "http://www.example.com/foo.crx", "text/plain",
+ "application/x-chrome-extension"},
+ {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1,
+ "http://www.example.com/foo.crx", "application/octet-stream",
+ "application/x-chrome-extension"},
+
+ // success edge cases
+ {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1,
+ "http://www.example.com/foo.crx?query=string", "",
+ "application/x-chrome-extension"},
+ {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1,
+ "http://www.example.com/foo..crx", "", "application/x-chrome-extension"},
+ {"Cr24\x03\x00\x00\x00", sizeof("Cr24\x03\x00\x00\x00") - 1,
+ "http://www.example.com/foo..crx", "", "application/x-chrome-extension"},
+
+ // wrong file extension
+ {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1,
+ "http://www.example.com/foo.bin", "", "application/octet-stream"},
+ {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1,
+ "http://www.example.com/foo.bin?monkey", "", "application/octet-stream"},
+ {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1,
+ "invalid-url", "", "application/octet-stream"},
+ {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1,
+ "http://www.example.com", "", "application/octet-stream"},
+ {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1,
+ "http://www.example.com/", "", "application/octet-stream"},
+ {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1,
+ "http://www.example.com/foo", "", "application/octet-stream"},
+ {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1,
+ "http://www.example.com/foocrx", "", "application/octet-stream"},
+ {"Cr24\x02\x00\x00\x00", sizeof("Cr24\x02\x00\x00\x00") - 1,
+ "http://www.example.com/foo.crx.blech", "", "application/octet-stream"},
+
+ // wrong magic
+ {"Cr24\x02\x00\x00\x01", sizeof("Cr24\x02\x00\x00\x01") - 1,
+ "http://www.example.com/foo.crx?monkey", "", "application/octet-stream"},
+ {"PADDING_Cr24\x02\x00\x00\x00",
+ sizeof("PADDING_Cr24\x02\x00\x00\x00") - 1,
+ "http://www.example.com/foo.crx?monkey", "", "application/octet-stream"},
};
TestArray(tests, arraysize(tests));
diff --git a/chromium/net/base/mime_util.cc b/chromium/net/base/mime_util.cc
index d97f6cffb68..59cf91ddd92 100644
--- a/chromium/net/base/mime_util.cc
+++ b/chromium/net/base/mime_util.cc
@@ -92,6 +92,7 @@ static const MimeInfo kPrimaryMappings[] = {
{"image/gif", "gif"},
{"image/jpeg", "jpeg,jpg"},
{"image/png", "png"},
+ {"image/apng", "png"},
{"image/webp", "webp"},
{"multipart/related", "mht,mhtml"},
{"text/css", "css"},
diff --git a/chromium/net/base/net_error_list.h b/chromium/net/base/net_error_list.h
index e959b782bc7..c9626316bb8 100644
--- a/chromium/net/base/net_error_list.h
+++ b/chromium/net/base/net_error_list.h
@@ -3,7 +3,9 @@
// found in the LICENSE file.
// This file intentionally does not have header guards, it's included
-// inside a macro to generate enum values.
+// inside a macro to generate enum values. The following line silences a
+// presubmit warning that would otherwise be triggered by this:
+// no-include-guard-because-multiply-included
// This file contains the list of network errors.
@@ -409,7 +411,7 @@ NET_ERROR(NO_BUFFER_SPACE, -176)
// There were no common signature algorithms between our client certificate
// private key and the server's preferences.
-NET_ERROR(SSL_CLIENT_AUTH_NO_COMMON_ALGORITHMS, -1478)
+NET_ERROR(SSL_CLIENT_AUTH_NO_COMMON_ALGORITHMS, -177)
// Certificate error codes
//
diff --git a/chromium/net/base/net_errors.cc b/chromium/net/base/net_errors.cc
index e634d089c66..d35382f214b 100644
--- a/chromium/net/base/net_errors.cc
+++ b/chromium/net/base/net_errors.cc
@@ -4,6 +4,8 @@
#include "net/base/net_errors.h"
+#include "net/quic/core/quic_error_codes.h"
+
namespace net {
const char kErrorDomain[] = "net";
@@ -12,6 +14,15 @@ std::string ErrorToString(int error) {
return "net::" + ErrorToShortString(error);
}
+std::string ExtendedErrorToString(int error, int extended_error_code) {
+ if (error == ERR_QUIC_PROTOCOL_ERROR && extended_error_code != 0) {
+ return std::string("net::ERR_QUIC_PROTOCOL_ERROR.") +
+ QuicErrorCodeToString(
+ static_cast<QuicErrorCode>(extended_error_code));
+ }
+ return ErrorToString(error);
+}
+
std::string ErrorToShortString(int error) {
if (error == 0)
return "OK";
diff --git a/chromium/net/base/net_errors.h b/chromium/net/base/net_errors.h
index 8fe976d4648..9c527023cf4 100644
--- a/chromium/net/base/net_errors.h
+++ b/chromium/net/base/net_errors.h
@@ -36,6 +36,11 @@ NET_EXPORT std::string ErrorToString(int error);
// Same as above, but leaves off the leading "net::".
NET_EXPORT std::string ErrorToShortString(int error);
+// Returns a textual representation of the error code and the extended eror
+// code.
+NET_EXPORT std::string ExtendedErrorToString(int error,
+ int extended_error_code);
+
// Returns true if |error| is a certificate error code.
NET_EXPORT bool IsCertificateError(int error);
diff --git a/chromium/net/base/net_info_source_list.h b/chromium/net/base/net_info_source_list.h
index 4277aba58b6..14a6496c565 100644
--- a/chromium/net/base/net_info_source_list.h
+++ b/chromium/net/base/net_info_source_list.h
@@ -3,7 +3,9 @@
// found in the LICENSE file.
// This file intentionally does not have header guards, it's included
-// inside a macro to generate enum values.
+// inside a macro to generate enum values. The following line silences a
+// presubmit warning that would otherwise be triggered by this:
+// no-include-guard-because-multiply-included
// Flags used to request different types of information about the current state
// of a URLRequestContext.
diff --git a/chromium/net/base/network_config_watcher_mac.cc b/chromium/net/base/network_config_watcher_mac.cc
index bc46c120640..657d1ac33f1 100644
--- a/chromium/net/base/network_config_watcher_mac.cc
+++ b/chromium/net/base/network_config_watcher_mac.cc
@@ -11,15 +11,100 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
+#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
+#include "build/build_config.h"
namespace net {
namespace {
+// SCDynamicStore API does not exist on iOS.
#if !defined(OS_IOS)
+const base::TimeDelta kRetryInterval = base::TimeDelta::FromSeconds(1);
+const int kMaxRetry = 5;
+
+// Maps SCError to an enum for UMA logging. These values are persisted to logs,
+// and should not be renumbered. Added to investigate https://crbug.com/547877.
+enum class SCStatusCode {
+ // Unmapped error codes.
+ SC_UNKNOWN = 0,
+
+ // These map to the corresponding SCError.
+ SC_OK = 1,
+ SC_FAILED = 2,
+ SC_INVALID_ARGUMENT = 3,
+ SC_ACCESS_ERROR = 4,
+ SC_NO_KEY = 5,
+ SC_KEY_EXISTS = 6,
+ SC_LOCKED = 7,
+ SC_NEED_LOCK = 8,
+ SC_NO_STORE_SESSION = 9,
+ SC_NO_STORE_SERVER = 10,
+ SC_NOTIFIER_ACTIVE = 11,
+ SC_NO_PREFS_SESSION = 12,
+ SC_PREFS_BUSY = 13,
+ SC_NO_CONFIG_FILE = 14,
+ SC_NO_LINK = 15,
+ SC_STALE = 16,
+ SC_MAX_LINK = 17,
+ SC_REACHABILITY_UNKNOWN = 18,
+ SC_CONNECTION_NO_SERVICE = 19,
+ SC_CONNECTION_IGNORE = 20,
+
+ // Maximum value for histogram bucket.
+ SC_COUNT,
+};
+
+SCStatusCode ConvertToSCStatusCode(int sc_error) {
+ switch (sc_error) {
+ case kSCStatusOK:
+ return SCStatusCode::SC_OK;
+ case kSCStatusFailed:
+ return SCStatusCode::SC_FAILED;
+ case kSCStatusInvalidArgument:
+ return SCStatusCode::SC_INVALID_ARGUMENT;
+ case kSCStatusAccessError:
+ return SCStatusCode::SC_ACCESS_ERROR;
+ case kSCStatusNoKey:
+ return SCStatusCode::SC_NO_KEY;
+ case kSCStatusKeyExists:
+ return SCStatusCode::SC_KEY_EXISTS;
+ case kSCStatusLocked:
+ return SCStatusCode::SC_LOCKED;
+ case kSCStatusNeedLock:
+ return SCStatusCode::SC_NEED_LOCK;
+ case kSCStatusNoStoreSession:
+ return SCStatusCode::SC_NO_STORE_SESSION;
+ case kSCStatusNoStoreServer:
+ return SCStatusCode::SC_NO_STORE_SERVER;
+ case kSCStatusNotifierActive:
+ return SCStatusCode::SC_NOTIFIER_ACTIVE;
+ case kSCStatusNoPrefsSession:
+ return SCStatusCode::SC_NO_PREFS_SESSION;
+ case kSCStatusPrefsBusy:
+ return SCStatusCode::SC_PREFS_BUSY;
+ case kSCStatusNoConfigFile:
+ return SCStatusCode::SC_NO_CONFIG_FILE;
+ case kSCStatusNoLink:
+ return SCStatusCode::SC_NO_LINK;
+ case kSCStatusStale:
+ return SCStatusCode::SC_STALE;
+ case kSCStatusMaxLink:
+ return SCStatusCode::SC_MAX_LINK;
+ case kSCStatusReachabilityUnknown:
+ return SCStatusCode::SC_REACHABILITY_UNKNOWN;
+ case kSCStatusConnectionNoService:
+ return SCStatusCode::SC_CONNECTION_NO_SERVICE;
+ case kSCStatusConnectionIgnore:
+ return SCStatusCode::SC_CONNECTION_IGNORE;
+ default:
+ return SCStatusCode::SC_UNKNOWN;
+ }
+}
+
// Called back by OS. Calls OnNetworkConfigChange().
void DynamicStoreCallback(SCDynamicStoreRef /* store */,
CFArrayRef changed_keys,
@@ -45,8 +130,14 @@ class NetworkConfigWatcherMacThread : public base::Thread {
// on, so we invoke this function later on in startup to keep it fast.
void InitNotifications();
+ // Returns whether initializing notifications has succeeded.
+ bool InitNotificationsHelper();
+
base::ScopedCFTypeRef<CFRunLoopSourceRef> run_loop_source_;
NetworkConfigWatcherMac::Delegate* const delegate_;
+#if !defined(OS_IOS)
+ int num_retry_;
+#endif // !defined(OS_IOS)
base::WeakPtrFactory<NetworkConfigWatcherMacThread> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(NetworkConfigWatcherMacThread);
@@ -56,7 +147,11 @@ NetworkConfigWatcherMacThread::NetworkConfigWatcherMacThread(
NetworkConfigWatcherMac::Delegate* delegate)
: base::Thread("NetworkConfigWatcher"),
delegate_(delegate),
- weak_factory_(this) {}
+#if !defined(OS_IOS)
+ num_retry_(0),
+#endif // !defined(OS_IOS)
+ weak_factory_(this) {
+}
NetworkConfigWatcherMacThread::~NetworkConfigWatcherMacThread() {
// Allow IO because Stop() calls PlatformThread::Join(), which is a blocking
@@ -89,6 +184,37 @@ void NetworkConfigWatcherMacThread::CleanUp() {
}
void NetworkConfigWatcherMacThread::InitNotifications() {
+ // If initialization fails, retry after a 1s delay.
+ bool success = InitNotificationsHelper();
+
+#if !defined(OS_IOS)
+ if (!success && num_retry_ < kMaxRetry) {
+ LOG(ERROR) << "Retrying SystemConfiguration registration in 1 second.";
+ task_runner()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&NetworkConfigWatcherMacThread::InitNotifications,
+ weak_factory_.GetWeakPtr()),
+ kRetryInterval);
+ num_retry_++;
+ return;
+ }
+
+ // There are kMaxRetry + 2 buckets. The 0 bucket is where no retry is
+ // performed. The kMaxRetry + 1 bucket is where all retries have failed.
+ int histogram_bucket = num_retry_;
+ if (!success) {
+ DCHECK_EQ(kMaxRetry, num_retry_);
+ histogram_bucket = kMaxRetry + 1;
+ }
+ UMA_HISTOGRAM_EXACT_LINEAR(
+ "Net.NetworkConfigWatcherMac.SCDynamicStore.NumRetry", histogram_bucket,
+ kMaxRetry + 2);
+#else
+ DCHECK(success);
+#endif // !defined(OS_IOS)
+}
+
+bool NetworkConfigWatcherMacThread::InitNotificationsHelper() {
#if !defined(OS_IOS)
// SCDynamicStore API does not exist on iOS.
// Add a run loop source for a dynamic store to the current run loop.
@@ -101,8 +227,26 @@ void NetworkConfigWatcherMacThread::InitNotifications() {
};
base::ScopedCFTypeRef<SCDynamicStoreRef> store(SCDynamicStoreCreate(
NULL, CFSTR("org.chromium"), DynamicStoreCallback, &context));
+ if (!store) {
+ int error = SCError();
+ LOG(ERROR) << "SCDynamicStoreCreate failed with Error: " << error << " - "
+ << SCErrorString(error);
+ UMA_HISTOGRAM_ENUMERATION(
+ "Net.NetworkConfigWatcherMac.SCDynamicStore.Create",
+ ConvertToSCStatusCode(error), SCStatusCode::SC_COUNT);
+ return false;
+ }
run_loop_source_.reset(SCDynamicStoreCreateRunLoopSource(
NULL, store.get(), 0));
+ if (!run_loop_source_) {
+ int error = SCError();
+ LOG(ERROR) << "SCDynamicStoreCreateRunLoopSource failed with Error: "
+ << error << " - " << SCErrorString(error);
+ UMA_HISTOGRAM_ENUMERATION(
+ "Net.NetworkConfigWatcherMac.SCDynamicStore.Create.RunLoopSource",
+ ConvertToSCStatusCode(error), SCStatusCode::SC_COUNT);
+ return false;
+ }
CFRunLoopAddSource(CFRunLoopGetCurrent(), run_loop_source_.get(),
kCFRunLoopCommonModes);
#endif // !defined(OS_IOS)
@@ -112,6 +256,7 @@ void NetworkConfigWatcherMacThread::InitNotifications() {
#if !defined(OS_IOS)
delegate_->SetDynamicStoreNotificationKeys(store.get());
#endif // !defined(OS_IOS)
+ return true;
}
} // namespace
diff --git a/chromium/net/base/network_config_watcher_mac.h b/chromium/net/base/network_config_watcher_mac.h
index 8157d476975..7e5ed593515 100644
--- a/chromium/net/base/network_config_watcher_mac.h
+++ b/chromium/net/base/network_config_watcher_mac.h
@@ -5,7 +5,7 @@
#ifndef NET_BASE_NETWORK_CONFIG_WATCHER_MAC_H_
#define NET_BASE_NETWORK_CONFIG_WATCHER_MAC_H_
-#include <SystemConfiguration/SCDynamicStore.h>
+#include <SystemConfiguration/SystemConfiguration.h>
#include <memory>
diff --git a/chromium/net/base/network_interfaces.h b/chromium/net/base/network_interfaces.h
index d3d9f4e03b5..538adb27e66 100644
--- a/chromium/net/base/network_interfaces.h
+++ b/chromium/net/base/network_interfaces.h
@@ -86,8 +86,11 @@ enum HostAddressSelectionPolicy {
NET_EXPORT bool GetNetworkList(NetworkInterfaceList* networks,
int policy);
-// Gets the SSID of the currently associated WiFi access point if there is one.
-// Otherwise, returns empty string.
+// Gets the SSID of the currently associated WiFi access point if there is one,
+// and it is available. SSID may not be available if the app does not have
+// permissions to access it. On Android M+, the app accessing SSID needs to have
+// ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION. If there is no WiFi access
+// point or its SSID is unavailable, an empty string is returned.
// Currently only implemented on Linux, ChromeOS, Android and Windows.
NET_EXPORT std::string GetWifiSSID();
diff --git a/chromium/net/base/network_interfaces_fuchsia.cc b/chromium/net/base/network_interfaces_fuchsia.cc
index 61c9e806904..65ef4f84f2e 100644
--- a/chromium/net/base/network_interfaces_fuchsia.cc
+++ b/chromium/net/base/network_interfaces_fuchsia.cc
@@ -18,37 +18,38 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
return false;
}
- netc_get_if_info_t netconfig;
- int size = ioctl_netc_get_if_info(s, &netconfig);
- PCHECK(close(s) == 0);
-
- if (size < 0) {
- PLOG(ERROR) << "ioctl_netc_get_if_info";
+ uint32_t num_ifs = 0;
+ if (ioctl_netc_get_num_ifs(s, &num_ifs) < 0) {
+ PLOG(ERROR) << "ioctl_netc_get_num_ifs";
+ PCHECK(close(s) == 0);
return false;
}
- networks->clear();
+ for (uint32_t i = 0; i < num_ifs; ++i) {
+ netc_if_info_t interface;
- for (size_t i = 0; i < netconfig.n_info; ++i) {
- netc_if_info_t* interface = netconfig.info + i;
+ if (ioctl_netc_get_if_info_at(s, &i, &interface) < 0) {
+ PLOG(WARNING) << "ioctl_netc_get_if_info_at";
+ continue;
+ }
// Skip loopback addresses.
if (internal::IsLoopbackOrUnspecifiedAddress(
- reinterpret_cast<sockaddr*>(&(interface->addr)))) {
+ reinterpret_cast<sockaddr*>(&(interface.addr)))) {
continue;
}
IPEndPoint address;
- if (!address.FromSockAddr(reinterpret_cast<sockaddr*>(&(interface->addr)),
- sizeof(interface->addr))) {
+ if (!address.FromSockAddr(reinterpret_cast<sockaddr*>(&(interface.addr)),
+ sizeof(interface.addr))) {
DLOG(WARNING) << "ioctl_netc_get_if_info returned invalid address.";
continue;
}
int prefix_length = 0;
IPEndPoint netmask;
- if (netmask.FromSockAddr(reinterpret_cast<sockaddr*>(&(interface->netmask)),
- sizeof(interface->netmask))) {
+ if (netmask.FromSockAddr(reinterpret_cast<sockaddr*>(&(interface.netmask)),
+ sizeof(interface.netmask))) {
prefix_length = MaskPrefixLength(netmask.address());
}
@@ -58,11 +59,13 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
int attributes = 0;
networks->push_back(
- NetworkInterface(interface->name, interface->name, interface->index,
+ NetworkInterface(interface.name, interface.name, interface.index,
NetworkChangeNotifier::CONNECTION_UNKNOWN,
address.address(), prefix_length, attributes));
}
+ PCHECK(close(s) == 0);
+
return true;
}
diff --git a/chromium/net/base/network_throttle_manager.h b/chromium/net/base/network_throttle_manager.h
deleted file mode 100644
index 96a864e6784..00000000000
--- a/chromium/net/base/network_throttle_manager.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_BASE_NETWORK_THROTTLE_MANAGER_H_
-#define NET_BASE_NETWORK_THROTTLE_MANAGER_H_
-
-#include <memory>
-
-#include "base/memory/weak_ptr.h"
-#include "net/base/net_export.h"
-#include "net/base/request_priority.h"
-
-namespace net {
-
-// This class controls throttling based on priority level and number of
-// outstanding requests. It vends Throttle objects, and tracks
-// outstanding requests by the lifetime of those objects. Consumers
-// determine whether or not they are throttled by consulting those
-// Throttle objects.
-//
-// This class must outlive all Throttles created from it via CreateThrottle().
-//
-// Methods are virtual to allow for test mocks.
-class NET_EXPORT_PRIVATE NetworkThrottleManager {
- public:
- class Throttle;
-
- // Abstract base class other classes can inherit from to get
- // notifications from throttle state changes.
- class NET_EXPORT_PRIVATE ThrottleDelegate {
- public:
- // Called when a throttle is unblocked.
- //
- // Note that this call may occur as the result of either a call to
- // Throttle::SetPriority (on the throttle related to this delegate
- // or another throttle) or the destruction of a Throttle, and if
- // so will occur synchronously during those events. It will not
- // be called from the destructor of the Throttle associated with
- // the ThrottleDelegate.
- virtual void OnThrottleUnblocked(Throttle* throttle) = 0;
-
- protected:
- virtual ~ThrottleDelegate() {}
- };
-
- // Class owned by external stream representations that
- // routes notifications. It may be constructed in either the
- // blocked or unblocked state according to the state of the
- // NetworkThrottleManager; if it's constructed in the unblocked
- // state, it will only make a single transition to unblocked,
- // which will be signaled by delegate->OnThrottleUnblocked(this).
- // If it's constructed in the unblocked state, it will remain
- // there.
- class NET_EXPORT_PRIVATE Throttle {
- public:
- virtual ~Throttle() {}
-
- virtual bool IsBlocked() const = 0;
-
- virtual RequestPriority Priority() const = 0;
-
- // Note that this may result in a possibly reentrant call to
- // |ThrottleDelegate::OnThrottleUnblocked|, as well as the resumption
- // of this or other requests, which may result in request completion
- // and destruction before return. Any caller of this function
- // should not rely on this object or containing objects surviving
- // this call.
- //
- // This call is a no-op if the priority is set to its current value.
- virtual void SetPriority(RequestPriority priority) = 0;
-
- protected:
- Throttle() {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Throttle);
- };
-
- virtual ~NetworkThrottleManager() {}
-
- // Caller must ensure that |*delegate| outlives the returned
- // Throttle.
- virtual std::unique_ptr<Throttle> CreateThrottle(ThrottleDelegate* delegate,
- RequestPriority priority,
- bool ignore_limits) = 0;
-
- protected:
- NetworkThrottleManager() {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(NetworkThrottleManager);
-};
-
-} // namespace net
-
-#endif // NET_BASE_NETWORK_THROTTLE_MANAGER_H_
diff --git a/chromium/net/base/network_throttle_manager_impl.cc b/chromium/net/base/network_throttle_manager_impl.cc
index 5e33729b8f7..cd62444c522 100644
--- a/chromium/net/base/network_throttle_manager_impl.cc
+++ b/chromium/net/base/network_throttle_manager_impl.cc
@@ -188,7 +188,7 @@ NetworkThrottleManagerImpl::CreateThrottle(
}
void NetworkThrottleManagerImpl::SetTickClockForTesting(
- base::TickClock* tick_clock) {
+ const base::TickClock* tick_clock) {
tick_clock_ = tick_clock;
DCHECK(!outstanding_recomputation_timer_->IsRunning());
outstanding_recomputation_timer_ = std::make_unique<base::Timer>(
diff --git a/chromium/net/base/network_throttle_manager_impl.h b/chromium/net/base/network_throttle_manager_impl.h
index 620da459931..cb1bfe4be7b 100644
--- a/chromium/net/base/network_throttle_manager_impl.h
+++ b/chromium/net/base/network_throttle_manager_impl.h
@@ -71,7 +71,7 @@ class NET_EXPORT NetworkThrottleManagerImpl : public NetworkThrottleManager {
RequestPriority priority,
bool ignore_limits) override;
- void SetTickClockForTesting(base::TickClock* tick_clock);
+ void SetTickClockForTesting(const base::TickClock* tick_clock);
// If the |NowTicks()| value of |tick_clock_| is greater than the
// time the outstanding_recomputation_timer_ has set to go off, Stop()
@@ -140,7 +140,7 @@ class NET_EXPORT NetworkThrottleManagerImpl : public NetworkThrottleManager {
ThrottleList blocked_throttles_;
// For testing.
- base::TickClock* tick_clock_;
+ const base::TickClock* tick_clock_;
base::WeakPtrFactory<NetworkThrottleManagerImpl> weak_ptr_factory_;
diff --git a/chromium/net/base/network_throttle_manager_impl_unittest.cc b/chromium/net/base/network_throttle_manager_impl_unittest.cc
deleted file mode 100644
index 713b2680d13..00000000000
--- a/chromium/net/base/network_throttle_manager_impl_unittest.cc
+++ /dev/null
@@ -1,564 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/base/network_throttle_manager_impl.h"
-
-#include <memory>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
-#include "base/run_loop.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "base/test/test_message_loop.h"
-#include "net/base/request_priority.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-
-namespace {
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-const int kInitialAgeHorizonForUncountedRequests =
- (NetworkThrottleManagerImpl::kInitialMedianInMs *
- NetworkThrottleManagerImpl::kMedianLifetimeMultiple);
-
-// Must be greater than the corresponding fudge factor in
-// network_throttle_manager_impl.cc.
-const int kAgeHorizonFudgeFactor = 20;
-
-// Test fixture for throttle manager tests.
-
-// Note that the manager owned and managed by this fixture has a clock
-// that is set to base::TimeTicks::Now() (which value is also exposed
-// via an accessor) on creation but does not change without
-// intervention by tests (to make the tests more predictable).
-//
-// HOWEVER, also note that that manager uses the base::Timer class, which
-// uses the system clock, which isn't affected by the setting of the
-// test fixture clock. So test should be written to a) avoid situations
-// in which the manager's timer will actually go off based on the system
-// clock, and b) call ConditionallyTriggerTimerForTesting() (which does
-// evaluate the manager's clock) when timer based tests are necessary.
-class NetworkThrottleManagerTest : public testing::Test,
- NetworkThrottleManager::ThrottleDelegate {
- public:
- NetworkThrottleManagerTest()
- : now_(base::TimeTicks::Now()),
- throttle_state_change_count_(0),
- last_throttle_to_change_state_(nullptr),
- throttle_manager_(new NetworkThrottleManagerImpl) {
- clock_.SetNowTicks(now_);
- throttle_manager_->SetTickClockForTesting(&clock_);
- }
-
- protected:
- enum ExpectedThrottleBlockState { BLOCKED, UNBLOCKED };
-
- base::TimeTicks now() { return now_; }
- NetworkThrottleManagerImpl* throttle_manager() {
- return throttle_manager_.get();
- }
-
- // Set the offset of the test clock from now_.
- void SetClockDelta(base::TimeDelta time_delta) {
- clock_.SetNowTicks(now_ + time_delta);
- }
-
- // Throttle creation
- std::unique_ptr<NetworkThrottleManager::Throttle> CreateThrottle(
- net::RequestPriority priority,
- ExpectedThrottleBlockState throttle_state) {
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle(
- throttle_manager_->CreateThrottle(this, priority, false));
- EXPECT_EQ(throttle_state == BLOCKED, throttle->IsBlocked());
- return throttle;
- }
- std::unique_ptr<NetworkThrottleManager::Throttle>
- CreateThrottleIgnoringLimits(net::RequestPriority priority) {
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle(
- throttle_manager_->CreateThrottle(this, priority, true));
- EXPECT_FALSE(throttle->IsBlocked());
- return throttle;
- }
-
- // Throttle state change information.
- int throttle_state_change_count() { return throttle_state_change_count_; }
- NetworkThrottleManager::Throttle* last_throttle_to_change_state() {
- return last_throttle_to_change_state_;
- }
-
- // Setting a callback to be invoked when a throttle's state changes.
- void SetThrottleStateChangedCallback(const base::Closure& callback) {
- throttle_state_changed_callback_ = callback;
- }
-
- private:
- // NetworkThrottleManager::Delegate
- void OnThrottleUnblocked(
- NetworkThrottleManager::Throttle* throttle) override {
- ++throttle_state_change_count_;
- last_throttle_to_change_state_ = throttle;
- if (!throttle_state_changed_callback_.is_null())
- base::ResetAndReturn(&throttle_state_changed_callback_).Run();
- }
-
- base::SimpleTestTickClock clock_;
- base::TimeTicks now_;
- int throttle_state_change_count_;
- NetworkThrottleManager::Throttle* last_throttle_to_change_state_;
- std::unique_ptr<NetworkThrottleManagerImpl> throttle_manager_;
- base::Closure throttle_state_changed_callback_;
-
- DISALLOW_COPY_AND_ASSIGN(NetworkThrottleManagerTest);
-};
-
-// Check to confirm that all created throttles at priorities other than
-// THROTTLED start unblocked.
-TEST_F(NetworkThrottleManagerTest, AllUnthrottled) {
- for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
- if (i == THROTTLED)
- continue;
- CreateThrottle(static_cast<RequestPriority>(i), UNBLOCKED);
- }
-}
-
-// Check for basic semantics around the new THROTTLED level.
-TEST_F(NetworkThrottleManagerTest, ThrottledBlocking) {
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle1(
- CreateThrottle(THROTTLED, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle2(
- CreateThrottle(THROTTLED, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle3(
- CreateThrottle(THROTTLED, BLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle4(
- CreateThrottle(THROTTLED, BLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle5(
- CreateThrottle(THROTTLED, BLOCKED));
-
- EXPECT_EQ(0, throttle_state_change_count());
-
- throttle1.reset();
- base::RunLoop().RunUntilIdle(); // Allow posttasks to run.
- EXPECT_EQ(1, throttle_state_change_count());
- EXPECT_EQ(throttle3.get(), last_throttle_to_change_state());
-
- EXPECT_FALSE(throttle3->IsBlocked());
- EXPECT_TRUE(throttle4->IsBlocked());
- EXPECT_TRUE(throttle5->IsBlocked());
-
- throttle2.reset();
- base::RunLoop().RunUntilIdle(); // Allow posttasks to run.
- EXPECT_EQ(2, throttle_state_change_count());
- EXPECT_EQ(throttle4.get(), last_throttle_to_change_state());
-
- EXPECT_FALSE(throttle3->IsBlocked());
- EXPECT_FALSE(throttle4->IsBlocked());
- EXPECT_TRUE(throttle5->IsBlocked());
-}
-
-// Check that THROTTLED semantics are dependent on all outstanding requests.
-TEST_F(NetworkThrottleManagerTest, ThrottledBlockingMultiPriority) {
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle1(
- CreateThrottle(HIGHEST, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle2(
- CreateThrottle(LOW, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle3(
- CreateThrottle(IDLE, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle4(
- CreateThrottle(THROTTLED, BLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle5(
- CreateThrottle(THROTTLED, BLOCKED));
-
- EXPECT_EQ(0, throttle_state_change_count());
-
- throttle1.reset();
- base::RunLoop().RunUntilIdle(); // Allow posttasks to run.
- EXPECT_EQ(0, throttle_state_change_count());
- EXPECT_FALSE(throttle3->IsBlocked());
- EXPECT_TRUE(throttle4->IsBlocked());
- EXPECT_TRUE(throttle5->IsBlocked());
-
- throttle2.reset();
- base::RunLoop().RunUntilIdle(); // Allow posttasks to run.
- EXPECT_EQ(1, throttle_state_change_count());
- EXPECT_EQ(throttle4.get(), last_throttle_to_change_state());
-
- EXPECT_FALSE(throttle3->IsBlocked());
- EXPECT_FALSE(throttle4->IsBlocked());
- EXPECT_TRUE(throttle5->IsBlocked());
-
- throttle3.reset();
- base::RunLoop().RunUntilIdle(); // Allow posttasks to run.
- EXPECT_EQ(2, throttle_state_change_count());
- EXPECT_EQ(throttle5.get(), last_throttle_to_change_state());
-
- EXPECT_FALSE(throttle4->IsBlocked());
- EXPECT_FALSE(throttle5->IsBlocked());
-}
-
-// Check that a SetPriority() away from THROTTLED results in unblocking
-// and an upcall.
-TEST_F(NetworkThrottleManagerTest, ThrottledSetPriority) {
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle1(
- CreateThrottle(THROTTLED, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle2(
- CreateThrottle(THROTTLED, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle3(
- CreateThrottle(THROTTLED, BLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle4(
- CreateThrottle(THROTTLED, BLOCKED));
-
- EXPECT_EQ(0, throttle_state_change_count());
-
- throttle3->SetPriority(LOW);
- EXPECT_EQ(1, throttle_state_change_count());
- EXPECT_EQ(throttle3.get(), last_throttle_to_change_state());
- EXPECT_FALSE(throttle3->IsBlocked());
- EXPECT_TRUE(throttle4->IsBlocked());
-}
-
-void ResetThrottles(
- bool* function_called,
- std::vector<std::unique_ptr<NetworkThrottleManager::Throttle>> throttles) {
- *function_called = true;
- // All pointers in the vector should be deleted on exit.
-}
-
-// Check that tearing down all elements in the NTM on a SetPriority
-// upcall doesn't create any problems.
-TEST_F(NetworkThrottleManagerTest, ThrottleTeardown) {
- std::vector<std::unique_ptr<NetworkThrottleManager::Throttle>> throttles;
-
- throttles.push_back(CreateThrottle(THROTTLED, UNBLOCKED));
- throttles.push_back(CreateThrottle(THROTTLED, UNBLOCKED));
-
- // Note that if there is more than one throttle blocked, then the
- // number of throttle state changes is dependent on destruction order.
- // So only one blocked throttle is created.
- auto throttle_temporary = CreateThrottle(THROTTLED, BLOCKED);
- NetworkThrottleManager::Throttle* throttle3 = throttle_temporary.get();
- throttles.push_back(std::move(throttle_temporary));
-
- bool callback_called(false);
- SetThrottleStateChangedCallback(
- base::Bind(&ResetThrottles, &callback_called, base::Passed(&throttles)));
-
- EXPECT_EQ(0, throttle_state_change_count());
-
- throttle3->SetPriority(LOW);
-
- // If the test is functioning as expected, throttle3 now points to
- // a deleted object and can no longer be indirected through.
-
- EXPECT_TRUE(callback_called);
- EXPECT_EQ(1, throttle_state_change_count());
- EXPECT_EQ(throttle3, last_throttle_to_change_state());
-}
-
-// Note that this routine is dependent on priority setting *not* resulting in
-// destruction of any throttle and should only be used in tests where that is
-// true.
-void SetAllToPriority(
- RequestPriority priority,
- std::vector<NetworkThrottleManager::Throttle*> throttles) {
- for (size_t i = 0; i < throttles.size(); ++i)
- throttles[i]->SetPriority(priority);
-}
-
-// Check that modifying all the priorities of the allocated throttles in
-// the callback works properly.
-TEST_F(NetworkThrottleManagerTest, ThrottlePriorityReset) {
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle1(
- CreateThrottle(THROTTLED, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle2(
- CreateThrottle(THROTTLED, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle3(
- CreateThrottle(THROTTLED, BLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle4(
- CreateThrottle(THROTTLED, BLOCKED));
-
- std::vector<NetworkThrottleManager::Throttle*> throttles;
- throttles.push_back(throttle1.get());
- throttles.push_back(throttle2.get());
- throttles.push_back(throttle3.get());
-
- SetThrottleStateChangedCallback(
- base::Bind(&SetAllToPriority, MEDIUM, base::Passed(&throttles)));
-
- EXPECT_EQ(0, throttle_state_change_count());
- throttle3->SetPriority(HIGHEST);
-
- // Expected result: throttles 1-3 @ medium priority (the callback should
- // have overridden the priority setting above), only throttle 4 blocked
- // (throttle3 should have been unblocked by either of the priority changes),
- // and one state changes (the unblocking).
- EXPECT_EQ(MEDIUM, throttle1->Priority());
- EXPECT_EQ(MEDIUM, throttle2->Priority());
- EXPECT_EQ(MEDIUM, throttle3->Priority());
- EXPECT_EQ(THROTTLED, throttle4->Priority());
- EXPECT_FALSE(throttle1->IsBlocked());
- EXPECT_FALSE(throttle2->IsBlocked());
- EXPECT_FALSE(throttle3->IsBlocked());
- EXPECT_TRUE(throttle4->IsBlocked());
- EXPECT_EQ(1, throttle_state_change_count());
-}
-
-// Check that modifying the priority of a request from a non-THROTTLED
-// value to THROTTLED causes no change in behavior.
-TEST_F(NetworkThrottleManagerTest, ThrottlePriorityResetToThrottled) {
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle1(
- CreateThrottle(THROTTLED, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle2(
- CreateThrottle(THROTTLED, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle3(
- CreateThrottle(LOW, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle4(
- CreateThrottle(THROTTLED, BLOCKED));
-
- EXPECT_EQ(0, throttle_state_change_count());
- throttle3->SetPriority(THROTTLED);
- EXPECT_EQ(0, throttle_state_change_count());
-
- EXPECT_FALSE(throttle1->IsBlocked());
- EXPECT_FALSE(throttle2->IsBlocked());
- EXPECT_FALSE(throttle3->IsBlocked());
- EXPECT_TRUE(throttle4->IsBlocked());
-
- EXPECT_EQ(THROTTLED, throttle1->Priority());
- EXPECT_EQ(THROTTLED, throttle2->Priority());
- EXPECT_EQ(THROTTLED, throttle3->Priority());
- EXPECT_EQ(THROTTLED, throttle4->Priority());
-}
-
-// Confirm that old requests don't count against the limit.
-TEST_F(NetworkThrottleManagerTest, DontCountAgedRequests) {
- const int age_in_days_of_old_throttles = 4;
-
- // Confirm default median and timing means that 4 days is long enough ago
- // to be aged out.
- EXPECT_GT(age_in_days_of_old_throttles * 24 * 60 * 60 * 1000,
- kInitialAgeHorizonForUncountedRequests);
-
- SetClockDelta(-base::TimeDelta::FromDays(age_in_days_of_old_throttles));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle1(
- CreateThrottle(IDLE, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle2(
- CreateThrottle(IDLE, UNBLOCKED));
-
- SetClockDelta(base::TimeDelta());
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle3(
- CreateThrottle(LOW, UNBLOCKED));
-
- // First throttled request should not be blocked.
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle4(
- CreateThrottle(THROTTLED, UNBLOCKED));
-
- // Second should be.
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle5(
- CreateThrottle(THROTTLED, BLOCKED));
-
- // Destroying the old requests should not result in any upcalls.
- EXPECT_EQ(0, throttle_state_change_count());
- throttle1.reset();
- base::RunLoop().RunUntilIdle(); // Allow posttasks to run.
- EXPECT_EQ(0, throttle_state_change_count());
- throttle2.reset();
- base::RunLoop().RunUntilIdle(); // Allow posttasks to run.
- EXPECT_EQ(0, throttle_state_change_count());
-
- // But destroying a new request should result in a state change.
- throttle3.reset();
- base::RunLoop().RunUntilIdle(); // Allow posttasks to run.
- EXPECT_EQ(1, throttle_state_change_count());
- EXPECT_EQ(throttle5.get(), last_throttle_to_change_state());
-}
-
-// Confirm that a slew of throttles of a specific age will shift the
-// median for determining "aged requests" to that age.
-TEST_F(NetworkThrottleManagerTest, ShiftMedian) {
- // Setup two throttles of age *just short* of aging out; confirm
- // they result in blocked THROTTLED requests.
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle1(
- CreateThrottle(IDLE, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle2(
- CreateThrottle(IDLE, UNBLOCKED));
- SetClockDelta(base::TimeDelta::FromMilliseconds(
- kInitialAgeHorizonForUncountedRequests - 1));
- EXPECT_FALSE(throttle_manager()->ConditionallyTriggerTimerForTesting());
-
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle3(
- CreateThrottle(THROTTLED, BLOCKED));
-
- throttle1.reset();
- throttle2.reset();
- throttle3.reset();
- base::RunLoop().RunUntilIdle(); // Allow posttasks to run.
-
- // Create 100 throttles and destroy them, effectively with lifetime zero.
- // This should substantially decrease the median age estimate.
- SetClockDelta(base::TimeDelta());
- for (int i = 0; i < 100; ++i) {
- std::unique_ptr<NetworkThrottleManager::Throttle> tmp(
- CreateThrottle(IDLE, UNBLOCKED));
- }
-
- // Clear out any possible leftover timer by setting the clock to a point
- // in the future at which it will definitely go off, and triggering it.
- SetClockDelta(base::TimeDelta::FromMilliseconds(
- 2 * kInitialAgeHorizonForUncountedRequests + kAgeHorizonFudgeFactor));
- throttle_manager()->ConditionallyTriggerTimerForTesting();
-
- // The identical test above should no longer result in blocked throttles.
- SetClockDelta(base::TimeDelta());
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle5(
- CreateThrottle(IDLE, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle6(
- CreateThrottle(IDLE, UNBLOCKED));
- SetClockDelta(base::TimeDelta::FromMilliseconds(
- kInitialAgeHorizonForUncountedRequests - 1));
- EXPECT_TRUE(throttle_manager()->ConditionallyTriggerTimerForTesting());
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle7(
- CreateThrottle(THROTTLED, UNBLOCKED));
-}
-
-// Confirm that just "aging out" requests will result in unblocking
-// blocked requests.
-TEST_F(NetworkThrottleManagerTest, AgeInvalidThrottles) {
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle1(
- CreateThrottle(IDLE, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle2(
- CreateThrottle(IDLE, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle3(
- CreateThrottle(THROTTLED, BLOCKED));
-
- EXPECT_EQ(0, throttle_state_change_count());
- SetClockDelta(base::TimeDelta::FromMilliseconds(
- kInitialAgeHorizonForUncountedRequests + kAgeHorizonFudgeFactor));
- EXPECT_TRUE(throttle_manager()->ConditionallyTriggerTimerForTesting());
- EXPECT_EQ(1, throttle_state_change_count());
- EXPECT_EQ(throttle3.get(), last_throttle_to_change_state());
- EXPECT_FALSE(throttle3->IsBlocked());
-}
-
-// Confirm that if throttles are unblocked and made active by all
-// existing outstanding throttles aging out, they will also eventually
-// age out and let new throttles through.
-TEST_F(NetworkThrottleManagerTest, NewlyUnblockedThrottlesAlsoAge) {
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle1(
- CreateThrottle(IDLE, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle2(
- CreateThrottle(IDLE, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle3(
- CreateThrottle(THROTTLED, BLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle4(
- CreateThrottle(THROTTLED, BLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle5(
- CreateThrottle(THROTTLED, BLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle6(
- CreateThrottle(THROTTLED, BLOCKED));
-
- // Age the first two throttles out of the outstanding, which should
- // result in the next two throttles becoming unblocked (and in the
- // oustanding list). (The internal implementation will zero out
- // the outstanding queue and then add in the two new unblocked throttles.)
- EXPECT_EQ(0, throttle_state_change_count());
- SetClockDelta(base::TimeDelta::FromMilliseconds(
- kInitialAgeHorizonForUncountedRequests + kAgeHorizonFudgeFactor));
- EXPECT_TRUE(throttle_manager()->ConditionallyTriggerTimerForTesting());
- EXPECT_EQ(2, throttle_state_change_count());
- EXPECT_FALSE(throttle3->IsBlocked());
- EXPECT_FALSE(throttle4->IsBlocked());
-
- // Age the next two throttles out of the outstanding queue, which
- // should result in the next two throttles becoming unblocked (and
- // in the oustanding list). This will only happen if a timer was properly
- // set in the above age process as the oustanding queue went through
- // the empty state.
- SetClockDelta(base::TimeDelta::FromMilliseconds(
- 2 * (kInitialAgeHorizonForUncountedRequests + kAgeHorizonFudgeFactor)));
- EXPECT_TRUE(throttle_manager()->ConditionallyTriggerTimerForTesting());
- EXPECT_EQ(4, throttle_state_change_count());
- EXPECT_FALSE(throttle5->IsBlocked());
- EXPECT_FALSE(throttle6->IsBlocked());
-}
-
-// Confirm that throttles that are blocked for a while and then
-// unblocked don't "age out".
-TEST_F(NetworkThrottleManagerTest, AgeBlockedThrottles) {
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle1(
- CreateThrottle(IDLE, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle2(
- CreateThrottle(IDLE, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle3(
- CreateThrottle(THROTTLED, BLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle4(
- CreateThrottle(THROTTLED, BLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle5(
- CreateThrottle(THROTTLED, BLOCKED));
-
- EXPECT_EQ(0, throttle_state_change_count());
- SetClockDelta(base::TimeDelta::FromMilliseconds(
- kInitialAgeHorizonForUncountedRequests + kAgeHorizonFudgeFactor));
- EXPECT_TRUE(throttle_manager()->ConditionallyTriggerTimerForTesting());
-
- // If blocked throttles aged out, all three throttles should have been
- // unblocked. If not, only the two replacing the IDLE throttles should
- // have.
- EXPECT_EQ(2, throttle_state_change_count());
-}
-
-// Confirm that deleting old throttles before they age out doesn't
-// interfere with the aging out of more recent throttles.
-TEST_F(NetworkThrottleManagerTest, DeletionAgingInterference) {
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle1(
- CreateThrottle(IDLE, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle2(
- CreateThrottle(IDLE, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle3(
- CreateThrottle(THROTTLED, BLOCKED));
- EXPECT_EQ(0, throttle_state_change_count());
-
- SetClockDelta(base::TimeDelta::FromMilliseconds(
- kInitialAgeHorizonForUncountedRequests / 2));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle4(
- CreateThrottle(IDLE, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle5(
- CreateThrottle(IDLE, UNBLOCKED));
- EXPECT_FALSE(throttle_manager()->ConditionallyTriggerTimerForTesting());
- EXPECT_EQ(0, throttle_state_change_count());
-
- throttle1.reset();
- throttle2.reset();
- EXPECT_FALSE(throttle_manager()->ConditionallyTriggerTimerForTesting());
- EXPECT_EQ(0, throttle_state_change_count());
-
- SetClockDelta(base::TimeDelta::FromMilliseconds(
- (3 * kInitialAgeHorizonForUncountedRequests / 2 +
- 2 * kAgeHorizonFudgeFactor)));
- EXPECT_TRUE(throttle_manager()->ConditionallyTriggerTimerForTesting());
- EXPECT_EQ(1, throttle_state_change_count());
- EXPECT_EQ(throttle3.get(), last_throttle_to_change_state());
- EXPECT_FALSE(throttle3->IsBlocked());
-}
-
-// Confirm that "ignore_limits" boolean is respected.
-TEST_F(NetworkThrottleManagerTest, IgnoreLimits) {
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle1(
- CreateThrottle(HIGHEST, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle2(
- CreateThrottle(LOW, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle3(
- CreateThrottle(IDLE, UNBLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle4(
- CreateThrottle(THROTTLED, BLOCKED));
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle5(
- CreateThrottleIgnoringLimits(THROTTLED));
-}
-
-} // namespace
-
-} // namespace net
diff --git a/chromium/net/base/percentile_estimator.cc b/chromium/net/base/percentile_estimator.cc
deleted file mode 100644
index 216d6e6ee60..00000000000
--- a/chromium/net/base/percentile_estimator.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "percentile_estimator.h"
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/rand_util.h"
-
-namespace {
-
-// Random number wrapper to allow substitutions for testing.
-int GenerateRand0To99() {
- return base::RandInt(0, 99);
-}
-
-} // namespace
-
-namespace net {
-
-// The algorithm used for percentile estimation is "Algorithm 3" from
-// https://arxiv.org/pdf/1407.1121v1.pdf. There are several parts to the
-// algorithm:
-// * The estimate is conditionally moved towards the sample by a step amount.
-// This means that if the samples are clustered around a value the estimates
-// will converge to that sample.
-// * The percentile requested (e.g. 90%l) is handled by the conditional move.
-// If the estimate is accurate, there is a chance equal to the percentile
-// value that a sample will be lower than it, and a chance equal to
-// 1-percentile that it will be higher. So the code balances those
-// probabilities by increasing the estimate in the percentile fraction
-// of the cases where the sample is over the estimate, and decreases the
-// estimate in (1-percentile) fraction of the cases where the sample is under
-// the estimate.
-// E.g. in the case of the 90%l estimation, the estimate would
-// move up in 90% of the cases in which the sample was above the
-// estimate (which would be 10% of the total samples, presuming the
-// estimate was accurate), and it would move down in 10% of the cases
-// in which the sample was below the estimate.
-// * Every time the estimate moves in the same direction, the step
-// amount is increased by one, and every time the estimate reverses
-// direction, the step amount is decreased (to 1, if greater than 1,
-// by one, if zero or negative). The effective step amount is
-// Max(step, 1).
-// * If the estimate
-// would be moved beyond the sample causing its move, it is moved to
-// be equal to the same (and the step amount set to the distance to
-// the sample). See the paper for further details.
-
-PercentileEstimator::PercentileEstimator(int percentile, int initial_estimate)
- : percentile_(percentile),
- sign_positive_(true),
- current_estimate_(initial_estimate),
- current_step_(1),
- generator_callback_(base::Bind(&GenerateRand0To99)) {}
-
-PercentileEstimator::~PercentileEstimator() = default;
-
-void PercentileEstimator::AddSample(int sample) {
- int rand100 = generator_callback_.Run();
- if (sample > current_estimate_ && rand100 > 1 - percentile_) {
- current_step_ += sign_positive_ ? 1 : -1;
- current_estimate_ += (current_step_ > 0) ? current_step_ : 1;
-
- // Clamp movement to distance to sample.
- if (current_estimate_ > sample) {
- current_step_ -= current_estimate_ - sample;
- current_estimate_ = sample;
- }
-
- // If we've reversed direction, reset the step down.
- if (!sign_positive_ && current_step_ > 1)
- current_step_ = 1;
-
- sign_positive_ = true;
- } else if (sample < current_estimate_ && rand100 > percentile_) {
- current_step_ += !sign_positive_ ? 1 : -1;
- current_estimate_ -= (current_step_ > 0) ? current_step_ : 1;
-
- // Clamp movement to distance to sample.
- if (current_estimate_ < sample) {
- current_step_ -= sample - current_estimate_;
- current_estimate_ = sample;
- }
-
- // If we've reversed direction, reset the step down.
- if (sign_positive_ && current_step_ > 1)
- current_step_ = 1;
-
- sign_positive_ = false;
- }
-}
-
-void PercentileEstimator::SetRandomNumberGeneratorForTesting(
- RandomNumberCallback generator_callback) {
- generator_callback_ = generator_callback;
-}
-
-} // namespace net
diff --git a/chromium/net/base/percentile_estimator.h b/chromium/net/base/percentile_estimator.h
deleted file mode 100644
index 0ff7b8176e2..00000000000
--- a/chromium/net/base/percentile_estimator.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_BASE_PERCENTILE_ESTIMATOR_H_
-#define NET_BASE_PERCENTILE_ESTIMATOR_H_
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "net/base/net_export.h"
-
-namespace net {
-
-// This class estimates statistical percentiles (e.g. 10%l, 50%l) for
-// integer distributions presented in stream form. These estimates
-// adjust automatically when the stream distribution changes.
-// TODO(rdsmith): Expand the class to maintain floating point
-// estimates rather than integer estimates, when there's a use case
-// for that that deserves the extra complexity and pitfalls of
-// floating point arithmetic.
-class NET_EXPORT PercentileEstimator {
- public:
- using RandomNumberCallback = base::Callback<int(void)>;
-
- static const int kMedianPercentile = 50;
-
- // |percentile| is a number between 0 and 100 indicating what percentile
- // should be estimated (e.g. 50 would be a median estimate).
- // |initial_estimate| is the value the class is seeded with; in other
- // words, if AddSample() is never called,
- // |CurrentEstimate() == initial_estimate|.
- PercentileEstimator(int percentile, int initial_estimate);
-
- ~PercentileEstimator();
-
- int current_estimate() const { return current_estimate_; }
- void AddSample(int sample);
-
- // Specify a callback that will generate a "random" number
- // in the range [0,99] on each call. Used so that tests can
- // rely on reproducible behavior.
- void SetRandomNumberGeneratorForTesting(
- RandomNumberCallback generator_callback);
-
- private:
- const int percentile_;
-
- bool sign_positive_;
- int current_estimate_;
- int current_step_;
-
- RandomNumberCallback generator_callback_;
-
- DISALLOW_COPY_AND_ASSIGN(PercentileEstimator);
-};
-
-} // namespace net
-
-#endif // NET_BASE_PERCENTILE_ESTIMATOR_H_
diff --git a/chromium/net/base/percentile_estimator_unittest.cc b/chromium/net/base/percentile_estimator_unittest.cc
deleted file mode 100644
index 71d9c1d386b..00000000000
--- a/chromium/net/base/percentile_estimator_unittest.cc
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/base/percentile_estimator.h"
-
-#include "base/bind.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-// A number to turn sawtooth ramps from 0->100 into something that looks more
-// random to the algorithm.
-const int kPrimeMultipleToRandomizeRamps = 71;
-
-// Random numbers (fixed here for repeatability of tests). Generated originally
-// by using python's random module with randrange(0,100).
-int random_numbers[] = {
- 83, 11, 33, 98, 49, 54, 83, 19, 93, 37, 98, 39, 59, 13, 51, 39, 69, 18, 17,
- 17, 6, 85, 95, 51, 83, 39, 18, 82, 88, 47, 69, 27, 20, 82, 86, 38, 98, 65,
- 53, 13, 71, 66, 29, 40, 70, 28, 64, 35, 47, 50, 84, 90, 36, 54, 15, 93, 98,
- 51, 82, 50, 17, 46, 12, 18, 26, 39, 95, 61, 52, 63, 97, 92, 12, 71, 7, 15,
- 74, 10, 64, 57, 25, 82, 95, 40, 76, 8, 28, 83, 58, 1, 22, 58, 17, 33, 61,
- 94, 40, 50, 84, 47, 81, 9, 79, 16, 45, 78, 15, 3, 97, 60, 70, 25, 11, 11,
- 68, 64, 61, 84, 52, 64, 54, 72, 24, 46, 48, 4, 46, 34, 10, 97, 2, 42, 13,
- 9, 95, 75, 11, 99, 92, 33, 65, 48, 19, 72, 63, 39, 0, 10, 83, 62, 12, 99,
- 67, 98, 99, 83, 40, 45, 34, 80, 13, 94, 22, 74, 8, 11, 11, 98, 35, 86, 80,
- 94, 87, 60, 16, 46, 9, 25, 75, 50, 54, 23, 31, 63, 9, 50, 5, 18, 87, 16,
- 47, 72, 24, 93, 14, 1, 26, 41, 50, 49, 41, 77, 54, 48, 50, 3, 50, 16, 54,
- 97, 57, 63, 83, 33, 65, 90, 48, 55, 44, 11, 71, 6, 86, 29, 46, 61, 20, 8,
- 88, 3, 70, 76, 84, 59, 36, 50, 77, 63, 10, 55, 32, 82, 58, 19, 97, 8, 73,
- 47, 55, 74, 46, 52, 62, 19, 65, 75, 57, 23, 98, 39, 63, 19, 75, 48, 93, 58,
- 29, 96, 57, 31, 17, 33, 8, 69, 89, 90, 17, 79, 59, 67, 34, 20, 44, 80, 71,
- 79, 24, 63, 13, 27, 28, 61, 38, 67, 82, 46, 9, 4, 69, 41, 49, 49, 10, 3,
- 93, 46, 57, 96, 78, 51, 45, 37, 0, 6, 99, 93, 87, 18, 72, 83, 95, 39, 54,
- 84, 12, 47, 14, 55, 15, 27, 95, 6, 13, 80, 40, 8, 39, 18, 15, 52, 31, 66,
- 59, 67, 90, 12, 61, 77, 66, 61, 33, 89, 47, 40, 86, 34, 98, 13, 76, 30, 43,
- 56, 57, 88, 34, 48, 67, 6, 29, 92, 38, 11, 23, 74, 45, 38, 35, 94, 15, 72,
- 65, 20, 94, 72, 97, 78, 61, 79, 75, 0, 45, 38, 32, 94, 3, 5, 67, 91, 34,
- 37, 12, 11, 15, 75, 14, 73, 34, 55, 78, 64, 52, 29, 60, 62, 16, 51, 44, 78,
- 0, 15, 41, 5, 52, 4, 68, 53, 39, 39, 68, 71, 66, 68, 97, 65, 55, 39, 94,
- 57, 43, 81, 67, 22, 30, 64, 37, 42, 35, 60, 61, 2, 51, 49, 43, 82, 61, 70,
- 63, 47, 57, 8, 55, 96, 68, 7, 46, 69, 8, 43, 18, 9, 25, 8, 97, 98, 83,
- 79, 19, 92, 54, 90, 72, 80, 92, 94, 26, 48, 94, 74, 32, 29, 44, 34, 55, 56,
- 97, 40, 86, 35, 64, 25, 85, 13, 57, 2, 29, 77, 19, 94, 46, 85, 15, 71, 81,
- 25, 45, 2, 1, 62, 77, 28, 95, 72, 72, 28, 3, 36, 76, 81, 56, 52, 27, 62,
- 8, 5, 62, 1, 43, 68, 40, 68, 22, 65, 30, 50, 36, 89, 5, 71, 68, 99, 53,
- 22, 26, 0, 1, 72, 76, 79, 50, 2, 32, 39, 40, 6, 99, 60, 59, 55, 28, 17,
- 12, 94, 51, 3, 4, 71, 36, 88, 26, 99, 25, 13, 80, 53, 4, 57, 55, 44, 26,
- 82, 4, 53, 34, 47, 16, 97, 56, 30, 0, 73, 85, 59, 86, 24, 70, 73, 53, 68,
- 15, 91, 90, 74, 39, 61, 32, 98, 14, 82, 99, 31, 7, 99, 34, 6, 3, 30, 57,
- 44, 58, 86, 37, 12, 63, 82, 78, 94, 4, 93, 89, 92, 59, 40, 94, 88, 97, 95,
- 5, 88, 40, 80, 79, 0, 2, 46, 86, 46, 75, 87, 86, 8, 23, 35, 62, 79, 66,
- 16, 16, 45, 11, 78, 76, 40, 73, 85, 28, 44, 33, 34, 22, 11, 62, 8, 35, 88,
- 92, 35, 53, 50, 51, 54, 75, 41, 21, 83, 57, 82, 80, 84, 65, 19, 11, 85, 41,
- 80, 86, 62, 34, 54, 54, 79, 81, 52, 87, 54, 54, 43, 17, 44, 63, 54, 14, 88,
- 84, 86, 73, 58, 44, 2, 70, 86, 80, 94, 13, 85, 78, 6, 44, 11, 11, 97, 67,
- 65, 28, 42, 40, 84, 92, 66, 85, 75, 29, 84, 82, 54, 50, 26, 12, 83, 57, 90,
- 9, 40, 69, 38, 70, 65, 76, 85, 76, 4, 30, 86, 43, 79, 77, 69, 53, 35, 12,
- 98, 7, 47, 12, 63, 10, 81, 39, 88, 12, 16, 88, 22, 72, 25, 41, 22, 34, 87,
- 68, 51, 86, 45, 27, 51, 80, 69, 89, 64, 89, 68, 61, 80, 6, 83, 47, 18, 86,
- 73, 16, 61, 89, 47, 5, 33, 59, 47, 75, 15, 60, 28, 18, 59, 65, 51, 13, 28,
- 26, 84, 89, 80, 51, 15, 92, 36, 89, 83, 28, 56, 65, 25, 44, 84, 70, 26, 10,
- 74, 91, 55, 85, 73, 25, 24, 64, 11, 1, 55, 32, 45, 74, 4, 55, 98, 42, 91,
- 88, 18, 79, 37, 15, 5, 98, 63, 65, 77, 66, 18, 99, 1, 78, 96, 15, 16, 16,
- 51, 11, 47, 58, 1, 12, 46, 5, 56, 34, 40, 36, 20, 4, 89, 59, 4, 13, 3,
- 8, 74, 41, 21, 64, 88, 97, 42, 14, 29, 38, 53, 65, 55, 67, 33, 69, 17, 79,
- 45, 2, 63, 2, 97, 47, 73, 22, 86, 32, 31, 95, 90, 84, 25, 86, 91, 77, 1,
- 5, 6, 22, 91, 3, 94, 52, 2, 95, 17, 1, 19, 22, 34, 49, 96, 88, 63, 26,
- 5, 25, 75, 23, 25, 80, 21, 83, 86, 81, 11, 70, 67, 11, 95, 81, 57, 63, 8,
- 43, 60, 40, 42, 67, 50, 2, 51, 43, 34, 7, 1, 90, 59, 74, 87, 23, 23, 71,
- 20, 89, 2, 75, 21, 91, 32, 87, 67, 98, 99, 22, 31, 59, 50, 64, 55, 22, 84,
- 9, 31, 31, 84, 36, 92, 60, 37, 85, 18, 12, 38, 55, 55, 93, 36, 9, 46, 48,
- 24, 91, 60, 95, 55, 73, 63, 27, 55, 96, 79, 50, 41, 5, 67, 85, 99, 95, 3,
- 97, 28, 27, 78, 38, 11, 77, 11, 64, 25, 22, 88, 34, 86, 30, 78, 95, 17, 9,
- 29, 58, 35, 22, 99, 28, 66, 35, 60, 10, 7, 51, 64, 86, 30, 27, 97, 63, 0,
- 36, 87, 52, 16, 5, 90, 8, 66, 58, 91, 85, 3, 95, 31, 73, 87, 30, 78, 46,
- 30, 75, 36, 44, 52, 76, 24, 58, 8, 70, 58, 95, 88, 0, 35, 86, 21, 96, 90,
- 54, 85, 56, 30, 37, 30, 62, 56, 63, 91, 25, 56, 20, 56, 23, 12, 8, 70, 56,
- 83, 49, 70, 67, 61, 95, 50, 41, 88, 37, 89, 37, 21, 63, 25, 46, 16, 75, 73,
- 86, 39, 4, 55, 41, 39, 45, 31, 97, 6, 81, 68, 38, 49, 80, 9, 87, 22, 37,
- 41, 28, 47, 74, 76, 34, 72, 65, 34, 41, 59, 42, 73, 32, 75, 25, 18, 26, 71,
- 93, 92, 12, 76, 93, 84, 44, 43, 4, 9, 3, 90, 91, 45, 0, 10, 43, 45, 65,
- 34, 82, 54, 1, 78, 36, 74, 58, 3, 26, 89, 21, 57, 42, 37, 12, 90, 97, 48,
- 27, 75, 40, 69, 61, 56, 44, 75, 77, 55, 31, 0, 77, 12, 23, 16, 98, 77, 8,
- 96, 92, 91, 26, 50, 42, 65, 38, 58, 41, 45, 69, 42, 37, 89, 92, 40, 74, 68,
- 86, 80, 49, 16, 48, 74, 50, 92, 54, 6, 82, 21, 35, 57, 81, 29, 10, 60, 74,
- 41, 70, 18, 65, 44, 77, 64, 8, 87, 90, 24, 52, 67, 58, 56, 89, 47, 15, 20,
- 4, 87, 72, 87, 13, 79, 3, 26, 43, 52, 72, 83, 17, 99, 29, 10, 61, 62, 42,
- 35, 47, 42, 40, 17, 71, 54, 30, 99, 64, 78, 70, 75, 38, 32, 51, 2, 49, 47,
- 0, 41, 50, 41, 64, 57, 78, 22, 17, 94, 24, 65, 84, 38, 75, 3, 58, 18, 51,
- 91, 72, 91, 55, 6, 70, 76, 73, 30, 54, 73, 77, 45, 85, 88, 58, 25, 80, 35,
- 99, 57, 73, 15, 55, 71, 44, 44, 79, 20, 63, 29, 14, 51, 10, 46, 80, 36, 47,
- 80, 53, 15, 64, 42, 59, 94, 55, 99, 28, 76, 80, 51, 4, 98, 98, 38, 59, 71,
- 9, 93, 91, 46, 74, 63, 10, 39, 1, 43, 11, 64, 39, 59, 54, 9, 44, 78, 52,
- 98, 9, 73, 24, 15, 40, 5, 55, 23, 83, 67, 10, 58, 45, 64, 41, 92, 85, 72,
- 18, 67, 65, 30, 56, 84, 63, 96, 51, 55, 19, 70, 48, 81, 2, 37, 85, 77};
-
-class PercentileEstimatorTest : public testing::Test {
- public:
- PercentileEstimatorTest() : index_(0) {}
-
- // Create a new estimator with the given parameters.
- void SetUpEstimator(int percentile, int initial_estimate) {
- estimator_.reset(
- new net::PercentileEstimator(percentile, initial_estimate));
- estimator_->SetRandomNumberGeneratorForTesting(
- base::Bind(&PercentileEstimatorTest::GetRandomNumber,
- // Safe since |estimator_| is owned by and
- // will not survive destruction of |this|.
- base::Unretained(this)));
- }
-
- int CurrentEstimate() { return estimator_->current_estimate(); }
- void AddSample(int sample) { estimator_->AddSample(sample); }
-
- // Add the sample until there's a change in the estimate, then return the
- // new estimate. To get around the randomness of whether samples are
- // incorporated or not.
- int AddSampleUntilRegistered(int sample) {
- int old_estimate = estimator_->current_estimate();
- while (old_estimate == estimator_->current_estimate())
- estimator_->AddSample(sample);
-
- return estimator_->current_estimate();
- }
-
- int GetRandomNumber() {
- int result = random_numbers[index_];
- ++index_;
- if (static_cast<unsigned long>(index_) >=
- sizeof(random_numbers) / sizeof(int)) {
- index_ = 0;
- }
- return result;
- }
-
- private:
- int index_;
- std::unique_ptr<net::PercentileEstimator> estimator_;
-
- DISALLOW_COPY_AND_ASSIGN(PercentileEstimatorTest);
-};
-
-// Converges upwards fairly quickly.
-TEST_F(PercentileEstimatorTest, MedianConvergesUpwards) {
- SetUpEstimator(50, 100);
-
- for (int i = 0; i < 40; ++i)
- AddSample(150);
-
- EXPECT_EQ(150, CurrentEstimate());
-}
-
-// Converges downwards fairly quickly.
-TEST_F(PercentileEstimatorTest, MedianConvergesDownwards) {
- SetUpEstimator(50, 100);
-
- for (int i = 0; i < 40; ++i)
- AddSample(50);
-
- EXPECT_EQ(50, CurrentEstimate());
-}
-
-// Stable if the value is bouncing around.
-TEST_F(PercentileEstimatorTest, BounceStable) {
- SetUpEstimator(50, 100);
-
- for (int i = 0; i < 20; ++i)
- AddSample(50 + (i % 2) * 100);
-
- EXPECT_LE(97, CurrentEstimate());
- EXPECT_LE(CurrentEstimate(), 103);
-}
-
-// Correctly converges to a 90%l value upwards.
-TEST_F(PercentileEstimatorTest, NinetythConvergesUpwards) {
- SetUpEstimator(90, 50);
-
- for (int i = 0; i < 10000; ++i)
- AddSample((i * kPrimeMultipleToRandomizeRamps) % 100);
-
- EXPECT_LE(86, CurrentEstimate());
- EXPECT_LE(CurrentEstimate(), 94);
-}
-
-// Correctly converges to a 90%l value downwards.
-TEST_F(PercentileEstimatorTest, NinetythConvergesDownwards) {
- SetUpEstimator(90, 150);
-
- for (int i = 0; i < 1000; ++i)
- AddSample((i * kPrimeMultipleToRandomizeRamps) % 100);
-
- EXPECT_LT(86, CurrentEstimate());
- EXPECT_LT(CurrentEstimate(), 94);
-}
-
-// Doesn't overshoot sample heading upwards.
-TEST_F(PercentileEstimatorTest, NoUpwardsOvershoot) {
- SetUpEstimator(50, 100);
-
- // Crank up the step size
- for (int i = 0; i < 20; ++i)
- AddSample(1000);
-
- // Derive the step size.
- int e1 = CurrentEstimate();
- int e2 = AddSampleUntilRegistered(1000);
- int step_size = e2 - e1;
- ASSERT_GT(step_size, 1);
-
- // Increment by less than the current step size.
- int new_sample = e2 + step_size / 2;
- AddSampleUntilRegistered(new_sample);
- EXPECT_EQ(new_sample, CurrentEstimate());
- AddSampleUntilRegistered(1000);
- EXPECT_GT(new_sample + step_size, CurrentEstimate());
-}
-
-// Doesn't overshoot sample heading downwards
-TEST_F(PercentileEstimatorTest, NoDownwardsOvershoot) {
- SetUpEstimator(50, 1000);
-
- // Crank up the step size
- for (int i = 0; i < 20; ++i)
- AddSample(100);
-
- // Derive the step size.
- int e1 = CurrentEstimate();
- int e2 = AddSampleUntilRegistered(100);
- int step_size = e1 - e2;
- ASSERT_GT(step_size, 1);
-
- // Increment by less than the current step size.
- int new_sample = e2 - step_size / 2;
- AddSampleUntilRegistered(new_sample);
- EXPECT_EQ(new_sample, CurrentEstimate());
- AddSampleUntilRegistered(100);
- EXPECT_LT(new_sample - step_size, CurrentEstimate());
-}
-
-} // namespace
diff --git a/chromium/net/base/proxy_server.cc b/chromium/net/base/proxy_server.cc
index a6fb7788ea7..da31a40fbe8 100644
--- a/chromium/net/base/proxy_server.cc
+++ b/chromium/net/base/proxy_server.cc
@@ -96,33 +96,23 @@ const HostPortPair& ProxyServer::host_port_pair() const {
}
// static
-ProxyServer ProxyServer::FromURI(const std::string& uri,
- Scheme default_scheme) {
- return FromURI(uri.begin(), uri.end(), default_scheme);
-}
-
-// static
-ProxyServer ProxyServer::FromURI(std::string::const_iterator begin,
- std::string::const_iterator end,
- Scheme default_scheme) {
+ProxyServer ProxyServer::FromURI(base::StringPiece uri, Scheme default_scheme) {
// We will default to |default_scheme| if no scheme specifier was given.
Scheme scheme = default_scheme;
// Trim the leading/trailing whitespace.
- HttpUtil::TrimLWS(&begin, &end);
+ uri = HttpUtil::TrimLWS(uri);
// Check for [<scheme> "://"]
- std::string::const_iterator colon = std::find(begin, end, ':');
- if (colon != end &&
- (end - colon) >= 3 &&
- *(colon + 1) == '/' &&
- *(colon + 2) == '/') {
- scheme = GetSchemeFromURIInternal(base::StringPiece(begin, colon));
- begin = colon + 3; // Skip past the "://"
+ size_t colon = uri.find(':');
+ if (colon != base::StringPiece::npos && uri.size() - colon >= 3 &&
+ uri[colon + 1] == '/' && uri[colon + 2] == '/') {
+ scheme = GetSchemeFromURIInternal(uri.substr(0, colon));
+ uri = uri.substr(colon + 3); // Skip past the "://"
}
// Now parse the <host>[":"<port>].
- return FromSchemeHostAndPort(scheme, begin, end);
+ return FromSchemeHostAndPort(scheme, uri);
}
std::string ProxyServer::ToURI() const {
@@ -148,33 +138,27 @@ std::string ProxyServer::ToURI() const {
}
// static
-ProxyServer ProxyServer::FromPacString(const std::string& pac_string) {
- return FromPacString(pac_string.begin(), pac_string.end());
-}
-
-// static
-ProxyServer ProxyServer::FromPacString(std::string::const_iterator begin,
- std::string::const_iterator end) {
+ProxyServer ProxyServer::FromPacString(base::StringPiece pac_string) {
// Trim the leading/trailing whitespace.
- HttpUtil::TrimLWS(&begin, &end);
+ pac_string = HttpUtil::TrimLWS(pac_string);
// Input should match:
// "DIRECT" | ( <type> 1*(LWS) <host-and-port> )
// Start by finding the first space (if any).
- std::string::const_iterator space;
- for (space = begin; space != end; ++space) {
- if (HttpUtil::IsLWS(*space)) {
+ size_t space = 0;
+ for (; space < pac_string.size(); space++) {
+ if (HttpUtil::IsLWS(pac_string[space])) {
break;
}
}
// Everything to the left of the space is the scheme.
- Scheme scheme = GetSchemeFromPacTypeInternal(base::StringPiece(begin, space));
+ Scheme scheme = GetSchemeFromPacTypeInternal(pac_string.substr(0, space));
// And everything to the right of the space is the
// <host>[":" <port>].
- return FromSchemeHostAndPort(scheme, space, end);
+ return FromSchemeHostAndPort(scheme, pac_string.substr(space));
}
std::string ProxyServer::ToPacString() const {
@@ -229,13 +213,11 @@ size_t ProxyServer::EstimateMemoryUsage() const {
// static
ProxyServer ProxyServer::FromSchemeHostAndPort(
Scheme scheme,
- std::string::const_iterator begin,
- std::string::const_iterator end) {
-
+ base::StringPiece host_and_port) {
// Trim leading/trailing space.
- HttpUtil::TrimLWS(&begin, &end);
+ host_and_port = HttpUtil::TrimLWS(host_and_port);
- if (scheme == SCHEME_DIRECT && begin != end)
+ if (scheme == SCHEME_DIRECT && !host_and_port.empty())
return ProxyServer(); // Invalid -- DIRECT cannot have a host/port.
HostPortPair host_port_pair;
@@ -244,7 +226,7 @@ ProxyServer ProxyServer::FromSchemeHostAndPort(
std::string host;
int port = -1;
// If the scheme has a host/port, parse it.
- bool ok = ParseHostAndPort(begin, end, &host, &port);
+ bool ok = ParseHostAndPort(host_and_port, &host, &port);
if (!ok)
return ProxyServer(); // Invalid -- failed parsing <host>[":"<port>]
diff --git a/chromium/net/base/proxy_server.h b/chromium/net/base/proxy_server.h
index 0ce103bc9f0..43ad6da723b 100644
--- a/chromium/net/base/proxy_server.h
+++ b/chromium/net/base/proxy_server.h
@@ -14,6 +14,7 @@
#include <string>
#include <tuple>
+#include "base/strings/string_piece.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_export.h"
@@ -95,10 +96,7 @@ class NET_EXPORT ProxyServer {
// "quic://foopy:17" {scheme=QUIC, host="foopy", port=17}
// "direct://" {scheme=DIRECT}
// "foopy:X" INVALID -- bad port.
- static ProxyServer FromURI(const std::string& uri, Scheme default_scheme);
- static ProxyServer FromURI(std::string::const_iterator uri_begin,
- std::string::const_iterator uri_end,
- Scheme default_scheme);
+ static ProxyServer FromURI(base::StringPiece uri, Scheme default_scheme);
// Formats as a URI string. This does the reverse of FromURI.
std::string ToURI() const;
@@ -117,9 +115,7 @@ class NET_EXPORT ProxyServer {
// "HTTPS foopy:123" {scheme=HTTPS, host="foopy", port=123}
// "QUIC foopy:123" {scheme=QUIC, host="foopy", port=123}
// "BLAH xxx:xx" INVALID
- static ProxyServer FromPacString(const std::string& pac_string);
- static ProxyServer FromPacString(std::string::const_iterator pac_string_begin,
- std::string::const_iterator pac_string_end);
+ static ProxyServer FromPacString(base::StringPiece pac_string);
// Returns a ProxyServer representing DIRECT connections.
static ProxyServer Direct() {
@@ -170,10 +166,8 @@ class NET_EXPORT ProxyServer {
private:
// Creates a ProxyServer given a scheme, and host/port string. If parsing the
// host/port string fails, the returned instance will be invalid.
- static ProxyServer FromSchemeHostAndPort(
- Scheme scheme,
- std::string::const_iterator host_and_port_begin,
- std::string::const_iterator host_and_port_end);
+ static ProxyServer FromSchemeHostAndPort(Scheme scheme,
+ base::StringPiece host_and_port);
Scheme scheme_ = SCHEME_INVALID;
HostPortPair host_port_pair_;
diff --git a/chromium/net/base/registry_controlled_domains/effective_tld_names.dat b/chromium/net/base/registry_controlled_domains/effective_tld_names.dat
index efda68a1292..a210b9d6072 100644
--- a/chromium/net/base/registry_controlled_domains/effective_tld_names.dat
+++ b/chromium/net/base/registry_controlled_domains/effective_tld_names.dat
@@ -449,6 +449,7 @@ arq.br
art.br
ato.br
b.br
+barueri.br
belem.br
bhz.br
bio.br
@@ -1133,7 +1134,7 @@ gov.gy
net.gy
org.gy
-// hk : https://www.hkdnr.hk
+// hk : https://www.hkirc.hk
// Submitted by registry <hk.tech@hkirc.hk>
hk
com.hk
@@ -1344,10 +1345,8 @@ int.is
it
gov.it
edu.it
-// Reserved geo-names:
-// http://www.nic.it/documenti/regolamenti-e-linee-guida/regolamento-assegnazione-versione-6.0.pdf
-// There is also a list of reserved geo-names corresponding to Italian municipalities
-// http://www.nic.it/documenti/appendice-c.pdf, but it is not included here.
+// Reserved geo-names (regions and provinces):
+// http://www.nic.it/sites/default/files/docs/Regulation_assignation_v7.1.pdf
// Regions
abr.it
abruzzo.it
@@ -1401,6 +1400,12 @@ sicily.it
taa.it
tos.it
toscana.it
+trentin-sud-tirol.it
+trentin-süd-tirol.it
+trentin-sudtirol.it
+trentin-südtirol.it
+trentin-sued-tirol.it
+trentin-suedtirol.it
trentino-a-adige.it
trentino-aadige.it
trentino-alto-adige.it
@@ -1408,9 +1413,12 @@ trentino-altoadige.it
trentino-s-tirol.it
trentino-stirol.it
trentino-sud-tirol.it
+trentino-süd-tirol.it
trentino-sudtirol.it
+trentino-südtirol.it
trentino-sued-tirol.it
trentino-suedtirol.it
+trentino.it
trentinoa-adige.it
trentinoaadige.it
trentinoalto-adige.it
@@ -1418,9 +1426,17 @@ trentinoaltoadige.it
trentinos-tirol.it
trentinostirol.it
trentinosud-tirol.it
+trentinosüd-tirol.it
trentinosudtirol.it
+trentinosüdtirol.it
trentinosued-tirol.it
trentinosuedtirol.it
+trentinsud-tirol.it
+trentinsüd-tirol.it
+trentinsudtirol.it
+trentinsüdtirol.it
+trentinsued-tirol.it
+trentinsuedtirol.it
tuscany.it
umb.it
umbria.it
@@ -1435,7 +1451,13 @@ valleaosta.it
valled-aosta.it
valledaosta.it
vallee-aoste.it
+vallée-aoste.it
+vallee-d-aoste.it
+vallée-d-aoste.it
valleeaoste.it
+valléeaoste.it
+valleedaoste.it
+valléedaoste.it
vao.it
vda.it
ven.it
@@ -1468,6 +1490,9 @@ at.it
av.it
avellino.it
ba.it
+balsan-sudtirol.it
+balsan-südtirol.it
+balsan-suedtirol.it
balsan.it
bari.it
barletta-trani-andria.it
@@ -1482,13 +1507,21 @@ bl.it
bn.it
bo.it
bologna.it
+bolzano-altoadige.it
bolzano.it
+bozen-sudtirol.it
+bozen-südtirol.it
+bozen-suedtirol.it
bozen.it
br.it
brescia.it
brindisi.it
bs.it
bt.it
+bulsan-sudtirol.it
+bulsan-südtirol.it
+bulsan-suedtirol.it
+bulsan.it
bz.it
ca.it
cagliari.it
@@ -1506,7 +1539,9 @@ catanzaro.it
cb.it
ce.it
cesena-forli.it
+cesena-forlì.it
cesenaforli.it
+cesenaforlì.it
ch.it
chieti.it
ci.it
@@ -1537,7 +1572,9 @@ florence.it
fm.it
foggia.it
forli-cesena.it
+forlì-cesena.it
forlicesena.it
+forlìcesena.it
fr.it
frosinone.it
ge.it
@@ -1668,6 +1705,7 @@ sp.it
sr.it
ss.it
suedtirol.it
+südtirol.it
sv.it
ta.it
taranto.it
@@ -1686,7 +1724,6 @@ trani-barletta-andria.it
traniandriabarletta.it
tranibarlettaandria.it
trapani.it
-trentino.it
trento.it
treviso.it
trieste.it
@@ -6156,9 +6193,6 @@ nc.tr
// Used by government agencies of Northern Cyprus
gov.nc.tr
-// travel : https://en.wikipedia.org/wiki/.travel
-travel
-
// tt : http://www.nic.tt/
tt
co.tt
@@ -6733,8 +6767,16 @@ yt
ελ
// xn--j6w193g ("Hong Kong", Chinese) : HK
-// https://www2.hkirc.hk/register/rules.jsp
+// https://www.hkirc.hk
+// Submitted by registry <hk.tech@hkirc.hk>
+// https://www.hkirc.hk/content.jsp?id=30#!/34
香港
+公司.香港
+教育.香港
+政府.香港
+個人.香港
+網絡.香港
+組織.香港
// xn--2scrj9c ("Bharat", Kannada) : IN
// India
@@ -6768,6 +6810,10 @@ yt
// India
भारत
+// xn--mgbbh1a ("Bharat", Kashmiri) : IN
+// India
+بارت
+
// xn--mgbbh1a71e ("Bharat", Arabic) : IN
// India
بھارت
@@ -6982,7 +7028,10 @@ gov.zw
mil.zw
org.zw
-// List of new gTLDs imported from https://newgtlds.icann.org/newgtlds.csv on 2017-02-23T00:46:09Z
+
+// newGTLDs
+// List of new gTLDs imported from https://newgtlds.icann.org/newgtlds.csv on 2018-05-08T19:40:37Z
+// This list is auto-generated, don't edit it manually.
// aaa : 2015-02-26 American Automobile Association, Inc.
aaa
@@ -7008,13 +7057,13 @@ abc
// able : 2015-06-25 Able Inc.
able
-// abogado : 2014-04-24 Top Level Domain Holdings Limited
+// abogado : 2014-04-24 Minds + Machines Group Limited
abogado
// abudhabi : 2015-07-30 Abu Dhabi Systems and Information Centre
abudhabi
-// academy : 2013-11-07 Half Oaks, LLC
+// academy : 2013-11-07 Binky Moon, LLC
academy
// accenture : 2014-08-15 Accenture plc
@@ -7023,13 +7072,13 @@ accenture
// accountant : 2014-11-20 dot Accountant Limited
accountant
-// accountants : 2014-03-20 Knob Town, LLC
+// accountants : 2014-03-20 Binky Moon, LLC
accountants
// aco : 2015-01-08 ACO Severin Ahlmann GmbH & Co. KG
aco
-// active : 2014-05-01 The Active Network, Inc
+// active : 2014-05-01 Active Network, LLC
active
// actor : 2013-12-12 United TLD Holdco Ltd.
@@ -7062,7 +7111,7 @@ africa
// agakhan : 2015-04-23 Fondation Aga Khan (Aga Khan Foundation)
agakhan
-// agency : 2013-11-14 Steel Falls, LLC
+// agency : 2013-11-14 Binky Moon, LLC
agency
// aig : 2014-12-18 American International Group, Inc.
@@ -7101,7 +7150,7 @@ allstate
// ally : 2015-06-18 Ally Financial Inc.
ally
-// alsace : 2014-07-02 REGION D ALSACE
+// alsace : 2014-07-02 Region Grand Est
alsace
// alstom : 2015-07-30 ALSTOM
@@ -7137,10 +7186,10 @@ anquan
// anz : 2015-07-31 Australia and New Zealand Banking Group Limited
anz
-// aol : 2015-09-17 AOL Inc.
+// aol : 2015-09-17 Oath Inc.
aol
-// apartments : 2014-12-11 June Maple, LLC
+// apartments : 2014-12-11 Binky Moon, LLC
apartments
// app : 2015-05-14 Charleston Road Registry Inc.
@@ -7158,7 +7207,7 @@ arab
// aramco : 2014-11-20 Aramco Services Company
aramco
-// archi : 2014-02-06 STARTING DOT LIMITED
+// archi : 2014-02-06 Afilias plc
archi
// army : 2014-03-06 United TLD Holdco Ltd.
@@ -7173,22 +7222,22 @@ arte
// asda : 2015-07-31 Wal-Mart Stores, Inc.
asda
-// associates : 2014-03-06 Baxter Hill, LLC
+// associates : 2014-03-06 Binky Moon, LLC
associates
// athleta : 2015-07-30 The Gap, Inc.
athleta
-// attorney : 2014-03-20
+// attorney : 2014-03-20 United TLD Holdco Ltd.
attorney
-// auction : 2014-03-20
+// auction : 2014-03-20 United TLD Holdco Ltd.
auction
// audi : 2015-05-21 AUDI Aktiengesellschaft
audi
-// audible : 2015-06-25 Amazon EU S.à r.l.
+// audible : 2015-06-25 Amazon Registry Services, Inc.
audible
// audio : 2014-03-20 Uniregistry, Corp.
@@ -7197,10 +7246,10 @@ audio
// auspost : 2015-08-13 Australian Postal Corporation
auspost
-// author : 2014-12-18 Amazon EU S.à r.l.
+// author : 2014-12-18 Amazon Registry Services, Inc.
author
-// auto : 2014-11-13
+// auto : 2014-11-13 Cars Registry Limited
auto
// autos : 2014-01-09 DERAutos, LLC
@@ -7209,7 +7258,7 @@ autos
// avianca : 2015-01-08 Aerovias del Continente Americano S.A. Avianca
avianca
-// aws : 2015-06-25 Amazon EU S.à r.l.
+// aws : 2015-06-25 Amazon Registry Services, Inc.
aws
// axa : 2013-12-19 AXA SA
@@ -7230,7 +7279,7 @@ banamex
// bananarepublic : 2015-07-31 The Gap, Inc.
bananarepublic
-// band : 2014-06-12
+// band : 2014-06-12 United TLD Holdco Ltd.
band
// bank : 2014-09-25 fTLD Registry Services LLC
@@ -7251,7 +7300,7 @@ barclays
// barefoot : 2015-06-11 Gallo Vineyards, Inc.
barefoot
-// bargains : 2013-11-14 Half Hallow, LLC
+// bargains : 2013-11-14 Binky Moon, LLC
bargains
// baseball : 2015-10-29 MLB Advanced Media DH, LLC
@@ -7287,7 +7336,7 @@ beats
// beauty : 2015-12-03 L'Oréal
beauty
-// beer : 2014-01-09 Top Level Domain Holdings Limited
+// beer : 2014-01-09 Minds + Machines Group Limited
beer
// bentley : 2014-12-18 Bentley Motors Limited
@@ -7314,19 +7363,19 @@ bible
// bid : 2013-12-19 dot Bid Limited
bid
-// bike : 2013-08-27 Grand Hollow, LLC
+// bike : 2013-08-27 Binky Moon, LLC
bike
// bing : 2014-12-18 Microsoft Corporation
bing
-// bingo : 2014-12-04 Sand Cedar, LLC
+// bingo : 2014-12-04 Binky Moon, LLC
bingo
-// bio : 2014-03-06 STARTING DOT LIMITED
+// bio : 2014-03-06 Afilias plc
bio
-// black : 2014-01-16 Afilias Limited
+// black : 2014-01-16 Afilias plc
black
// blackfriday : 2014-01-16 Uniregistry, Corp.
@@ -7338,13 +7387,13 @@ blanco
// blockbuster : 2015-07-30 Dish DBS Corporation
blockbuster
-// blog : 2015-05-14
+// blog : 2015-05-14 Knock Knock WHOIS There, LLC
blog
// bloomberg : 2014-07-17 Bloomberg IP Holdings LLC
bloomberg
-// blue : 2013-11-07 Afilias Limited
+// blue : 2013-11-07 Afilias plc
blue
// bms : 2014-10-30 Bristol-Myers Squibb Company
@@ -7365,7 +7414,7 @@ boats
// boehringer : 2015-07-09 Boehringer Ingelheim International GmbH
boehringer
-// bofa : 2015-07-31 NMS Services, Inc.
+// bofa : 2015-07-31 Bank of America Corporation
bofa
// bom : 2014-10-16 Núcleo de Informação e Coordenação do Ponto BR - NIC.br
@@ -7377,28 +7426,25 @@ bond
// boo : 2014-01-30 Charleston Road Registry Inc.
boo
-// book : 2015-08-27 Amazon EU S.à r.l.
+// book : 2015-08-27 Amazon Registry Services, Inc.
book
// booking : 2015-07-16 Booking.com B.V.
booking
-// boots : 2015-01-08 THE BOOTS COMPANY PLC
-boots
-
// bosch : 2015-06-18 Robert Bosch GMBH
bosch
// bostik : 2015-05-28 Bostik SA
bostik
-// boston : 2015-12-10
+// boston : 2015-12-10 Boston TLD Management, LLC
boston
-// bot : 2014-12-18 Amazon EU S.à r.l.
+// bot : 2014-12-18 Amazon Registry Services, Inc.
bot
-// boutique : 2013-11-14 Over Galley, LLC
+// boutique : 2013-11-14 Binky Moon, LLC
boutique
// box : 2015-11-12 NS1 Limited
@@ -7413,7 +7459,7 @@ bridgestone
// broadway : 2014-12-22 Celebrate Broadway, Inc.
broadway
-// broker : 2014-12-11 IG Group Holdings PLC
+// broker : 2014-12-11 Dotbroker Registry Limited
broker
// brother : 2015-01-29 Brother Industries, Ltd.
@@ -7422,7 +7468,7 @@ brother
// brussels : 2014-02-06 DNS.be vzw
brussels
-// budapest : 2013-11-21 Top Level Domain Holdings Limited
+// budapest : 2013-11-21 Minds + Machines Group Limited
budapest
// bugatti : 2015-07-23 Bugatti International SA
@@ -7431,13 +7477,13 @@ bugatti
// build : 2013-11-07 Plan Bee LLC
build
-// builders : 2013-11-07 Atomic Madison, LLC
+// builders : 2013-11-07 Binky Moon, LLC
builders
-// business : 2013-11-07 Spring Cross, LLC
+// business : 2013-11-07 Binky Moon, LLC
business
-// buy : 2014-12-18 Amazon EU S.à r.l.
+// buy : 2014-12-18 Amazon Registry Services, Inc.
buy
// buzz : 2013-10-02 DOTSTRATEGY CO.
@@ -7446,16 +7492,16 @@ buzz
// bzh : 2014-02-27 Association www.bzh
bzh
-// cab : 2013-10-24 Half Sunset, LLC
+// cab : 2013-10-24 Binky Moon, LLC
cab
-// cafe : 2015-02-11 Pioneer Canyon, LLC
+// cafe : 2015-02-11 Binky Moon, LLC
cafe
// cal : 2014-07-24 Charleston Road Registry Inc.
cal
-// call : 2014-12-18 Amazon EU S.à r.l.
+// call : 2014-12-18 Amazon Registry Services, Inc.
call
// calvinklein : 2015-07-30 PVH gTLD Holdings LLC
@@ -7464,10 +7510,10 @@ calvinklein
// cam : 2016-04-21 AC Webconnecting Holding B.V.
cam
-// camera : 2013-08-27 Atomic Maple, LLC
+// camera : 2013-08-27 Binky Moon, LLC
camera
-// camp : 2013-11-07 Delta Dynamite, LLC
+// camp : 2013-11-07 Binky Moon, LLC
camp
// cancerresearch : 2014-05-15 Australian Cancer Research Foundation
@@ -7479,37 +7525,37 @@ canon
// capetown : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
capetown
-// capital : 2014-03-06 Delta Mill, LLC
+// capital : 2014-03-06 Binky Moon, LLC
capital
// capitalone : 2015-08-06 Capital One Financial Corporation
capitalone
-// car : 2015-01-22
+// car : 2015-01-22 Cars Registry Limited
car
// caravan : 2013-12-12 Caravan International, Inc.
caravan
-// cards : 2013-12-05 Foggy Hollow, LLC
+// cards : 2013-12-05 Binky Moon, LLC
cards
-// care : 2014-03-06 Goose Cross
+// care : 2014-03-06 Binky Moon, LLC
care
// career : 2013-10-09 dotCareer LLC
career
-// careers : 2013-10-02 Wild Corner, LLC
+// careers : 2013-10-02 Binky Moon, LLC
careers
-// cars : 2014-11-13
+// cars : 2014-11-13 Cars Registry Limited
cars
// cartier : 2014-06-23 Richemont DNS Inc.
cartier
-// casa : 2013-11-21 Top Level Domain Holdings Limited
+// casa : 2013-11-21 Minds + Machines Group Limited
casa
// case : 2015-09-03 CNH Industrial N.V.
@@ -7518,13 +7564,13 @@ case
// caseih : 2015-09-03 CNH Industrial N.V.
caseih
-// cash : 2014-03-06 Delta Lake, LLC
+// cash : 2014-03-06 Binky Moon, LLC
cash
-// casino : 2014-12-18 Binky Sky, LLC
+// casino : 2014-12-18 Binky Moon, LLC
casino
-// catering : 2013-12-05 New Falls. LLC
+// catering : 2013-12-05 Binky Moon, LLC
catering
// catholic : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication)
@@ -7545,7 +7591,7 @@ cbs
// ceb : 2015-04-09 The Corporate Executive Board Company
ceb
-// center : 2013-11-07 Tin Mill, LLC
+// center : 2013-11-07 Binky Moon, LLC
center
// ceo : 2013-11-07 CEOTLD Pty Ltd
@@ -7557,7 +7603,7 @@ cern
// cfa : 2014-08-28 CFA Institute
cfa
-// cfd : 2014-12-11 IG Group Holdings PLC
+// cfd : 2014-12-11 DotCFD Registry Limited
cfd
// chanel : 2015-04-09 Chanel International B.V.
@@ -7566,13 +7612,16 @@ chanel
// channel : 2014-05-08 Charleston Road Registry Inc.
channel
-// chase : 2015-04-30 JPMorgan Chase & Co.
+// charity : 2018-04-11 Corn Lake, LLC
+charity
+
+// chase : 2015-04-30 JPMorgan Chase Bank, National Association
chase
-// chat : 2014-12-04 Sand Fields, LLC
+// chat : 2014-12-04 Binky Moon, LLC
chat
-// cheap : 2013-11-14 Sand Cover, LLC
+// cheap : 2013-11-14 Binky Moon, LLC
cheap
// chintai : 2015-06-11 CHINTAI Corporation
@@ -7587,13 +7636,13 @@ chrome
// chrysler : 2015-07-30 FCA US LLC.
chrysler
-// church : 2014-02-06 Holly Fields, LLC
+// church : 2014-02-06 Binky Moon, LLC
church
// cipriani : 2015-02-19 Hotel Cipriani Srl
cipriani
-// circle : 2014-12-18 Amazon EU S.à r.l.
+// circle : 2014-12-18 Amazon Registry Services, Inc.
circle
// cisco : 2014-12-22 Cisco Technology, Inc.
@@ -7608,31 +7657,31 @@ citi
// citic : 2014-01-09 CITIC Group Corporation
citic
-// city : 2014-05-29 Snow Sky, LLC
+// city : 2014-05-29 Binky Moon, LLC
city
// cityeats : 2014-12-11 Lifestyle Domain Holdings, Inc.
cityeats
-// claims : 2014-03-20 Black Corner, LLC
+// claims : 2014-03-20 Binky Moon, LLC
claims
-// cleaning : 2013-12-05 Fox Shadow, LLC
+// cleaning : 2013-12-05 Binky Moon, LLC
cleaning
// click : 2014-06-05 Uniregistry, Corp.
click
-// clinic : 2014-03-20 Goose Park, LLC
+// clinic : 2014-03-20 Binky Moon, LLC
clinic
// clinique : 2015-10-01 The Estée Lauder Companies Inc.
clinique
-// clothing : 2013-08-27 Steel Lake, LLC
+// clothing : 2013-08-27 Binky Moon, LLC
clothing
-// cloud : 2015-04-16 ARUBA S.p.A.
+// cloud : 2015-04-16 Aruba PEC S.p.A.
cloud
// club : 2013-11-08 .CLUB DOMAINS, LLC
@@ -7641,19 +7690,19 @@ club
// clubmed : 2015-06-25 Club Méditerranée S.A.
clubmed
-// coach : 2014-10-09 Koko Island, LLC
+// coach : 2014-10-09 Binky Moon, LLC
coach
-// codes : 2013-10-31 Puff Willow, LLC
+// codes : 2013-10-31 Binky Moon, LLC
codes
-// coffee : 2013-10-17 Trixy Cover, LLC
+// coffee : 2013-10-17 Binky Moon, LLC
coffee
// college : 2014-01-16 XYZ.COM LLC
college
-// cologne : 2014-02-05 NetCologne Gesellschaft für Telekommunikation mbH
+// cologne : 2014-02-05 punkt.wien GmbH
cologne
// comcast : 2015-07-23 Comcast IP Holdings I, LLC
@@ -7662,64 +7711,64 @@ comcast
// commbank : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA
commbank
-// community : 2013-12-05 Fox Orchard, LLC
+// community : 2013-12-05 Binky Moon, LLC
community
-// company : 2013-11-07 Silver Avenue, LLC
+// company : 2013-11-07 Binky Moon, LLC
company
// compare : 2015-10-08 iSelect Ltd
compare
-// computer : 2013-10-24 Pine Mill, LLC
+// computer : 2013-10-24 Binky Moon, LLC
computer
// comsec : 2015-01-08 VeriSign, Inc.
comsec
-// condos : 2013-12-05 Pine House, LLC
+// condos : 2013-12-05 Binky Moon, LLC
condos
-// construction : 2013-09-16 Fox Dynamite, LLC
+// construction : 2013-09-16 Binky Moon, LLC
construction
-// consulting : 2013-12-05
+// consulting : 2013-12-05 United TLD Holdco Ltd.
consulting
// contact : 2015-01-08 Top Level Spectrum, Inc.
contact
-// contractors : 2013-09-10 Magic Woods, LLC
+// contractors : 2013-09-10 Binky Moon, LLC
contractors
-// cooking : 2013-11-21 Top Level Domain Holdings Limited
+// cooking : 2013-11-21 Minds + Machines Group Limited
cooking
// cookingchannel : 2015-07-02 Lifestyle Domain Holdings, Inc.
cookingchannel
-// cool : 2013-11-14 Koko Lake, LLC
+// cool : 2013-11-14 Binky Moon, LLC
cool
-// corsica : 2014-09-25 Collectivité Territoriale de Corse
+// corsica : 2014-09-25 Collectivité de Corse
corsica
-// country : 2013-12-19 Top Level Domain Holdings Limited
+// country : 2013-12-19 DotCountry LLC
country
-// coupon : 2015-02-26 Amazon EU S.à r.l.
+// coupon : 2015-02-26 Amazon Registry Services, Inc.
coupon
-// coupons : 2015-03-26 Black Island, LLC
+// coupons : 2015-03-26 Binky Moon, LLC
coupons
// courses : 2014-12-04 OPEN UNIVERSITIES AUSTRALIA PTY LTD
courses
-// credit : 2014-03-20 Snow Shadow, LLC
+// credit : 2014-03-20 Binky Moon, LLC
credit
-// creditcard : 2014-03-20 Binky Frostbite, LLC
+// creditcard : 2014-03-20 Binky Moon, LLC
creditcard
// creditunion : 2015-01-22 CUNA Performance Resources, LLC
@@ -7737,7 +7786,7 @@ crs
// cruise : 2015-12-10 Viking River Cruises (Bermuda) Ltd.
cruise
-// cruises : 2013-12-05 Spring Way, LLC
+// cruises : 2013-12-05 Binky Moon, LLC
cruises
// csc : 2014-09-25 Alliance-One Services, Inc.
@@ -7767,7 +7816,7 @@ data
// date : 2014-11-20 dot Date Limited
date
-// dating : 2013-12-05 Pine Fest, LLC
+// dating : 2013-12-05 Binky Moon, LLC
dating
// datsun : 2014-03-27 NISSAN MOTOR CO., LTD.
@@ -7779,22 +7828,22 @@ day
// dclk : 2014-11-20 Charleston Road Registry Inc.
dclk
-// dds : 2015-05-07 Top Level Domain Holdings Limited
+// dds : 2015-05-07 Minds + Machines Group Limited
dds
-// deal : 2015-06-25 Amazon EU S.à r.l.
+// deal : 2015-06-25 Amazon Registry Services, Inc.
deal
// dealer : 2014-12-22 Dealer Dot Com, Inc.
dealer
-// deals : 2014-05-22 Sand Sunset, LLC
+// deals : 2014-05-22 Binky Moon, LLC
deals
-// degree : 2014-03-06
+// degree : 2014-03-06 United TLD Holdco Ltd.
degree
-// delivery : 2014-09-11 Steel Station, LLC
+// delivery : 2014-09-11 Binky Moon, LLC
delivery
// dell : 2014-10-24 Dell Inc.
@@ -7809,10 +7858,10 @@ delta
// democrat : 2013-10-24 United TLD Holdco Ltd.
democrat
-// dental : 2014-03-20 Tin Birch, LLC
+// dental : 2014-03-20 Binky Moon, LLC
dental
-// dentist : 2014-03-20
+// dentist : 2014-03-20 United TLD Holdco Ltd.
dentist
// desi : 2013-11-14 Desi Networks LLC
@@ -7827,22 +7876,22 @@ dev
// dhl : 2015-07-23 Deutsche Post AG
dhl
-// diamonds : 2013-09-22 John Edge, LLC
+// diamonds : 2013-09-22 Binky Moon, LLC
diamonds
// diet : 2014-06-26 Uniregistry, Corp.
diet
-// digital : 2014-03-06 Dash Park, LLC
+// digital : 2014-03-06 Binky Moon, LLC
digital
-// direct : 2014-04-10 Half Trail, LLC
+// direct : 2014-04-10 Binky Moon, LLC
direct
-// directory : 2013-09-20 Extra Madison, LLC
+// directory : 2013-09-20 Binky Moon, LLC
directory
-// discount : 2014-03-06 Holly Hill, LLC
+// discount : 2014-03-06 Binky Moon, LLC
discount
// discover : 2015-07-23 Discover Financial Services
@@ -7860,19 +7909,19 @@ dnp
// docs : 2014-10-16 Charleston Road Registry Inc.
docs
-// doctor : 2016-06-02 Brice Trail, LLC
+// doctor : 2016-06-02 Binky Moon, LLC
doctor
// dodge : 2015-07-30 FCA US LLC.
dodge
-// dog : 2014-12-04 Koko Mill, LLC
+// dog : 2014-12-04 Binky Moon, LLC
dog
// doha : 2014-09-18 Communications Regulatory Authority (CRA)
doha
-// domains : 2013-10-17 Sugar Cross, LLC
+// domains : 2013-10-17 Binky Moon, LLC
domains
// dot : 2015-05-21 Dish DBS Corporation
@@ -7923,25 +7972,25 @@ eco
// edeka : 2014-12-18 EDEKA Verband kaufmännischer Genossenschaften e.V.
edeka
-// education : 2013-11-07 Brice Way, LLC
+// education : 2013-11-07 Binky Moon, LLC
education
-// email : 2013-10-31 Spring Madison, LLC
+// email : 2013-10-31 Binky Moon, LLC
email
// emerck : 2014-04-03 Merck KGaA
emerck
-// energy : 2014-09-11 Binky Birch, LLC
+// energy : 2014-09-11 Binky Moon, LLC
energy
// engineer : 2014-03-06 United TLD Holdco Ltd.
engineer
-// engineering : 2014-03-06 Romeo Canyon
+// engineering : 2014-03-06 Binky Moon, LLC
engineering
-// enterprises : 2013-09-20 Snow Oaks, LLC
+// enterprises : 2013-09-20 Binky Moon, LLC
enterprises
// epost : 2015-07-23 Deutsche Post AG
@@ -7950,7 +7999,7 @@ epost
// epson : 2014-12-04 Seiko Epson Corporation
epson
-// equipment : 2013-08-27 Corn Station, LLC
+// equipment : 2013-08-27 Binky Moon, LLC
equipment
// ericsson : 2015-07-09 Telefonaktiebolaget L M Ericsson
@@ -7962,7 +8011,7 @@ erni
// esq : 2014-05-08 Charleston Road Registry Inc.
esq
-// estate : 2013-08-27 Trixy Park, LLC
+// estate : 2013-08-27 Binky Moon, LLC
estate
// esurance : 2015-07-23 Esurance Insurance Company
@@ -7977,22 +8026,22 @@ eurovision
// eus : 2013-12-12 Puntueus Fundazioa
eus
-// events : 2013-12-05 Pioneer Maple, LLC
+// events : 2013-12-05 Binky Moon, LLC
events
// everbank : 2014-05-15 EverBank
everbank
-// exchange : 2014-03-06 Spring Falls, LLC
+// exchange : 2014-03-06 Binky Moon, LLC
exchange
-// expert : 2013-11-21 Magic Pass, LLC
+// expert : 2013-11-21 Binky Moon, LLC
expert
-// exposed : 2013-12-05 Victor Beach, LLC
+// exposed : 2013-12-05 Binky Moon, LLC
exposed
-// express : 2015-02-11 Sea Sunset, LLC
+// express : 2015-02-11 Binky Moon, LLC
express
// extraspace : 2015-05-14 Extra Space Storage LLC
@@ -8001,7 +8050,7 @@ extraspace
// fage : 2014-12-18 Fage International S.A.
fage
-// fail : 2014-03-06 Atomic Pipe, LLC
+// fail : 2014-03-06 Binky Moon, LLC
fail
// fairwinds : 2014-11-13 FairWinds Partners, LLC
@@ -8010,25 +8059,25 @@ fairwinds
// faith : 2014-11-20 dot Faith Limited
faith
-// family : 2015-04-02
+// family : 2015-04-02 United TLD Holdco Ltd.
family
-// fan : 2014-03-06
+// fan : 2014-03-06 Asiamix Digital Limited
fan
// fans : 2014-11-07 Asiamix Digital Limited
fans
-// farm : 2013-11-07 Just Maple, LLC
+// farm : 2013-11-07 Binky Moon, LLC
farm
// farmers : 2015-07-09 Farmers Insurance Exchange
farmers
-// fashion : 2014-07-03 Top Level Domain Holdings Limited
+// fashion : 2014-07-03 Minds + Machines Group Limited
fashion
-// fast : 2014-12-18 Amazon EU S.à r.l.
+// fast : 2014-12-18 Amazon Registry Services, Inc.
fast
// fedex : 2015-08-06 Federal Express Corporation
@@ -8049,7 +8098,7 @@ fiat
// fidelity : 2015-07-30 Fidelity Brokerage Services LLC
fidelity
-// fido : 2015-08-06 Rogers Communications Partnership
+// fido : 2015-08-06 Rogers Communications Canada Inc.
fido
// film : 2015-01-08 Motion Picture Domain Registry Pty Ltd
@@ -8058,43 +8107,43 @@ film
// final : 2014-10-16 Núcleo de Informação e Coordenação do Ponto BR - NIC.br
final
-// finance : 2014-03-20 Cotton Cypress, LLC
+// finance : 2014-03-20 Binky Moon, LLC
finance
-// financial : 2014-03-06 Just Cover, LLC
+// financial : 2014-03-06 Binky Moon, LLC
financial
-// fire : 2015-06-25 Amazon EU S.à r.l.
+// fire : 2015-06-25 Amazon Registry Services, Inc.
fire
-// firestone : 2014-12-18 Bridgestone Corporation
+// firestone : 2014-12-18 Bridgestone Licensing Services, Inc
firestone
// firmdale : 2014-03-27 Firmdale Holdings Limited
firmdale
-// fish : 2013-12-12 Fox Woods, LLC
+// fish : 2013-12-12 Binky Moon, LLC
fish
-// fishing : 2013-11-21 Top Level Domain Holdings Limited
+// fishing : 2013-11-21 Minds + Machines Group Limited
fishing
-// fit : 2014-11-07 Top Level Domain Holdings Limited
+// fit : 2014-11-07 Minds + Machines Group Limited
fit
-// fitness : 2014-03-06 Brice Orchard, LLC
+// fitness : 2014-03-06 Binky Moon, LLC
fitness
// flickr : 2015-04-02 Yahoo! Domain Services Inc.
flickr
-// flights : 2013-12-05 Fox Station, LLC
+// flights : 2013-12-05 Binky Moon, LLC
flights
// flir : 2015-07-23 FLIR Systems, Inc.
flir
-// florist : 2013-11-07 Half Cypress, LLC
+// florist : 2013-11-07 Binky Moon, LLC
florist
// flowers : 2014-10-09 Uniregistry, Corp.
@@ -8112,28 +8161,28 @@ food
// foodnetwork : 2015-07-02 Lifestyle Domain Holdings, Inc.
foodnetwork
-// football : 2014-12-18 Foggy Farms, LLC
+// football : 2014-12-18 Binky Moon, LLC
football
// ford : 2014-11-13 Ford Motor Company
ford
-// forex : 2014-12-11 IG Group Holdings PLC
+// forex : 2014-12-11 Dotforex Registry Limited
forex
-// forsale : 2014-05-22
+// forsale : 2014-05-22 United TLD Holdco Ltd.
forsale
// forum : 2015-04-02 Fegistry, LLC
forum
-// foundation : 2013-12-05 John Dale, LLC
+// foundation : 2013-12-05 Binky Moon, LLC
foundation
// fox : 2015-09-11 FOX Registry, LLC
fox
-// free : 2015-12-10 Amazon EU S.à r.l.
+// free : 2015-12-10 Amazon Registry Services, Inc.
free
// fresenius : 2015-07-30 Fresenius Immobilien-Verwaltungs-GmbH
@@ -8160,25 +8209,25 @@ fujitsu
// fujixerox : 2015-07-23 Xerox DNHC LLC
fujixerox
-// fun : 2016-01-14
+// fun : 2016-01-14 DotSpace Inc.
fun
-// fund : 2014-03-20 John Castle, LLC
+// fund : 2014-03-20 Binky Moon, LLC
fund
-// furniture : 2014-03-20 Lone Fields, LLC
+// furniture : 2014-03-20 Binky Moon, LLC
furniture
-// futbol : 2013-09-20
+// futbol : 2013-09-20 United TLD Holdco Ltd.
futbol
-// fyi : 2015-04-02 Silver Tigers, LLC
+// fyi : 2015-04-02 Binky Moon, LLC
fyi
// gal : 2013-11-07 Asociación puntoGAL
gal
-// gallery : 2013-09-13 Sugar House, LLC
+// gallery : 2013-09-13 Binky Moon, LLC
gallery
// gallo : 2015-06-11 Gallo Vineyards, Inc.
@@ -8190,13 +8239,13 @@ gallup
// game : 2015-05-28 Uniregistry, Corp.
game
-// games : 2015-05-28
+// games : 2015-05-28 United TLD Holdco Ltd.
games
// gap : 2015-07-31 The Gap, Inc.
gap
-// garden : 2014-06-26 Top Level Domain Holdings Limited
+// garden : 2014-06-26 Minds + Machines Group Limited
garden
// gbiz : 2014-07-17 Charleston Road Registry Inc.
@@ -8208,7 +8257,7 @@ gdn
// gea : 2014-12-04 GEA Group Aktiengesellschaft
gea
-// gent : 2014-01-23 COMBELL GROUP NV/SA
+// gent : 2014-01-23 COMBELL NV
gent
// genting : 2015-03-12 Resorts World Inc Pte. Ltd.
@@ -8220,10 +8269,10 @@ george
// ggee : 2014-01-09 GMO Internet, Inc.
ggee
-// gift : 2013-10-17 Uniregistry, Corp.
+// gift : 2013-10-17 DotGift, LLC
gift
-// gifts : 2014-07-03 Goose Sky, LLC
+// gifts : 2014-07-03 Binky Moon, LLC
gifts
// gives : 2014-03-06 United TLD Holdco Ltd.
@@ -8235,13 +8284,13 @@ giving
// glade : 2015-07-23 Johnson Shareholdings, Inc.
glade
-// glass : 2013-11-07 Black Cover, LLC
+// glass : 2013-11-07 Binky Moon, LLC
glass
// gle : 2014-07-24 Charleston Road Registry Inc.
gle
-// global : 2014-04-17 Dot GLOBAL AS
+// global : 2014-04-17 Dot Global Domain Registry Limited
global
// globo : 2013-12-19 Globo Comunicação e Participações S.A
@@ -8250,10 +8299,10 @@ globo
// gmail : 2014-05-01 Charleston Road Registry Inc.
gmail
-// gmbh : 2016-01-29 Extra Dynamite, LLC
+// gmbh : 2016-01-29 Binky Moon, LLC
gmbh
-// gmo : 2014-01-09 GMO Internet, Inc.
+// gmo : 2014-01-09 GMO Internet Pte. Ltd.
gmo
// gmx : 2014-04-24 1&1 Mail & Media GmbH
@@ -8262,13 +8311,13 @@ gmx
// godaddy : 2015-07-23 Go Daddy East, LLC
godaddy
-// gold : 2015-01-22 June Edge, LLC
+// gold : 2015-01-22 Binky Moon, LLC
gold
// goldpoint : 2014-11-20 YODOBASHI CAMERA CO.,LTD.
goldpoint
-// golf : 2014-12-18 Lone falls, LLC
+// golf : 2014-12-18 Binky Moon, LLC
golf
// goo : 2014-12-18 NTT Resonant Inc.
@@ -8289,28 +8338,28 @@ google
// gop : 2014-01-16 Republican State Leadership Committee, Inc.
gop
-// got : 2014-12-18 Amazon EU S.à r.l.
+// got : 2014-12-18 Amazon Registry Services, Inc.
got
// grainger : 2015-05-07 Grainger Registry Services, LLC
grainger
-// graphics : 2013-09-13 Over Madison, LLC
+// graphics : 2013-09-13 Binky Moon, LLC
graphics
-// gratis : 2014-03-20 Pioneer Tigers, LLC
+// gratis : 2014-03-20 Binky Moon, LLC
gratis
-// green : 2014-05-08 Afilias Limited
+// green : 2014-05-08 Afilias plc
green
-// gripe : 2014-03-06 Corn Sunset, LLC
+// gripe : 2014-03-06 Binky Moon, LLC
gripe
// grocery : 2016-06-16 Wal-Mart Stores, Inc.
grocery
-// group : 2014-08-15 Romeo Town, LLC
+// group : 2014-08-15 Binky Moon, LLC
group
// guardian : 2015-07-30 The Guardian Life Insurance Company of America
@@ -8322,13 +8371,13 @@ gucci
// guge : 2014-08-28 Charleston Road Registry Inc.
guge
-// guide : 2013-09-13 Snow Moon, LLC
+// guide : 2013-09-13 Binky Moon, LLC
guide
// guitars : 2013-11-14 Uniregistry, Corp.
guitars
-// guru : 2013-08-27 Pioneer Cypress, LLC
+// guru : 2013-08-27 Binky Moon, LLC
guru
// hair : 2015-12-03 L'Oréal
@@ -8340,7 +8389,7 @@ hamburg
// hangout : 2014-11-13 Charleston Road Registry Inc.
hangout
-// haus : 2013-12-05
+// haus : 2013-12-05 United TLD Holdco Ltd.
haus
// hbo : 2015-07-30 HBO Registry Services, Inc.
@@ -8355,7 +8404,7 @@ hdfcbank
// health : 2015-02-11 DotHealth, LLC
health
-// healthcare : 2014-06-12 Silver Glen, LLC
+// healthcare : 2014-06-12 Binky Moon, LLC
healthcare
// help : 2014-06-26 Uniregistry, Corp.
@@ -8382,22 +8431,22 @@ hisamitsu
// hitachi : 2014-10-31 Hitachi, Ltd.
hitachi
-// hiv : 2014-03-13
+// hiv : 2014-03-13 Uniregistry, Corp.
hiv
// hkt : 2015-05-14 PCCW-HKT DataCom Services Limited
hkt
-// hockey : 2015-03-19 Half Willow, LLC
+// hockey : 2015-03-19 Binky Moon, LLC
hockey
-// holdings : 2013-08-27 John Madison, LLC
+// holdings : 2013-08-27 Binky Moon, LLC
holdings
-// holiday : 2013-11-07 Goose Woods, LLC
+// holiday : 2013-11-07 Binky Moon, LLC
holiday
-// homedepot : 2015-04-02 Homer TLC, Inc.
+// homedepot : 2015-04-02 Home Depot Product Authority, LLC
homedepot
// homegoods : 2015-07-16 The TJX Companies, Inc.
@@ -8415,10 +8464,10 @@ honda
// honeywell : 2015-07-23 Honeywell GTLD LLC
honeywell
-// horse : 2013-11-21 Top Level Domain Holdings Limited
+// horse : 2013-11-21 Minds + Machines Group Limited
horse
-// hospital : 2016-10-20 Ruby Pike, LLC
+// hospital : 2016-10-20 Binky Moon, LLC
hospital
// host : 2014-04-17 DotHost Inc.
@@ -8427,7 +8476,7 @@ host
// hosting : 2014-05-29 Uniregistry, Corp.
hosting
-// hot : 2015-08-27 Amazon EU S.à r.l.
+// hot : 2015-08-27 Amazon Registry Services, Inc.
hot
// hoteles : 2015-03-05 Travel Reservations SRL
@@ -8439,13 +8488,13 @@ hotels
// hotmail : 2014-12-18 Microsoft Corporation
hotmail
-// house : 2013-11-07 Sugar Park, LLC
+// house : 2013-11-07 Binky Moon, LLC
house
// how : 2014-01-23 Charleston Road Registry Inc.
how
-// hsbc : 2014-10-24 HSBC Holdings PLC
+// hsbc : 2014-10-24 HSBC Global Services (UK) Limited
hsbc
// hughes : 2015-07-30 Hughes Satellite Systems Corporation
@@ -8466,7 +8515,7 @@ icbc
// ice : 2014-10-30 IntercontinentalExchange, Inc.
ice
-// icu : 2015-01-08 One.com A/S
+// icu : 2015-01-08 ShortDot SA
icu
// ieee : 2015-07-23 IEEE Global LLC
@@ -8481,16 +8530,19 @@ ikano
// imamat : 2015-08-06 Fondation Aga Khan (Aga Khan Foundation)
imamat
-// imdb : 2015-06-25 Amazon EU S.à r.l.
+// imdb : 2015-06-25 Amazon Registry Services, Inc.
imdb
-// immo : 2014-07-10 Auburn Bloom, LLC
+// immo : 2014-07-10 Binky Moon, LLC
immo
// immobilien : 2013-11-07 United TLD Holdco Ltd.
immobilien
-// industries : 2013-12-05 Outer House, LLC
+// inc : 2018-03-10 GTLD Limited
+inc
+
+// industries : 2013-12-05 Binky Moon, LLC
industries
// infiniti : 2014-03-27 NISSAN MOTOR CO., LTD.
@@ -8502,31 +8554,31 @@ ing
// ink : 2013-12-05 Top Level Design, LLC
ink
-// institute : 2013-11-07 Outer Maple, LLC
+// institute : 2013-11-07 Binky Moon, LLC
institute
// insurance : 2015-02-19 fTLD Registry Services LLC
insurance
-// insure : 2014-03-20 Pioneer Willow, LLC
+// insure : 2014-03-20 Binky Moon, LLC
insure
// intel : 2015-08-06 Intel Corporation
intel
-// international : 2013-11-07 Wild Way, LLC
+// international : 2013-11-07 Binky Moon, LLC
international
// intuit : 2015-07-30 Intuit Administrative Services, Inc.
intuit
-// investments : 2014-03-20 Holly Glen, LLC
+// investments : 2014-03-20 Binky Moon, LLC
investments
// ipiranga : 2014-08-28 Ipiranga Produtos de Petroleo S.A.
ipiranga
-// irish : 2014-08-07 Dot-Irish LLC
+// irish : 2014-08-07 Binky Moon, LLC
irish
// iselect : 2015-02-11 iSelect Ltd
@@ -8568,13 +8620,13 @@ jcp
// jeep : 2015-07-30 FCA US LLC.
jeep
-// jetzt : 2014-01-09
+// jetzt : 2014-01-09 Binky Moon, LLC
jetzt
-// jewelry : 2015-03-05 Wild Bloom, LLC
+// jewelry : 2015-03-05 Binky Moon, LLC
jewelry
-// jio : 2015-04-02 Affinity Names, Inc.
+// jio : 2015-04-02 Reliance Industries Limited
jio
// jlc : 2014-12-04 Richemont DNS Inc.
@@ -8592,13 +8644,13 @@ jnj
// joburg : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
joburg
-// jot : 2014-12-18 Amazon EU S.à r.l.
+// jot : 2014-12-18 Amazon Registry Services, Inc.
jot
-// joy : 2014-12-18 Amazon EU S.à r.l.
+// joy : 2014-12-18 Amazon Registry Services, Inc.
joy
-// jpmorgan : 2015-04-30 JPMorgan Chase & Co.
+// jpmorgan : 2015-04-30 JPMorgan Chase Bank, National Association
jpmorgan
// jprs : 2014-09-18 Japan Registry Services Co., Ltd.
@@ -8631,22 +8683,22 @@ kfh
// kia : 2015-07-09 KIA MOTORS CORPORATION
kia
-// kim : 2013-09-23 Afilias Limited
+// kim : 2013-09-23 Afilias plc
kim
// kinder : 2014-11-07 Ferrero Trading Lux S.A.
kinder
-// kindle : 2015-06-25 Amazon EU S.à r.l.
+// kindle : 2015-06-25 Amazon Registry Services, Inc.
kindle
-// kitchen : 2013-09-20 Just Goodbye, LLC
+// kitchen : 2013-09-20 Binky Moon, LLC
kitchen
// kiwi : 2013-09-20 DOT KIWI LIMITED
kiwi
-// koeln : 2014-01-09 NetCologne Gesellschaft für Telekommunikation mbH
+// koeln : 2014-01-09 punkt.wien GmbH
koeln
// komatsu : 2015-01-08 Komatsu Ltd.
@@ -8673,7 +8725,7 @@ kuokgroup
// kyoto : 2014-11-07 Academic Institution: Kyoto Jyoho Gakuen
kyoto
-// lacaixa : 2014-01-09 CAIXA D'ESTALVIS I PENSIONS DE BARCELONA
+// lacaixa : 2014-01-09 Fundación Bancaria Caixa d’Estalvis i Pensions de Barcelona, “la Caixa”
lacaixa
// ladbrokes : 2015-08-06 LADBROKES INTERNATIONAL PLC
@@ -8694,7 +8746,7 @@ lancia
// lancome : 2015-07-23 L'Oréal
lancome
-// land : 2013-09-10 Pine Moon, LLC
+// land : 2013-09-10 Binky Moon, LLC
land
// landrover : 2014-11-13 Jaguar Land Rover Ltd
@@ -8718,13 +8770,13 @@ latrobe
// law : 2015-01-22 Minds + Machines Group Limited
law
-// lawyer : 2014-03-20
+// lawyer : 2014-03-20 United TLD Holdco Ltd.
lawyer
// lds : 2014-03-20 IRI Domain Management, LLC ("Applicant")
lds
-// lease : 2014-03-06 Victor Trail, LLC
+// lease : 2014-03-06 Binky Moon, LLC
lease
// leclerc : 2014-08-07 A.C.D. LEC Association des Centres Distributeurs Edouard Leclerc
@@ -8733,7 +8785,7 @@ leclerc
// lefrak : 2015-07-16 LeFrak Organization, Inc.
lefrak
-// legal : 2014-10-16 Blue Falls, LLC
+// legal : 2014-10-16 Binky Moon, LLC
legal
// lego : 2015-07-16 LEGO Juris A/S
@@ -8742,7 +8794,7 @@ lego
// lexus : 2015-04-23 TOYOTA MOTOR CORPORATION
lexus
-// lgbt : 2014-05-08 Afilias Limited
+// lgbt : 2014-05-08 Afilias plc
lgbt
// liaison : 2014-10-02 Liaison Technologies, Incorporated
@@ -8751,7 +8803,7 @@ liaison
// lidl : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG
lidl
-// life : 2014-02-06 Trixy Oaks, LLC
+// life : 2014-02-06 Binky Moon, LLC
life
// lifeinsurance : 2015-01-15 American Council of Life Insurers
@@ -8760,19 +8812,19 @@ lifeinsurance
// lifestyle : 2014-12-11 Lifestyle Domain Holdings, Inc.
lifestyle
-// lighting : 2013-08-27 John McCook, LLC
+// lighting : 2013-08-27 Binky Moon, LLC
lighting
-// like : 2014-12-18 Amazon EU S.à r.l.
+// like : 2014-12-18 Amazon Registry Services, Inc.
like
// lilly : 2015-07-31 Eli Lilly and Company
lilly
-// limited : 2014-03-06 Big Fest, LLC
+// limited : 2014-03-06 Binky Moon, LLC
limited
-// limo : 2013-10-17 Hidden Frostbite, LLC
+// limo : 2013-10-17 Binky Moon, LLC
limo
// lincoln : 2014-11-13 Ford Motor Company
@@ -8787,7 +8839,7 @@ link
// lipsy : 2015-06-25 Lipsy Ltd
lipsy
-// live : 2014-12-04
+// live : 2014-12-04 United TLD Holdco Ltd.
live
// living : 2015-07-30 Lifestyle Domain Holdings, Inc.
@@ -8796,10 +8848,13 @@ living
// lixil : 2015-03-19 LIXIL Group Corporation
lixil
+// llc : 2017-12-14 Afilias plc
+llc
+
// loan : 2014-11-20 dot Loan Limited
loan
-// loans : 2014-03-20 June Woods, LLC
+// loans : 2014-03-20 Binky Moon, LLC
loans
// locker : 2015-06-04 Dish DBS Corporation
@@ -8820,7 +8875,7 @@ london
// lotte : 2014-11-07 Lotte Holdings Co., Ltd.
lotte
-// lotto : 2014-04-10 Afilias Limited
+// lotto : 2014-04-10 Afilias plc
lotto
// love : 2014-12-22 Merchant Law Group LLP
@@ -8832,10 +8887,10 @@ lpl
// lplfinancial : 2015-07-30 LPL Holdings, Inc.
lplfinancial
-// ltd : 2014-09-25 Over Corner, LLC
+// ltd : 2014-09-25 Binky Moon, LLC
ltd
-// ltda : 2014-04-17 DOMAIN ROBOT SERVICOS DE HOSPEDAGEM NA INTERNET LTDA
+// ltda : 2014-04-17 InterNetX, Corp
ltda
// lundbeck : 2015-08-06 H. Lundbeck A/S
@@ -8844,7 +8899,7 @@ lundbeck
// lupin : 2014-11-07 LUPIN LIMITED
lupin
-// luxe : 2014-01-09 Top Level Domain Holdings Limited
+// luxe : 2014-01-09 Minds + Machines Group Limited
luxe
// luxury : 2013-10-17 Luxury Partners, LLC
@@ -8859,7 +8914,7 @@ madrid
// maif : 2014-10-02 Mutuelle Assurance Instituteur France (MAIF)
maif
-// maison : 2013-12-05 Victor Frostbite, LLC
+// maison : 2013-12-05 Binky Moon, LLC
maison
// makeup : 2015-01-15 L'Oréal
@@ -8868,7 +8923,7 @@ makeup
// man : 2014-12-04 MAN SE
man
-// management : 2013-11-07 John Goodbye, LLC
+// management : 2013-11-07 Binky Moon, LLC
management
// mango : 2013-10-24 PUNTO FA S.L.
@@ -8877,13 +8932,13 @@ mango
// map : 2016-06-09 Charleston Road Registry Inc.
map
-// market : 2014-03-06
+// market : 2014-03-06 United TLD Holdco Ltd.
market
-// marketing : 2013-11-07 Fern Pass, LLC
+// marketing : 2013-11-07 Binky Moon, LLC
marketing
-// markets : 2014-12-11 IG Group Holdings PLC
+// markets : 2014-12-11 Dotmarkets Registry Limited
markets
// marriott : 2014-10-09 Marriott Worldwide Corporation
@@ -8898,7 +8953,7 @@ maserati
// mattel : 2015-08-06 Mattel Sites, Inc.
mattel
-// mba : 2015-04-02 Lone Hollow, LLC
+// mba : 2015-04-02 Binky Moon, LLC
mba
// mckinsey : 2015-07-31 McKinsey Holdings, Inc.
@@ -8907,10 +8962,10 @@ mckinsey
// med : 2015-08-06 Medistry LLC
med
-// media : 2014-03-06 Grand Glen, LLC
+// media : 2014-03-06 Binky Moon, LLC
media
-// meet : 2014-01-16
+// meet : 2014-01-16 Charleston Road Registry Inc.
meet
// melbourne : 2014-05-29 The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation
@@ -8928,7 +8983,7 @@ men
// menu : 2013-09-11 Wedding TLD2, LLC
menu
-// meo : 2014-11-07 PT Comunicacoes S.A.
+// meo : 2014-11-07 MEO Servicos de Comunicacoes e Multimedia, S.A.
meo
// merckmsd : 2016-07-14 MSD Registry Holdings, Inc.
@@ -8937,7 +8992,7 @@ merckmsd
// metlife : 2015-05-07 MetLife Services and Solutions, LLC
metlife
-// miami : 2013-12-19 Top Level Domain Holdings Limited
+// miami : 2013-12-19 Minds + Machines Group Limited
miami
// microsoft : 2014-12-18 Microsoft Corporation
@@ -8976,7 +9031,7 @@ moda
// moe : 2013-11-13 Interlink Co., Ltd.
moe
-// moi : 2014-12-18 Amazon EU S.à r.l.
+// moi : 2014-12-18 Amazon Registry Services, Inc.
moi
// mom : 2015-04-16 Uniregistry, Corp.
@@ -8985,7 +9040,7 @@ mom
// monash : 2013-09-30 Monash University
monash
-// money : 2014-10-16 Outer McCook, LLC
+// money : 2014-10-16 Binky Moon, LLC
money
// monster : 2015-09-11 Monster Worldwide, Inc.
@@ -8997,13 +9052,13 @@ mopar
// mormon : 2013-12-05 IRI Domain Management, LLC ("Applicant")
mormon
-// mortgage : 2014-03-20
+// mortgage : 2014-03-20 United TLD Holdco Ltd.
mortgage
// moscow : 2013-12-19 Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID)
moscow
-// moto : 2015-06-04
+// moto : 2015-06-04 Motorola Trademark Holdings, LLC
moto
// motorcycles : 2014-01-09 DERMotorcycles, LLC
@@ -9012,7 +9067,7 @@ motorcycles
// mov : 2014-01-30 Charleston Road Registry Inc.
mov
-// movie : 2015-02-05 New Frostbite, LLC
+// movie : 2015-02-05 Binky Moon, LLC
movie
// movistar : 2014-10-16 Telefónica S.A.
@@ -9024,9 +9079,6 @@ msd
// mtn : 2014-12-04 MTN Dubai Limited
mtn
-// mtpc : 2014-11-20 Mitsubishi Tanabe Pharma Corporation
-mtpc
-
// mtr : 2015-03-12 MTR Corporation Limited
mtr
@@ -9036,7 +9088,7 @@ mutual
// nab : 2015-08-20 National Australia Bank Limited
nab
-// nadex : 2014-12-11 IG Group Holdings PLC
+// nadex : 2014-12-11 Nadex Domains, Inc.
nadex
// nagoya : 2013-10-24 GMO Registry, Inc.
@@ -9063,10 +9115,10 @@ netbank
// netflix : 2015-06-18 Netflix, Inc.
netflix
-// network : 2013-11-14 Trixy Manor, LLC
+// network : 2013-11-14 Binky Moon, LLC
network
-// neustar : 2013-12-05 NeuStar, Inc.
+// neustar : 2013-12-05 Registry Services, LLC
neustar
// new : 2014-01-30 Charleston Road Registry Inc.
@@ -9075,7 +9127,7 @@ new
// newholland : 2015-09-03 CNH Industrial N.V.
newholland
-// news : 2014-12-18
+// news : 2014-12-18 United TLD Holdco Ltd.
news
// next : 2015-06-18 Next plc
@@ -9123,7 +9175,7 @@ northwesternmutual
// norton : 2014-12-04 Symantec Corporation
norton
-// now : 2015-06-25 Amazon EU S.à r.l.
+// now : 2015-06-25 Amazon Registry Services, Inc.
now
// nowruz : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
@@ -9147,7 +9199,7 @@ nyc
// obi : 2014-09-25 OBI Group Holding SE & Co. KGaA
obi
-// observer : 2015-04-30
+// observer : 2015-04-30 Top Level Spectrum, Inc.
observer
// off : 2015-07-23 Johnson Shareholdings, Inc.
@@ -9156,7 +9208,7 @@ off
// office : 2015-03-12 Microsoft Corporation
office
-// okinawa : 2013-12-05 BusinessRalliart Inc.
+// okinawa : 2013-12-05 BRregistry, Inc.
okinawa
// olayan : 2015-05-14 Crescent Holding GmbH
@@ -9201,13 +9253,13 @@ oracle
// orange : 2015-03-12 Orange Brand Services Limited
orange
-// organic : 2014-03-27 Afilias Limited
+// organic : 2014-03-27 Afilias plc
organic
// origins : 2015-10-01 The Estée Lauder Companies Inc.
origins
-// osaka : 2014-09-04 Interlink Co., Ltd.
+// osaka : 2014-09-04 Osaka Registry Co., Ltd.
osaka
// otsuka : 2013-10-11 Otsuka Holdings Co., Ltd.
@@ -9234,10 +9286,10 @@ paris
// pars : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
pars
-// partners : 2013-12-05 Magic Glen, LLC
+// partners : 2013-12-05 Binky Moon, LLC
partners
-// parts : 2013-12-05 Sea Goodbye, LLC
+// parts : 2013-12-05 Binky Moon, LLC
parts
// party : 2014-09-11 Blue Sky Registry Limited
@@ -9246,7 +9298,7 @@ party
// passagens : 2015-03-05 Travel Reservations SRL
passagens
-// pay : 2015-08-27 Amazon EU S.à r.l.
+// pay : 2015-08-27 Amazon Registry Services, Inc.
pay
// pccw : 2015-05-14 PCCW Enterprises Limited
@@ -9273,10 +9325,10 @@ phone
// photo : 2013-11-14 Uniregistry, Corp.
photo
-// photography : 2013-09-20 Sugar Glen, LLC
+// photography : 2013-09-20 Binky Moon, LLC
photography
-// photos : 2013-10-17 Sea Corner, LLC
+// photos : 2013-10-17 Binky Moon, LLC
photos
// physio : 2014-05-01 PhysBiz Pty Ltd
@@ -9291,28 +9343,28 @@ pics
// pictet : 2014-06-26 Pictet Europe S.A.
pictet
-// pictures : 2014-03-06 Foggy Sky, LLC
+// pictures : 2014-03-06 Binky Moon, LLC
pictures
// pid : 2015-01-08 Top Level Spectrum, Inc.
pid
-// pin : 2014-12-18 Amazon EU S.à r.l.
+// pin : 2014-12-18 Amazon Registry Services, Inc.
pin
// ping : 2015-06-11 Ping Registry Provider, Inc.
ping
-// pink : 2013-10-01 Afilias Limited
+// pink : 2013-10-01 Afilias plc
pink
// pioneer : 2015-07-16 Pioneer Corporation
pioneer
-// pizza : 2014-06-26 Foggy Moon, LLC
+// pizza : 2014-06-26 Binky Moon, LLC
pizza
-// place : 2014-04-24 Snow Galley, LLC
+// place : 2014-04-24 Binky Moon, LLC
place
// play : 2015-03-05 Charleston Road Registry Inc.
@@ -9321,10 +9373,10 @@ play
// playstation : 2015-07-02 Sony Computer Entertainment Inc.
playstation
-// plumbing : 2013-09-10 Spring Tigers, LLC
+// plumbing : 2013-09-10 Binky Moon, LLC
plumbing
-// plus : 2015-02-05 Sugar Mill, LLC
+// plus : 2015-02-05 Binky Moon, LLC
plus
// pnc : 2015-07-02 PNC Domain Co., LLC
@@ -9333,7 +9385,7 @@ pnc
// pohl : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
pohl
-// poker : 2014-07-03 Afilias Domains No. 5 Limited
+// poker : 2014-07-03 Afilias plc
poker
// politie : 2015-08-20 Politie Nederland
@@ -9351,13 +9403,13 @@ praxi
// press : 2014-04-03 DotPress Inc.
press
-// prime : 2015-06-25 Amazon EU S.à r.l.
+// prime : 2015-06-25 Amazon Registry Services, Inc.
prime
// prod : 2014-01-23 Charleston Road Registry Inc.
prod
-// productions : 2013-12-05 Magic Birch, LLC
+// productions : 2013-12-05 Binky Moon, LLC
productions
// prof : 2014-07-24 Charleston Road Registry Inc.
@@ -9366,16 +9418,16 @@ prof
// progressive : 2015-07-23 Progressive Casualty Insurance Company
progressive
-// promo : 2014-12-18
+// promo : 2014-12-18 Afilias plc
promo
-// properties : 2013-12-05 Big Pass, LLC
+// properties : 2013-12-05 Binky Moon, LLC
properties
// property : 2014-05-22 Uniregistry, Corp.
property
-// protection : 2015-04-23
+// protection : 2015-04-23 XYZ.COM LLC
protection
// pru : 2015-07-30 Prudential Financial, Inc.
@@ -9411,7 +9463,7 @@ radio
// raid : 2015-07-23 Johnson Shareholdings, Inc.
raid
-// read : 2014-12-18 Amazon EU S.à r.l.
+// read : 2014-12-18 Amazon Registry Services, Inc.
read
// realestate : 2015-09-11 dotRealEstate LLC
@@ -9423,10 +9475,10 @@ realtor
// realty : 2015-03-19 Fegistry, LLC
realty
-// recipes : 2013-10-17 Grand Island, LLC
+// recipes : 2013-10-17 Binky Moon, LLC
recipes
-// red : 2013-11-07 Afilias Limited
+// red : 2013-11-07 Afilias plc
red
// redstone : 2014-10-31 Redstone Haute Couture Co., Ltd.
@@ -9438,10 +9490,10 @@ redumbrella
// rehab : 2014-03-06 United TLD Holdco Ltd.
rehab
-// reise : 2014-03-13
+// reise : 2014-03-13 Binky Moon, LLC
reise
-// reisen : 2014-03-06 New Cypress, LLC
+// reisen : 2014-03-06 Binky Moon, LLC
reisen
// reit : 2014-09-04 National Association of Real Estate Investment Trusts, Inc.
@@ -9453,16 +9505,16 @@ reliance
// ren : 2013-12-12 Beijing Qianxiang Wangjing Technology Development Co., Ltd.
ren
-// rent : 2014-12-04 DERRent, LLC
+// rent : 2014-12-04 XYZ.COM LLC
rent
-// rentals : 2013-12-05 Big Hollow,LLC
+// rentals : 2013-12-05 Binky Moon, LLC
rentals
-// repair : 2013-11-07 Lone Sunset, LLC
+// repair : 2013-11-07 Binky Moon, LLC
repair
-// report : 2013-12-05 Binky Glen, LLC
+// report : 2013-12-05 Binky Moon, LLC
report
// republican : 2014-03-20 United TLD Holdco Ltd.
@@ -9471,13 +9523,13 @@ republican
// rest : 2013-12-19 Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable
rest
-// restaurant : 2014-07-03 Snow Avenue, LLC
+// restaurant : 2014-07-03 Binky Moon, LLC
restaurant
// review : 2014-11-20 dot Review Limited
review
-// reviews : 2013-09-13
+// reviews : 2013-09-13 United TLD Holdco Ltd.
reviews
// rexroth : 2015-06-18 Robert Bosch GMBH
@@ -9510,16 +9562,16 @@ rmit
// rocher : 2014-12-18 Ferrero Trading Lux S.A.
rocher
-// rocks : 2013-11-14
+// rocks : 2013-11-14 United TLD Holdco Ltd.
rocks
-// rodeo : 2013-12-19 Top Level Domain Holdings Limited
+// rodeo : 2013-12-19 Minds + Machines Group Limited
rodeo
-// rogers : 2015-08-06 Rogers Communications Partnership
+// rogers : 2015-08-06 Rogers Communications Canada Inc.
rogers
-// room : 2014-12-18 Amazon EU S.à r.l.
+// room : 2014-12-18 Amazon Registry Services, Inc.
room
// rsvp : 2014-05-08 Charleston Road Registry Inc.
@@ -9531,19 +9583,19 @@ rugby
// ruhr : 2013-10-02 regiodot GmbH & Co. KG
ruhr
-// run : 2015-03-19 Snow Park, LLC
+// run : 2015-03-19 Binky Moon, LLC
run
// rwe : 2015-04-02 RWE AG
rwe
-// ryukyu : 2014-01-09 BusinessRalliart Inc.
+// ryukyu : 2014-01-09 BRregistry, Inc.
ryukyu
// saarland : 2013-12-12 dotSaarland GmbH
saarland
-// safe : 2014-12-18 Amazon EU S.à r.l.
+// safe : 2014-12-18 Amazon Registry Services, Inc.
safe
// safety : 2015-01-08 Safety Registry Services, LLC.
@@ -9552,10 +9604,10 @@ safety
// sakura : 2014-12-18 SAKURA Internet Inc.
sakura
-// sale : 2014-10-16
+// sale : 2014-10-16 United TLD Holdco Ltd.
sale
-// salon : 2014-12-11 Outer Orchard, LLC
+// salon : 2014-12-11 Binky Moon, LLC
salon
// samsclub : 2015-07-31 Wal-Mart Stores, Inc.
@@ -9576,16 +9628,16 @@ sanofi
// sap : 2014-03-27 SAP AG
sap
-// sapo : 2014-11-07 PT Comunicacoes S.A.
+// sapo : 2014-11-07 MEO Servicos de Comunicacoes e Multimedia, S.A.
sapo
-// sarl : 2014-07-03 Delta Orchard, LLC
+// sarl : 2014-07-03 Binky Moon, LLC
sarl
// sas : 2015-04-02 Research IP LLC
sas
-// save : 2015-06-25 Amazon EU S.à r.l.
+// save : 2015-06-25 Amazon Registry Services, Inc.
save
// saxo : 2014-10-31 Saxo Bank A/S
@@ -9612,10 +9664,10 @@ schmidt
// scholarships : 2014-04-24 Scholarships.com, LLC
scholarships
-// school : 2014-12-18 Little Galley, LLC
+// school : 2014-12-18 Binky Moon, LLC
school
-// schule : 2014-03-06 Outer Moon, LLC
+// schule : 2014-03-06 Binky Moon, LLC
schule
// schwarz : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG
@@ -9639,10 +9691,10 @@ search
// seat : 2014-05-22 SEAT, S.A. (Sociedad Unipersonal)
seat
-// secure : 2015-08-27 Amazon EU S.à r.l.
+// secure : 2015-08-27 Amazon Registry Services, Inc.
secure
-// security : 2015-05-14
+// security : 2015-05-14 XYZ.COM LLC
security
// seek : 2014-12-04 Seek Limited
@@ -9654,7 +9706,7 @@ select
// sener : 2014-10-24 Sener Ingeniería y Sistemas, S.A.
sener
-// services : 2014-02-27 Fox Castle, LLC
+// services : 2014-02-27 Binky Moon, LLC
services
// ses : 2015-07-23 SES
@@ -9690,22 +9742,22 @@ shell
// shia : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
shia
-// shiksha : 2013-11-14 Afilias Limited
+// shiksha : 2013-11-14 Afilias plc
shiksha
-// shoes : 2013-10-02 Binky Galley, LLC
+// shoes : 2013-10-02 Binky Moon, LLC
shoes
// shop : 2016-04-08 GMO Registry, Inc.
shop
-// shopping : 2016-03-31
+// shopping : 2016-03-31 Binky Moon, LLC
shopping
// shouji : 2015-01-08 QIHOO 360 TECHNOLOGY CO. LTD.
shouji
-// show : 2015-03-05 Snow Beach, LLC
+// show : 2015-03-05 Binky Moon, LLC
show
// showtime : 2015-08-06 CBS Domains Inc.
@@ -9714,25 +9766,25 @@ showtime
// shriram : 2014-01-23 Shriram Capital Ltd.
shriram
-// silk : 2015-06-25 Amazon EU S.à r.l.
+// silk : 2015-06-25 Amazon Registry Services, Inc.
silk
// sina : 2015-03-12 Sina Corporation
sina
-// singles : 2013-08-27 Fern Madison, LLC
+// singles : 2013-08-27 Binky Moon, LLC
singles
// site : 2015-01-15 DotSite Inc.
site
-// ski : 2015-04-09 STARTING DOT LIMITED
+// ski : 2015-04-09 Afilias plc
ski
// skin : 2015-01-15 L'Oréal
skin
-// sky : 2014-06-19 Sky IP International Ltd, a company incorporated in England and Wales, operating via its registered Swiss branch
+// sky : 2014-06-19 Sky International AG
sky
// skype : 2014-12-18 Microsoft Corporation
@@ -9744,13 +9796,13 @@ sling
// smart : 2015-07-09 Smart Communications, Inc. (SMART)
smart
-// smile : 2014-12-18 Amazon EU S.à r.l.
+// smile : 2014-12-18 Amazon Registry Services, Inc.
smile
// sncf : 2015-02-19 Société Nationale des Chemins de fer Francais S N C F
sncf
-// soccer : 2015-03-26 Foggy Shadow, LLC
+// soccer : 2015-03-26 Binky Moon, LLC
soccer
// social : 2013-11-07 United TLD Holdco Ltd.
@@ -9759,19 +9811,19 @@ social
// softbank : 2015-07-02 SoftBank Corp.
softbank
-// software : 2014-03-20
+// software : 2014-03-20 United TLD Holdco Ltd.
software
// sohu : 2013-12-19 Sohu.com Limited
sohu
-// solar : 2013-11-07 Ruby Town, LLC
+// solar : 2013-11-07 Binky Moon, LLC
solar
-// solutions : 2013-11-07 Silver Cover, LLC
+// solutions : 2013-11-07 Binky Moon, LLC
solutions
-// song : 2015-02-26 Amazon EU S.à r.l.
+// song : 2015-02-26 Amazon Registry Services, Inc.
song
// sony : 2015-01-08 Sony Corporation
@@ -9786,13 +9838,16 @@ space
// spiegel : 2014-02-05 SPIEGEL-Verlag Rudolf Augstein GmbH & Co. KG
spiegel
-// spot : 2015-02-26 Amazon EU S.à r.l.
+// sport : 2017-11-16 Global Association of International Sports Federations (GAISF)
+sport
+
+// spot : 2015-02-26 Amazon Registry Services, Inc.
spot
-// spreadbetting : 2014-12-11 IG Group Holdings PLC
+// spreadbetting : 2014-12-11 Dotspreadbetting Registry Limited
spreadbetting
-// srl : 2015-05-07 mySRL GmbH
+// srl : 2015-05-07 InterNetX, Corp
srl
// srt : 2015-07-30 FCA US LLC.
@@ -9828,7 +9883,7 @@ stcgroup
// stockholm : 2014-12-18 Stockholms kommun
stockholm
-// storage : 2014-12-22 Self Storage Company LLC
+// storage : 2014-12-22 XYZ.COM LLC
storage
// store : 2015-04-09 DotStore Inc.
@@ -9837,7 +9892,7 @@ store
// stream : 2016-01-08 dot Stream Limited
stream
-// studio : 2015-02-11
+// studio : 2015-02-11 United TLD Holdco Ltd.
studio
// study : 2014-12-11 OPEN UNIVERSITIES AUSTRALIA PTY LTD
@@ -9846,22 +9901,22 @@ study
// style : 2014-12-04 Binky Moon, LLC
style
-// sucks : 2014-12-22 Vox Populi Registry Inc.
+// sucks : 2014-12-22 Vox Populi Registry Ltd.
sucks
-// supplies : 2013-12-19 Atomic Fields, LLC
+// supplies : 2013-12-19 Binky Moon, LLC
supplies
-// supply : 2013-12-19 Half Falls, LLC
+// supply : 2013-12-19 Binky Moon, LLC
supply
-// support : 2013-10-24 Grand Orchard, LLC
+// support : 2013-10-24 Binky Moon, LLC
support
-// surf : 2014-01-09 Top Level Domain Holdings Limited
+// surf : 2014-01-09 Minds + Machines Group Limited
surf
-// surgery : 2014-03-20 Tin Avenue, LLC
+// surgery : 2014-03-20 Binky Moon, LLC
surgery
// suzuki : 2014-02-20 SUZUKI MOTOR CORPORATION
@@ -9882,7 +9937,7 @@ sydney
// symantec : 2014-12-04 Symantec Corporation
symantec
-// systems : 2013-11-07 Dash Cypress, LLC
+// systems : 2013-11-07 Binky Moon, LLC
systems
// tab : 2014-12-04 Tabcorp Holdings Limited
@@ -9891,7 +9946,7 @@ tab
// taipei : 2014-07-10 Taipei City Government
taipei
-// talk : 2015-04-09 Amazon EU S.à r.l.
+// talk : 2015-04-09 Amazon Registry Services, Inc.
talk
// taobao : 2015-01-15 Alibaba Group Holding Limited
@@ -9909,10 +9964,10 @@ tatar
// tattoo : 2013-08-30 Uniregistry, Corp.
tattoo
-// tax : 2014-03-20 Storm Orchard, LLC
+// tax : 2014-03-20 Binky Moon, LLC
tax
-// taxi : 2015-03-19 Pine Falls, LLC
+// taxi : 2015-03-19 Binky Moon, LLC
taxi
// tci : 2014-09-12 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
@@ -9921,13 +9976,13 @@ tci
// tdk : 2015-06-11 TDK Corporation
tdk
-// team : 2015-03-05 Atomic Lake, LLC
+// team : 2015-03-05 Binky Moon, LLC
team
-// tech : 2015-01-30 Dot Tech LLC
+// tech : 2015-01-30 Personals TLD Inc.
tech
-// technology : 2013-09-13 Auburn Falls
+// technology : 2013-09-13 Binky Moon, LLC
technology
// telecity : 2015-02-19 TelecityGroup International Limited
@@ -9939,19 +9994,19 @@ telefonica
// temasek : 2014-08-07 Temasek Holdings (Private) Limited
temasek
-// tennis : 2014-12-04 Cotton Bloom, LLC
+// tennis : 2014-12-04 Binky Moon, LLC
tennis
// teva : 2015-07-02 Teva Pharmaceutical Industries Limited
teva
-// thd : 2015-04-02 Homer TLC, Inc.
+// thd : 2015-04-02 Home Depot Product Authority, LLC
thd
-// theater : 2015-03-19 Blue Tigers, LLC
+// theater : 2015-03-19 Binky Moon, LLC
theater
-// theatre : 2015-05-07
+// theatre : 2015-05-07 XYZ.COM LLC
theatre
// tiaa : 2015-07-23 Teachers Insurance and Annuity Association of America
@@ -9960,16 +10015,16 @@ tiaa
// tickets : 2015-02-05 Accent Media Limited
tickets
-// tienda : 2013-11-14 Victor Manor, LLC
+// tienda : 2013-11-14 Binky Moon, LLC
tienda
// tiffany : 2015-01-30 Tiffany and Company
tiffany
-// tips : 2013-09-20 Corn Willow, LLC
+// tips : 2013-09-20 Binky Moon, LLC
tips
-// tires : 2014-11-07 Dog Edge, LLC
+// tires : 2014-11-07 Binky Moon, LLC
tires
// tirol : 2014-04-24 punkt Tirol GmbH
@@ -9987,16 +10042,16 @@ tkmaxx
// tmall : 2015-01-15 Alibaba Group Holding Limited
tmall
-// today : 2013-09-20 Pearl Woods, LLC
+// today : 2013-09-20 Binky Moon, LLC
today
// tokyo : 2013-11-13 GMO Registry, Inc.
tokyo
-// tools : 2013-11-21 Pioneer North, LLC
+// tools : 2013-11-21 Binky Moon, LLC
tools
-// top : 2014-03-20 Jiangsu Bangning Science & Technology Co.,Ltd.
+// top : 2014-03-20 .TOP Registry
top
// toray : 2014-12-18 Toray Industries, Inc.
@@ -10008,27 +10063,30 @@ toshiba
// total : 2015-08-06 Total SA
total
-// tours : 2015-01-22 Sugar Station, LLC
+// tours : 2015-01-22 Binky Moon, LLC
tours
-// town : 2014-03-06 Koko Moon, LLC
+// town : 2014-03-06 Binky Moon, LLC
town
// toyota : 2015-04-23 TOYOTA MOTOR CORPORATION
toyota
-// toys : 2014-03-06 Pioneer Orchard, LLC
+// toys : 2014-03-06 Binky Moon, LLC
toys
// trade : 2014-01-23 Elite Registry Limited
trade
-// trading : 2014-12-11 IG Group Holdings PLC
+// trading : 2014-12-11 Dottrading Registry Limited
trading
-// training : 2013-11-07 Wild Willow, LLC
+// training : 2013-11-07 Binky Moon, LLC
training
+// travel : Dog Beach, LLC
+travel
+
// travelchannel : 2015-07-02 Lifestyle Domain Holdings, Inc.
travelchannel
@@ -10038,7 +10096,7 @@ travelers
// travelersinsurance : 2015-03-26 Travelers TLD, LLC
travelersinsurance
-// trust : 2014-10-16
+// trust : 2014-10-16 NCC Group Inc.
trust
// trv : 2015-03-26 Travelers TLD, LLC
@@ -10050,10 +10108,10 @@ tube
// tui : 2014-07-03 TUI AG
tui
-// tunes : 2015-02-26 Amazon EU S.à r.l.
+// tunes : 2015-02-26 Amazon Registry Services, Inc.
tunes
-// tushu : 2014-12-18 Amazon EU S.à r.l.
+// tushu : 2014-12-18 Amazon Registry Services, Inc.
tushu
// tvs : 2015-02-19 T V SUNDRAM IYENGAR & SONS LIMITED
@@ -10071,7 +10129,7 @@ uconnect
// unicom : 2015-10-15 China United Network Communications Corporation Limited
unicom
-// university : 2014-03-06 Little Station, LLC
+// university : 2014-03-06 Binky Moon, LLC
university
// uno : 2013-09-11 Dot Latin LLC
@@ -10083,7 +10141,7 @@ uol
// ups : 2015-06-25 UPS Market Driver, Inc.
ups
-// vacations : 2013-12-05 Atomic Tigers, LLC
+// vacations : 2013-12-05 Binky Moon, LLC
vacations
// vana : 2014-12-11 Lifestyle Domain Holdings, Inc.
@@ -10095,22 +10153,22 @@ vanguard
// vegas : 2014-01-16 Dot Vegas, Inc.
vegas
-// ventures : 2013-08-27 Binky Lake, LLC
+// ventures : 2013-08-27 Binky Moon, LLC
ventures
// verisign : 2015-08-13 VeriSign, Inc.
verisign
-// versicherung : 2014-03-20
+// versicherung : 2014-03-20 TLD-BOX Registrydienstleistungen GmbH
versicherung
-// vet : 2014-03-06
+// vet : 2014-03-06 United TLD Holdco Ltd.
vet
-// viajes : 2013-10-17 Black Madison, LLC
+// viajes : 2013-10-17 Binky Moon, LLC
viajes
-// video : 2014-10-16
+// video : 2014-10-16 United TLD Holdco Ltd.
video
// vig : 2015-05-14 VIENNA INSURANCE GROUP AG Wiener Versicherung Gruppe
@@ -10119,10 +10177,10 @@ vig
// viking : 2015-04-02 Viking River Cruises (Bermuda) Ltd.
viking
-// villas : 2013-12-05 New Sky, LLC
+// villas : 2013-12-05 Binky Moon, LLC
villas
-// vin : 2015-06-18 Holly Shadow, LLC
+// vin : 2015-06-18 Binky Moon, LLC
vin
// vip : 2015-01-22 Minds + Machines Group Limited
@@ -10134,7 +10192,7 @@ virgin
// visa : 2015-07-30 Visa Worldwide Pte. Limited
visa
-// vision : 2013-12-05 Koko Station, LLC
+// vision : 2013-12-05 Binky Moon, LLC
vision
// vista : 2014-09-18 Vistaprint Limited
@@ -10152,7 +10210,7 @@ vivo
// vlaanderen : 2014-02-06 DNS.be vzw
vlaanderen
-// vodka : 2013-12-19 Top Level Domain Holdings Limited
+// vodka : 2013-12-19 Minds + Machines Group Limited
vodka
// volkswagen : 2015-05-14 Volkswagen Group of America Inc.
@@ -10170,7 +10228,7 @@ voting
// voto : 2013-11-21 Monolith Registry LLC
voto
-// voyage : 2013-08-27 Ruby House, LLC
+// voyage : 2013-08-27 Binky Moon, LLC
voyage
// vuelos : 2015-03-05 Travel Reservations SRL
@@ -10185,25 +10243,25 @@ walmart
// walter : 2014-11-13 Sandvik AB
walter
-// wang : 2013-10-24 Zodiac Leo Limited
+// wang : 2013-10-24 Zodiac Wang Limited
wang
-// wanggou : 2014-12-18 Amazon EU S.à r.l.
+// wanggou : 2014-12-18 Amazon Registry Services, Inc.
wanggou
// warman : 2015-06-18 Weir Group IP Limited
warman
-// watch : 2013-11-14 Sand Shadow, LLC
+// watch : 2013-11-14 Binky Moon, LLC
watch
// watches : 2014-12-22 Richemont DNS Inc.
watches
-// weather : 2015-01-08 The Weather Channel, LLC
+// weather : 2015-01-08 International Business Machines Corporation
weather
-// weatherchannel : 2015-03-12 The Weather Channel, LLC
+// weatherchannel : 2015-03-12 International Business Machines Corporation
weatherchannel
// webcam : 2014-01-23 dot Webcam Limited
@@ -10218,7 +10276,7 @@ website
// wed : 2013-10-01 Atgron, Inc.
wed
-// wedding : 2014-04-24 Top Level Domain Holdings Limited
+// wedding : 2014-04-24 Minds + Machines Group Limited
wedding
// weibo : 2015-03-05 Sina Corporation
@@ -10245,7 +10303,7 @@ win
// windows : 2014-12-18 Microsoft Corporation
windows
-// wine : 2015-06-18 June Station, LLC
+// wine : 2015-06-18 Binky Moon, LLC
wine
// winners : 2015-07-16 The TJX Companies, Inc.
@@ -10260,22 +10318,22 @@ wolterskluwer
// woodside : 2015-07-09 Woodside Petroleum Limited
woodside
-// work : 2013-12-19 Top Level Domain Holdings Limited
+// work : 2013-12-19 Minds + Machines Group Limited
work
-// works : 2013-11-14 Little Dynamite, LLC
+// works : 2013-11-14 Binky Moon, LLC
works
-// world : 2014-06-12 Bitter Fields, LLC
+// world : 2014-06-12 Binky Moon, LLC
world
-// wow : 2015-10-08 Amazon EU S.à r.l.
+// wow : 2015-10-08 Amazon Registry Services, Inc.
wow
// wtc : 2013-12-19 World Trade Centers Association, Inc.
wtc
-// wtf : 2014-03-06 Hidden Way, LLC
+// wtf : 2014-03-06 Binky Moon, LLC
wtf
// xbox : 2014-12-18 Microsoft Corporation
@@ -10296,7 +10354,7 @@ xin
// xn--11b4c3d : 2015-01-15 VeriSign Sarl
कॉम
-// xn--1ck2e1b : 2015-02-26 Amazon EU S.à r.l.
+// xn--1ck2e1b : 2015-02-26 Amazon Registry Services, Inc.
セール
// xn--1qqw23a : 2014-01-09 Guangzhou YU Wei Information Technology Co., Ltd.
@@ -10320,7 +10378,7 @@ xin
// xn--42c2d9a : 2015-01-15 VeriSign Sarl
คอม
-// xn--45q11c : 2013-11-21 Zodiac Scorpio Limited
+// xn--45q11c : 2013-11-21 Zodiac Gemini Ltd
八卦
// xn--4gbrim : 2013-10-04 Suhub Electronic Establishment
@@ -10329,7 +10387,7 @@ xin
// xn--55qw42g : 2013-11-08 China Organizational Name Administration Center
公益
-// xn--55qx5d : 2013-11-14 Computer Network Information Center of Chinese Academy of Sciences (China Internet Network Information Center)
+// xn--55qx5d : 2013-11-14 China Internet Network Information Center (CNNIC)
公司
// xn--5su34j936bgsg : 2015-09-03 Shangri‐La International Hotel Management Limited
@@ -10338,7 +10396,7 @@ xin
// xn--5tzm5g : 2014-12-22 Global Website TLD Asia Limited
网站
-// xn--6frz82g : 2013-09-23 Afilias Limited
+// xn--6frz82g : 2013-09-23 Afilias plc
移动
// xn--6qq986b3xl : 2013-09-13 Tycoon Treasure Limited
@@ -10371,7 +10429,7 @@ xin
// xn--b4w605ferd : 2014-08-07 Temasek Holdings (Private) Limited
淡马锡
-// xn--bck1b9a5dre4c : 2015-02-26 Amazon EU S.à r.l.
+// xn--bck1b9a5dre4c : 2015-02-26 Amazon Registry Services, Inc.
ファッション
// xn--c1avg : 2013-11-14 Public Interest Registry
@@ -10380,7 +10438,7 @@ xin
// xn--c2br7g : 2015-01-15 VeriSign Sarl
नेट
-// xn--cck2b3b : 2015-02-26 Amazon EU S.à r.l.
+// xn--cck2b3b : 2015-02-26 Amazon Registry Services, Inc.
ストア
// xn--cg4bki : 2013-09-27 SAMSUNG SDS CO., LTD
@@ -10389,25 +10447,25 @@ xin
// xn--czr694b : 2014-01-16 Dot Trademark TLD Holding Company Limited
商标
-// xn--czrs0t : 2013-12-19 Wild Island, LLC
+// xn--czrs0t : 2013-12-19 Binky Moon, LLC
商店
-// xn--czru2d : 2013-11-21 Zodiac Capricorn Limited
+// xn--czru2d : 2013-11-21 Zodiac Aquarius Limited
商城
// xn--d1acj3b : 2013-11-20 The Foundation for Network Initiatives “The Smart Internet”
дети
-// xn--eckvdtc9d : 2014-12-18 Amazon EU S.à r.l.
+// xn--eckvdtc9d : 2014-12-18 Amazon Registry Services, Inc.
ポイント
-// xn--efvy88h : 2014-08-22 Xinhua News Agency Guangdong Branch 新华通讯社广东分社
+// xn--efvy88h : 2014-08-22 Guangzhou YU Wei Information Technology Co., Ltd.
新闻
// xn--estv75g : 2015-02-19 Industrial and Commercial Bank of China Limited
工行
-// xn--fct429k : 2015-04-09 Amazon EU S.à r.l.
+// xn--fct429k : 2015-04-09 Amazon Registry Services, Inc.
家電
// xn--fhbei : 2015-01-15 VeriSign Sarl
@@ -10419,7 +10477,7 @@ xin
// xn--fiq64b : 2013-10-14 CITIC Group Corporation
中信
-// xn--fjq720a : 2014-05-22 Will Bloom, LLC
+// xn--fjq720a : 2014-05-22 Binky Moon, LLC
娱乐
// xn--flw351e : 2014-07-31 Charleston Road Registry Inc.
@@ -10431,13 +10489,13 @@ xin
// xn--g2xx48c : 2015-01-30 Minds + Machines Group Limited
购物
-// xn--gckr3f0f : 2015-02-26 Amazon EU S.à r.l.
+// xn--gckr3f0f : 2015-02-26 Amazon Registry Services, Inc.
クラウド
-// xn--gk3at1e : 2015-10-08 Amazon EU S.à r.l.
+// xn--gk3at1e : 2015-10-08 Amazon Registry Services, Inc.
通販
-// xn--hxt814e : 2014-05-15 Zodiac Libra Limited
+// xn--hxt814e : 2014-05-15 Zodiac Taurus Limited
网店
// xn--i1b6b1a6a2e : 2013-11-14 Public Interest Registry
@@ -10446,7 +10504,7 @@ xin
// xn--imr513n : 2014-12-11 Dot Trademark TLD Holding Company Limited
餐厅
-// xn--io0a7i : 2013-11-14 Computer Network Information Center of Chinese Academy of Sciences (China Internet Network Information Center)
+// xn--io0a7i : 2013-11-14 China Internet Network Information Center (CNNIC)
网络
// xn--j1aef : 2015-01-15 VeriSign Sarl
@@ -10455,7 +10513,7 @@ xin
// xn--jlq61u9w7b : 2015-01-08 Nokia Corporation
诺基亚
-// xn--jvr189m : 2015-02-26 Amazon EU S.à r.l.
+// xn--jvr189m : 2015-02-26 Amazon Registry Services, Inc.
食品
// xn--kcrx77d1x4a : 2014-11-07 Koninklijke Philips N.V.
@@ -10515,6 +10573,9 @@ xin
// xn--nyqy26a : 2014-11-07 Stable Tone Limited
健康
+// xn--otu796d : 2017-08-06 Dot Trademark TLD Holding Company Limited
+招聘
+
// xn--p1acf : 2013-12-12 Rusnames Limited
рус
@@ -10533,10 +10594,10 @@ xin
// xn--rhqv96g : 2013-09-11 Stable Tone Limited
世界
-// xn--rovu88b : 2015-02-26 Amazon EU S.à r.l.
+// xn--rovu88b : 2015-02-26 Amazon Registry Services, Inc.
書籍
-// xn--ses554g : 2014-01-16
+// xn--ses554g : 2014-01-16 KNET Co., Ltd.
网址
// xn--t60b56a : 2015-01-15 VeriSign Sarl
@@ -10548,7 +10609,7 @@ xin
// xn--tiq49xqyj : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication)
天主教
-// xn--unup4y : 2013-07-14 Spring Fields, LLC
+// xn--unup4y : 2013-07-14 Binky Moon, LLC
游戏
// xn--vermgensberater-ctb : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
@@ -10557,7 +10618,7 @@ vermögensberater
// xn--vermgensberatung-pwb : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
vermögensberatung
-// xn--vhquv : 2013-08-27 Dash McCook, LLC
+// xn--vhquv : 2013-08-27 Binky Moon, LLC
企业
// xn--vuq861b : 2014-10-16 Beijing Tele-info Network Technology Co., Ltd.
@@ -10587,7 +10648,7 @@ yachts
// yahoo : 2015-04-02 Yahoo! Domain Services Inc.
yahoo
-// yamaxun : 2014-12-18 Amazon EU S.à r.l.
+// yamaxun : 2014-12-18 Amazon Registry Services, Inc.
yamaxun
// yandex : 2014-04-10 YANDEX, LLC
@@ -10596,13 +10657,13 @@ yandex
// yodobashi : 2014-11-20 YODOBASHI CAMERA CO.,LTD.
yodobashi
-// yoga : 2014-05-29 Top Level Domain Holdings Limited
+// yoga : 2014-05-29 Minds + Machines Group Limited
yoga
// yokohama : 2013-12-12 GMO Registry, Inc.
yokohama
-// you : 2015-04-09 Amazon EU S.à r.l.
+// you : 2015-04-09 Amazon Registry Services, Inc.
you
// youtube : 2014-05-01 Charleston Road Registry Inc.
@@ -10611,13 +10672,13 @@ youtube
// yun : 2015-01-08 QIHOO 360 TECHNOLOGY CO. LTD.
yun
-// zappos : 2015-06-25 Amazon EU S.à r.l.
+// zappos : 2015-06-25 Amazon Registry Services, Inc.
zappos
// zara : 2014-11-07 Industria de Diseño Textil, S.A. (INDITEX, S.A.)
zara
-// zero : 2014-12-18 Amazon EU S.à r.l.
+// zero : 2014-12-18 Amazon Registry Services, Inc.
zero
// zip : 2014-05-08 Charleston Road Registry Inc.
@@ -10626,7 +10687,7 @@ zip
// zippo : 2015-07-02 Zadco Company
zippo
-// zone : 2013-11-14 Outer Falls, LLC
+// zone : 2013-11-14 Binky Moon, LLC
zone
// zuerich : 2014-11-07 Kanton Zürich (Canton of Zurich)
@@ -10643,12 +10704,6 @@ cc.ua
inf.ua
ltd.ua
-// AgileBits Inc : https://agilebits.com
-// Submitted by Roustem Karimov <roustem@agilebits.com>
-1password.ca
-1password.com
-1password.eu
-
// Agnat sp. z o.o. : https://domena.pl
// Submitted by Przemyslaw Plewa <it-admin@domena.pl>
beep.pl
@@ -10679,6 +10734,7 @@ cn-north-1.eb.amazonaws.com.cn
elasticbeanstalk.com
ap-northeast-1.elasticbeanstalk.com
ap-northeast-2.elasticbeanstalk.com
+ap-northeast-3.elasticbeanstalk.com
ap-south-1.elasticbeanstalk.com
ap-southeast-1.elasticbeanstalk.com
ap-southeast-2.elasticbeanstalk.com
@@ -10801,6 +10857,10 @@ betainabox.com
// Submitted by Nathan O'Sullivan <nathan@mammoth.com.au>
bnr.la
+// Blackbaud, Inc. : https://www.blackbaud.com
+// Submitted by Paul Crowder <paul.crowder@blackbaud.com>
+blackbaudcdn.net
+
// Boomla : https://boomla.com
// Submitted by Tibor Halter <thalter@boomla.com>
boomla.net
@@ -10848,7 +10908,6 @@ no.com
qc.com
ru.com
sa.com
-se.com
se.net
uk.com
uk.net
@@ -10892,9 +10951,14 @@ xenapponazure.com
// Submitted by Leon Rowland <leon@clearvox.nl>
virtueeldomein.nl
+// Clever Cloud : https://www.clever-cloud.com/
+// Submitted by Quentin Adam <noc@clever-cloud.com>
+cleverapps.io
+
// Cloud66 : https://www.cloud66.com/
// Submitted by Khash Sajadi <khash@cloud66.com>
c66.me
+cloud66.ws
// CloudAccess.net : https://www.cloudaccess.net/
// Submitted by Pawel Panek <noc@cloudaccess.net>
@@ -10912,6 +10976,10 @@ cloudcontrolapp.com
// co.ca : http://registry.co.ca/
co.ca
+// Co & Co : https://co-co.nl/
+// Submitted by Govert Versluis <govert@co-co.nl>
+*.otap.co
+
// i-registry s.r.o. : http://www.i-registry.cz/
// Submitted by Martin Semrad <semrad@i-registry.cz>
co.cz
@@ -10938,6 +11006,10 @@ cloudns.pro
cloudns.pw
cloudns.us
+// Cloudeity Inc : https://cloudeity.com
+// Submitted by Stefan Dimitrov <contact@cloudeity.com>
+cloudeity.net
+
// CoDNS B.V.
co.nl
co.no
@@ -10981,6 +11053,15 @@ cyon.site
daplie.me
localhost.daplie.me
+// Datto, Inc. : https://www.datto.com/
+// Submitted by Philipp Heckel <ph@datto.com>
+dattolocal.com
+dattorelay.com
+dattoweb.com
+mydatto.com
+dattolocal.net
+mydatto.net
+
// Dansk.net : http://www.dansk.net/
// Submitted by Anani Voule <digital@digital.co.dk>
biz.dk
@@ -11325,6 +11406,10 @@ ddnss.org
definima.net
definima.io
+// dnstrace.pro : https://dnstrace.pro/
+// Submitted by Chris Partridge <chris@partridge.tech>
+bci.dnstrace.pro
+
// Dynu.com : https://www.dynu.com/
// Submitted by Sue Ye <sue@dynu.com>
ddnsfree.com
@@ -11536,6 +11621,11 @@ a.ssl.fastly.net
b.ssl.fastly.net
global.ssl.fastly.net
+// FASTVPS EESTI OU : https://fastvps.ru/
+// Submitted by Likhachev Vasiliy <lihachev@fastvps.ru>
+fastpanel.direct
+fastvps-server.com
+
// Featherhead : https://featherhead.xyz/
// Submitted by Simon Menke <simon@featherhead.xyz>
fhapp.xyz
@@ -11573,6 +11663,8 @@ freeboxos.fr
// Futureweb OG : http://www.futureweb.at
// Submitted by Andreas Schnederle-Wagner <schnederle@futureweb.at>
*.futurecms.at
+*.ex.futurecms.at
+*.in.futurecms.at
futurehosting.at
futuremailing.at
*.ex.ortsinfo.at
@@ -11709,6 +11801,14 @@ hepforge.org
herokuapp.com
herokussl.com
+// Hibernating Rhinos
+// Submitted by Oren Eini <oren@ravendb.net>
+myravendb.com
+ravendb.community
+ravendb.me
+development.run
+ravendb.run
+
// Ici la Lune : http://www.icilalune.com/
// Submitted by Simon Morvan <simon@icilalune.com>
moonscale.net
@@ -11763,6 +11863,19 @@ pixolino.com
// Submitted by Matthew Hardeman <mhardeman@ipifony.com>
ipifony.net
+// IServ GmbH : https://iserv.eu
+// Submitted by Kim-Alexander Brodowski <kim.brodowski@iserv.eu>
+mein-iserv.de
+test-iserv.de
+
+// Jino : https://www.jino.ru
+// Submitted by Sergey Ulyashin <ulyashin@jino.ru>
+myjino.ru
+*.hosting.myjino.ru
+*.landing.myjino.ru
+*.spectrum.myjino.ru
+*.vps.myjino.ru
+
// Joyent : https://www.joyent.com/
// Submitted by Brian Bennett <brian.bennett@joyent.com>
*.triton.zone
@@ -11790,34 +11903,84 @@ git-repos.de
lcube-server.de
svn-repos.de
+// Lightmaker Property Manager, Inc. : https://app.lmpm.com/
+// Submitted by Greg Holland <greg.holland@lmpm.com>
+app.lmpm.com
+
+// Linki Tools UG : https://linki.tools
+// Submitted by Paulo Matos <pmatos@linki.tools>
+linkitools.space
+
+// linkyard ldt: https://www.linkyard.ch/
+// Submitted by Mario Siegenthaler <mario.siegenthaler@linkyard.ch>
+linkyard.cloud
+linkyard-cloud.ch
+
// LiquidNet Ltd : http://www.liquidnetlimited.com/
// Submitted by Victor Velchev <admin@liquidnetlimited.com>
we.bs
+// Lug.org.uk : https://lug.org.uk
+// Submitted by Jon Spriggs <admin@lug.org.uk>
+uklugs.org
+glug.org.uk
+lug.org.uk
+lugs.org.uk
+
// Lukanet Ltd : https://lukanet.com
// Submitted by Anton Avramov <register@lukanet.com>
barsy.bg
+barsy.co.uk
+barsyonline.co.uk
+barsycenter.com
barsyonline.com
+barsy.club
barsy.de
barsy.eu
barsy.in
+barsy.info
+barsy.io
+barsy.me
+barsy.menu
+barsy.mobi
barsy.net
barsy.online
+barsy.org
+barsy.pro
+barsy.pub
+barsy.shop
+barsy.site
barsy.support
+barsy.uk
// Magento Commerce
// Submitted by Damien Tournoud <dtournoud@magento.cloud>
*.magentosite.cloud
+// May First - People Link : https://mayfirst.org/
+// Submitted by Jamie McClelland <info@mayfirst.org>
+mayfirst.info
+mayfirst.org
+
// Mail.Ru Group : https://hb.cldmail.ru
// Submitted by Ilya Zaretskiy <zaretskiy@corp.mail.ru>
hb.cldmail.ru
+// Memset hosting : https://www.memset.com
+// Submitted by Tom Whitwell <domains@memset.com>
+miniserver.com
+memset.net
+
// MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/
// Submitted by Zdeněk Šustr <zdenek.sustr@cesnet.cz>
cloud.metacentrum.cz
custom.metacentrum.cz
+// MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/
+// Submitted by Radim Janča <janca@cesnet.cz>
+flt.cloud.muni.cz
+usr.cloud.muni.cz
+
// Meteor Development Group : https://www.meteor.com/hosting
// Submitted by Pierre Carrier <pierre@meteor.com>
meteorapp.com
@@ -11826,12 +11989,17 @@ eu.meteorapp.com
// Michau Enterprises Limited : http://www.co.pl/
co.pl
-// Microsoft : http://microsoft.com
-// Submitted by Barry Dorrans <bdorrans@microsoft.com>
+// Microsoft Corporation : http://microsoft.com
+// Submitted by Justin Luk <juluk@microsoft.com>
+azurecontainer.io
azurewebsites.net
azure-mobile.net
cloudapp.net
+// Mozilla Corporation : https://mozilla.com
+// Submitted by Ben Francis <bfrancis@mozilla.com>
+mozilla-iot.org
+
// Mozilla Foundation : https://mozilla.org/
// Submitted by glob <glob@mozilla.com>
bmoattachments.org
@@ -11863,6 +12031,34 @@ nh-serv.co.uk
// Submitted by Jeff Wheelhouse <support@nearlyfreespeech.net>
nfshost.com
+// Now-DNS : https://now-dns.com
+// Submitted by Steve Russell <steve@now-dns.com>
+dnsking.ch
+mypi.co
+n4t.co
+001www.com
+ddnslive.com
+myiphost.com
+forumz.info
+16-b.it
+32-b.it
+64-b.it
+soundcast.me
+tcp4.me
+dnsup.net
+hicam.net
+now-dns.net
+ownip.net
+vpndns.net
+dynserv.org
+now-dns.org
+x443.pw
+now-dns.top
+ntdll.top
+freeddns.us
+crafting.xyz
+zapto.xyz
+
// nsupdate.info : https://www.nsupdate.info/
// Submitted by Thomas Waldmann <info@nsupdate.info>
nsupdate.info
@@ -11965,6 +12161,10 @@ stage.nodeart.io
nodum.co
nodum.io
+// Nucleos Inc. : https://nucleos.com
+// Submitted by Piotr Zduniak <piotr@nucleos.com>
+pcloud.host
+
// NYC.mn : http://www.information.nyc.mn
// Submitted by Matthew Brown <mattbrown@nyc.mn>
nyc.mn
@@ -11972,25 +12172,32 @@ nyc.mn
// NymNom : https://nymnom.com/
// Submitted by Dave McCormack <dave.mccormack@nymnom.com>
nom.ae
+nom.af
nom.ai
nom.al
nym.by
nym.bz
nom.cl
nom.gd
+nom.ge
nom.gl
nym.gr
nom.gt
+nym.gy
nom.hn
+nym.ie
nom.im
+nom.ke
nym.kz
nym.la
+nym.lc
nom.li
nym.li
nym.lt
nym.lu
nym.me
nom.mk
+nym.mn
nym.mx
nom.nu
nym.nz
@@ -11998,11 +12205,14 @@ nym.pe
nym.pt
nom.pw
nom.qa
+nym.ro
nom.rs
nom.si
nym.sk
+nom.st
nym.su
nym.sx
+nom.tj
nym.tw
nom.ug
nom.uy
@@ -12029,9 +12239,14 @@ operaunite.com
// Submitted by Duarte Santos <domain-admin@outsystemscloud.com>
outsystemscloud.com
-// OwnProvider : http://www.ownprovider.com
+// OwnProvider GmbH: http://www.ownprovider.com
// Submitted by Jan Moennich <jan.moennich@ownprovider.com>
ownprovider.com
+own.pm
+
+// OX : http://www.ox.rs
+// Submitted by Adam Grand <webmaster@mail.ox.rs>
+ox.rs
// oy.lc
// Submitted by Charly Coste <changaco@changaco.oy.lc>
@@ -12085,10 +12300,14 @@ priv.at
protonet.io
// Publication Presse Communication SARL : https://ppcom.fr
-// Submitted by Yaacov Akiba Slama <admin@chirurgiens-dentistes-en-france.fr>
+// Submitted by Yaacov Akiba Slama <admin@chirurfgiens-dentistes-en-france.fr>
chirurgiens-dentistes-en-france.fr
byen.site
+// Russian Academy of Sciences
+// Submitted by Tech Support <support@rasnet.ru>
+ras.ru
+
// QA2
// Submitted by Daniel Dent (https://www.danieldent.com/)
qa2.com
@@ -12141,6 +12360,10 @@ sandcats.io
logoip.de
logoip.com
+// schokokeks.org GbR : https://schokokeks.org/
+// Submitted by Hanno Böck <hanno@schokokeks.org>
+schokokeks.net
+
// Scry Security : http://www.scrysec.com
// Submitted by Shante Adam <shante@skyhat.io>
scrysec.com
@@ -12206,6 +12429,10 @@ apps.lair.io
// Submitted by Reza Akhavan <spacekit.io@gmail.com>
spacekit.io
+// SpeedPartner GmbH: https://www.speedpartner.de/
+// Submitted by Stefan Neufeind <info@speedpartner.de>
+customer.speedpartner.de
+
// Stackspace : https://www.stackspace.io/
// Submitted by Lina He <info@stackspace.io>
stackspace.space
@@ -12214,6 +12441,10 @@ stackspace.space
// Submitted by Philip Hutchins <hostmaster@storj.io>
storj.farm
+// Studenten Net Twente : http://www.snt.utwente.nl/
+// Submitted by Silke Hofstra <syscom@snt.utwente.nl>
+utwente.io
+
// Sub 6 Limited: http://www.sub6.com
// Submitted by Dan Miller <dm@sub6.com>
temp-dns.com
@@ -12246,6 +12477,10 @@ gdynia.pl
med.pl
sopot.pl
+// The Gwiddle Foundation : https://gwiddlefoundation.org.uk
+// Submitted by Joshua Bayfield <joshua.bayfield@gwiddlefoundation.org.uk>
+gwiddle.co.uk
+
// Thingdust AG : https://thingdust.com/
// Submitted by Adrian Imboden <adi@thingdust.com>
cust.dev.thingdust.io
@@ -12309,6 +12544,7 @@ synology-ds.de
// Uberspace : https://uberspace.de
// Submitted by Moritz Werner <mwerner@jonaspasche.com>
uber.space
+*.uberspace.de
// UDR Limited : http://www.udr.hk.com
// Submitted by registry <hostmaster@udr.hk.com>
@@ -12317,10 +12553,19 @@ hk.org
ltd.hk
inc.hk
+// United Gameserver GmbH : https://united-gameserver.de
+// Submitted by Stefan Schwarz <sysadm@united-gameserver.de>
+virtualuser.de
+virtual-user.de
+
// .US
// Submitted by Ed Moore <Ed.Moore@lib.de.us>
lib.de.us
+// VeryPositive SIA : http://very.lv
+// Submitted by Danko Aleksejevs <danko@very.lv>
+2038.io
+
// Viprinet Europe GmbH : http://www.viprinet.com
// Submitted by Simon Kissel <hostmaster@viprinet.com>
router.management
@@ -12343,12 +12588,26 @@ remotewd.com
// Submitted by Yuvi Panda <yuvipanda@wikimedia.org>
wmflabs.org
+// XenonCloud GbR: https://xenoncloud.net
+// Submitted by Julian Uphoff <publicsuffixlist@xenoncloud.net>
+half.host
+
+// XnBay Technology : http://www.xnbay.com/
+// Submitted by XnBay Developer <developer.xncloud@gmail.com>
+xnbay.com
+u2.xnbay.com
+u2-local.xnbay.com
+
// XS4ALL Internet bv : https://www.xs4all.nl/
// Submitted by Daniel Mostertman <unixbeheer+publicsuffix@xs4all.net>
cistron.nl
demon.nl
xs4all.space
+// YesCourse Pty Ltd : https://yescourse.com
+// Submitted by Atul Bhouraskar <atul@yescourse.com>
+official.academy
+
// Yola : https://www.yola.com/
// Submitted by Stefano Rivera <stefano@yola.com>
yolasite.com
@@ -12363,6 +12622,11 @@ ybo.review
ybo.science
ybo.trade
+// Yunohost : https://yunohost.org
+// Submitted by Valentin Grimaud <security@yunohost.org>
+nohost.me
+noho.st
+
// ZaNiC : http://www.za.net/
// Submitted by registry <hostmaster@nic.za.net>
za.net
@@ -12372,4 +12636,8 @@ za.org
// Submitted by Olli Vanhoja <olli@zeit.co>
now.sh
+// Zone.id : https://zone.id/
+// Submitted by Su Hendro <admin@zone.id>
+zone.id
+
// ===END PRIVATE DOMAINS===
diff --git a/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf b/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf
index c8a96e03502..f1a5a5bf613 100644
--- a/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf
+++ b/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf
@@ -12,22 +12,23 @@ struct DomainRule {
};
%%
0.bg, 0
+001www.com, 4
0emm.com, 6
1.bg, 0
12hp.at, 4
12hp.ch, 4
12hp.de, 4
1337.pictures, 4
+16-b.it, 4
1kapp.com, 4
-1password.ca, 4
-1password.com, 4
-1password.eu, 4
2.bg, 0
2000.hu, 0
+2038.io, 4
2ix.at, 4
2ix.ch, 4
2ix.de, 4
3.bg, 0
+32-b.it, 4
3utilities.com, 4
4.bg, 0
4lima.at, 4
@@ -36,6 +37,7 @@ struct DomainRule {
4u.com, 4
5.bg, 0
6.bg, 0
+64-b.it, 4
7.bg, 0
8.bg, 0
9.bg, 0
@@ -324,6 +326,7 @@ aostavalley.it, 0
aoste.it, 0
ap-northeast-1.elasticbeanstalk.com, 4
ap-northeast-2.elasticbeanstalk.com, 4
+ap-northeast-3.elasticbeanstalk.com, 4
ap-south-1.elasticbeanstalk.com, 4
ap-southeast-1.elasticbeanstalk.com, 4
ap-southeast-2.elasticbeanstalk.com, 4
@@ -334,6 +337,7 @@ ap.leg.br, 4
aparecida.br, 0
apartments, 0
app, 0
+app.lmpm.com, 4
app.os.fedoraproject.org, 4
app.os.stg.fedoraproject.org, 4
appchizi.com, 4
@@ -516,6 +520,7 @@ azerbaijan.su, 4
azumino.nagano.jp, 0
azure, 0
azure-mobile.net, 4
+azurecontainer.io, 4
azurewebsites.net, 4
b.bg, 0
b.br, 0
@@ -543,6 +548,8 @@ bale.museum, 0
balestrand.no, 0
ballangen.no, 0
ballooning.aero, 0
+balsan-sudtirol.it, 0
+balsan-suedtirol.it, 0
balsan.it, 0
balsfjord.no, 0
baltimore.museum, 0
@@ -569,13 +576,29 @@ barreau.bj, 0
barrel-of-knowledge.info, 4
barrell-of-knowledge.info, 4
barsy.bg, 4
+barsy.club, 4
+barsy.co.uk, 4
barsy.de, 4
barsy.eu, 4
barsy.in, 4
+barsy.info, 4
+barsy.io, 4
+barsy.me, 4
+barsy.menu, 4
+barsy.mobi, 4
barsy.net, 4
barsy.online, 4
+barsy.org, 4
+barsy.pro, 4
+barsy.pub, 4
+barsy.shop, 4
+barsy.site, 4
barsy.support, 4
+barsy.uk, 4
+barsycenter.com, 4
+barsyonline.co.uk, 4
barsyonline.com, 4
+barueri.br, 0
barum.no, 0
bas.it, 0
baseball, 0
@@ -598,6 +621,7 @@ bbt, 0
bbva, 0
bc.ca, 0
bcg, 0
+bci.dnstrace.pro, 4
bcn, 0
bd, 2
bd.se, 0
@@ -703,6 +727,7 @@ bjerkreim.no, 0
bjugn.no, 0
bl.it, 0
black, 0
+blackbaudcdn.net, 4
blackfriday, 0
blanco, 0
blockbuster, 0
@@ -817,6 +842,7 @@ boleslawiec.pl, 0
bolivia.bo, 0
bologna.it, 0
bolt.hu, 0
+bolzano-altoadige.it, 0
bolzano.it, 0
bom, 0
bomlo.no, 0
@@ -826,7 +852,6 @@ boo, 0
book, 0
booking, 0
boomla.net, 4
-boots, 0
bosch, 0
bostik, 0
boston, 0
@@ -841,6 +866,8 @@ bounty-full.com, 4
boutique, 0
box, 0
boxfuse.io, 4
+bozen-sudtirol.it, 0
+bozen-suedtirol.it, 0
bozen.it, 0
bplaced.com, 4
bplaced.de, 4
@@ -890,6 +917,9 @@ build, 0
builders, 0
building.museum, 0
bukhara.su, 4
+bulsan-sudtirol.it, 0
+bulsan-suedtirol.it, 0
+bulsan.it, 0
bungoono.oita.jp, 0
bungotakada.oita.jp, 0
bunkyo.tokyo.jp, 0
@@ -1086,6 +1116,7 @@ championship.aero, 0
chanel, 0
channel, 0
channelsdvr.net, 4
+charity, 0
charter.aero, 0
chase, 0
chat, 0
@@ -1186,6 +1217,7 @@ cl.it, 0
claims, 0
clan.rip, 4
cleaning, 0
+cleverapps.io, 4
click, 0
clinic, 0
clinique, 0
@@ -1196,11 +1228,13 @@ cloud, 0
cloud.fedoraproject.org, 4
cloud.goog, 4
cloud.metacentrum.cz, 4
+cloud66.ws, 4
cloudaccess.host, 4
cloudaccess.net, 4
cloudapp.net, 4
cloudcontrolapp.com, 4
cloudcontrolled.com, 4
+cloudeity.net, 4
cloudfront.net, 4
cloudfunctions.net, 4
cloudns.asia, 4
@@ -1508,6 +1542,7 @@ cq.cn, 0
cr, 0
cr.it, 0
cr.ua, 0
+crafting.xyz, 4
crafts.museum, 0
cranbrook.museum, 0
creation.museum, 0
@@ -1545,6 +1580,7 @@ cust.prod.thingdust.io, 4
cust.testing.thingdust.io, 4
custom.metacentrum.cz, 4
customer.enonic.io, 4
+customer.speedpartner.de, 4
cv, 0
cv.ua, 0
cw, 0
@@ -1587,6 +1623,10 @@ date.fukushima.jp, 0
date.hokkaido.jp, 0
dating, 0
datsun, 0
+dattolocal.com, 4
+dattolocal.net, 4
+dattorelay.com, 4
+dattoweb.com, 4
davvenjarga.no, 0
davvesiida.no, 0
day, 0
@@ -1599,6 +1639,7 @@ ddns.net, 4
ddnsfree.com, 4
ddnsgeek.com, 4
ddnsking.com, 4
+ddnslive.com, 4
ddnss.de, 4
ddnss.org, 4
ddr.museum, 0
@@ -1646,6 +1687,7 @@ detroit.museum, 0
dev, 0
dev-myqnapcloud.com, 4
dev.static.land, 4
+development.run, 4
devices.resinstaging.io, 4
df.gov.br, 0
df.leg.br, 4
@@ -1688,6 +1730,8 @@ dnsdojo.org, 4
dnsfor.me, 4
dnshome.de, 4
dnsiskinky.com, 4
+dnsking.ch, 4
+dnsup.net, 4
dnsupdater.de, 4
do, 0
docs, 0
@@ -1781,6 +1825,7 @@ dyndns.tv, 4
dyndns.ws, 4
dyndns1.de, 4
dynns.com, 4
+dynserv.org, 4
dynu.net, 4
dynv6.net, 4
dynvpn.de, 4
@@ -2058,6 +2103,7 @@ evenes.no, 0
events, 0
everbank, 0
evje-og-hornnes.no, 0
+ex.futurecms.at, 6
ex.ortsinfo.at, 6
exchange, 0
exchange.aero, 0
@@ -2096,6 +2142,8 @@ farsund.no, 0
fashion, 0
fast, 0
fastlylb.net, 4
+fastpanel.direct, 4
+fastvps-server.com, 4
fauske.no, 0
fbx-os.fr, 4
fbxos.fr, 4
@@ -2190,6 +2238,7 @@ floripa.br, 0
florist, 0
floro.no, 0
flowers, 0
+flt.cloud.muni.cz, 4
fly, 0
flynnhosting.net, 4
flynnhub.com, 4
@@ -2226,6 +2275,7 @@ fortmissoula.museum, 0
fortworth.museum, 0
forum, 0
forum.hu, 0
+forumz.info, 4
fosnes.no, 0
fot.br, 0
foundation, 0
@@ -2246,6 +2296,7 @@ freebox-os.fr, 4
freeboxos.com, 4
freeboxos.fr, 4
freeddns.org, 4
+freeddns.us, 4
freemasonry.museum, 0
freesite.host, 4
freetls.fastly.net, 4
@@ -2508,6 +2559,7 @@ global.ssl.fastly.net, 4
globo, 0
glogow.pl, 0
gloppen.no, 0
+glug.org.uk, 4
gm, 0
gmail, 0
gmbh, 0
@@ -2796,6 +2848,7 @@ gv.ao, 0
gv.at, 0
gw, 0
gwangju.kr, 0
+gwiddle.co.uk, 4
gx.cn, 0
gy, 0
gyeongbuk.kr, 0
@@ -2829,6 +2882,7 @@ hakuba.nagano.jp, 0
hakui.ishikawa.jp, 0
hakusan.ishikawa.jp, 0
halden.no, 0
+half.host, 4
halloffame.museum, 0
halsa.no, 0
ham-radio-op.net, 4
@@ -2916,6 +2970,7 @@ heroy.nordland.no, 0
hgtv, 0
hi.cn, 0
hi.us, 0
+hicam.net, 4
hichiso.gifu.jp, 0
hida.gifu.jp, 0
hidaka.hokkaido.jp, 0
@@ -3069,6 +3124,7 @@ hospital, 0
host, 0
hosting, 0
hosting-cluster.nl, 4
+hosting.myjino.ru, 6
hot, 0
hotel.hu, 0
hotel.lk, 0
@@ -3192,6 +3248,7 @@ in, 0
in-addr.arpa, 0
in-the-band.net, 4
in.eu.org, 4
+in.futurecms.at, 6
in.na, 0
in.net, 4
in.ni, 0
@@ -3211,6 +3268,7 @@ inashiki.ibaraki.jp, 0
inatsuki.fukuoka.jp, 0
inawashiro.fukushima.jp, 0
inazawa.aichi.jp, 0
+inc, 0
inc.hk, 4
incheon.kr, 0
ind.br, 0
@@ -4040,6 +4098,7 @@ lancome, 0
land, 0
land-4-sale.us, 4
landes.museum, 0
+landing.myjino.ru, 6
landrover, 0
langevag.no, 0
lans.museum, 0
@@ -4188,6 +4247,9 @@ lindas.no, 0
linde, 0
lindesnes.no, 0
link, 0
+linkitools.space, 4
+linkyard-cloud.ch, 4
+linkyard.cloud, 4
linz.museum, 0
lipsy, 0
live, 0
@@ -4197,6 +4259,7 @@ livinghistory.museum, 0
livorno.it, 0
lixil, 0
lk, 0
+llc, 0
ln.cn, 0
lo.it, 0
loabat.no, 0
@@ -4257,7 +4320,9 @@ lubin.pl, 0
lucania.it, 0
lucca.it, 0
lucerne.museum, 0
+lug.org.uk, 4
lugansk.ua, 0
+lugs.org.uk, 4
lukow.pl, 0
lund.no, 0
lundbeck, 0
@@ -4375,6 +4440,8 @@ matsuyama.ehime.jp, 0
matsuzaki.shizuoka.jp, 0
matta-varjjat.no, 0
mattel, 0
+mayfirst.info, 4
+mayfirst.org, 4
mazowsze.pl, 0
mazury.pl, 0
mb.ca, 0
@@ -4421,6 +4488,7 @@ medizinhistorisches.museum, 0
meeres.museum, 0
meet, 0
meguro.tokyo.jp, 0
+mein-iserv.de, 4
mein-vigor.de, 4
meiwa.gunma.jp, 0
meiwa.mie.jp, 0
@@ -4432,6 +4500,7 @@ meloy.no, 0
meme, 0
memorial, 0
memorial.museum, 0
+memset.net, 4
men, 0
menu, 0
meo, 0
@@ -4573,6 +4642,7 @@ mine.nu, 4
miners.museum, 0
mini, 0
mining.museum, 0
+miniserver.com, 4
minnesota.museum, 0
mino.gifu.jp, 0
minobu.yamanashi.jp, 0
@@ -4721,6 +4791,7 @@ mov, 0
movie, 0
movimiento.bo, 0
movistar, 0
+mozilla-iot.org, 4
mp, 0
mp.br, 0
mq, 0
@@ -4743,7 +4814,6 @@ mt.it, 0
mt.leg.br, 4
mt.us, 0
mtn, 0
-mtpc, 0
mtr, 0
mu, 0
muenchen.museum, 0
@@ -4799,6 +4869,8 @@ my.id, 0
myactivedirectory.com, 4
myasustor.com, 4
mycd.eu, 4
+mydatto.com, 4
+mydatto.net, 4
myddns.rocks, 4
mydissent.net, 4
mydrobo.com, 4
@@ -4809,6 +4881,8 @@ myfritz.net, 4
myftp.biz, 4
myftp.org, 4
myhome-server.de, 4
+myiphost.com, 4
+myjino.ru, 4
mykolaiv.ua, 0
mymailer.com.tw, 4
mymediapc.net, 4
@@ -4816,8 +4890,10 @@ myoko.niigata.jp, 0
mypep.link, 4
mypets.ws, 4
myphotos.cc, 4
+mypi.co, 4
mypsx.net, 4
myqnapcloud.com, 4
+myravendb.com, 4
mysecuritycamera.com, 4
mysecuritycamera.net, 4
mysecuritycamera.org, 4
@@ -4829,6 +4905,7 @@ mywire.org, 4
mz, 0
n.bg, 0
n.se, 0
+n4t.co, 4
na, 0
na.it, 0
naamesjevuemie.no, 0
@@ -5237,11 +5314,14 @@ nodum.io, 4
nogata.fukuoka.jp, 0
nogi.tochigi.jp, 0
noheji.aomori.jp, 0
+noho.st, 4
+nohost.me, 4
noip.me, 4
noip.us, 4
nokia, 0
nom.ad, 0
nom.ae, 4
+nom.af, 4
nom.ag, 0
nom.ai, 4
nom.al, 4
@@ -5251,10 +5331,12 @@ nom.co, 0
nom.es, 0
nom.fr, 0
nom.gd, 4
+nom.ge, 4
nom.gl, 4
nom.gt, 4
nom.hn, 4
nom.im, 4
+nom.ke, 4
nom.km, 0
nom.li, 4
nom.mg, 0
@@ -5271,6 +5353,8 @@ nom.re, 0
nom.ro, 0
nom.rs, 4
nom.si, 4
+nom.st, 4
+nom.tj, 4
nom.tm, 0
nom.ug, 4
nom.uy, 4
@@ -5309,6 +5393,9 @@ nov.ru, 4
nov.su, 4
novara.it, 0
now, 0
+now-dns.net, 4
+now-dns.org, 4
+now-dns.top, 4
now.sh, 4
nowaruda.pl, 0
nowruz, 0
@@ -5329,6 +5416,7 @@ nt.ca, 0
nt.edu.au, 0
nt.no, 0
nt.ro, 0
+ntdll.top, 4
ntr.br, 0
ntt, 0
nu, 0
@@ -5349,16 +5437,21 @@ nyc.museum, 0
nym.by, 4
nym.bz, 4
nym.gr, 4
+nym.gy, 4
+nym.ie, 4
nym.kz, 4
nym.la, 4
+nym.lc, 4
nym.li, 4
nym.lt, 4
nym.lu, 4
nym.me, 4
+nym.mn, 4
nym.mx, 4
nym.nz, 4
nym.pe, 4
nym.pt, 4
+nym.ro, 4
nym.sk, 4
nym.su, 4
nym.sx, 4
@@ -5399,6 +5492,7 @@ off, 0
off.ai, 0
office, 0
office-on-the.net, 4
+official.academy, 4
ofunato.iwate.jp, 0
og.ao, 0
og.it, 0
@@ -5722,6 +5816,7 @@ otaki.chiba.jp, 0
otaki.nagano.jp, 0
otaki.saitama.jp, 0
otama.fukushima.jp, 0
+otap.co, 6
otari.nagano.jp, 0
otaru.hokkaido.jp, 0
other.nf, 0
@@ -5746,7 +5841,10 @@ ovh, 0
ovre-eiker.no, 0
owani.aomori.jp, 0
owariasahi.aichi.jp, 0
+own.pm, 4
+ownip.net, 4
ownprovider.com, 4
+ox.rs, 4
oxford.museum, 0
oy.lc, 4
oyabe.toyama.jp, 0
@@ -5810,6 +5908,7 @@ pb.leg.br, 4
pc.it, 0
pc.pl, 0
pccw, 0
+pcloud.host, 4
pd.it, 0
pe, 0
pe.ca, 0
@@ -6082,7 +6181,11 @@ rana.no, 0
randaberg.no, 0
rankoshi.hokkaido.jp, 0
ranzan.saitama.jp, 0
+ras.ru, 4
rauma.no, 0
+ravendb.community, 4
+ravendb.me, 4
+ravendb.run, 4
ravenna.it, 0
rawa-maz.pl, 0
rc.it, 0
@@ -6461,6 +6564,7 @@ schaeffler, 0
schlesisches.museum, 0
schmidt, 0
schoenbrunn.museum, 0
+schokokeks.net, 4
schokoladen.museum, 0
scholarships, 0
school, 0
@@ -6495,7 +6599,6 @@ sd.cn, 0
sd.us, 0
sdn.gov.pl, 0
se, 0
-se.com, 4
se.eu.org, 4
se.gov.br, 0
se.leg.br, 4
@@ -6817,6 +6920,7 @@ sos.pl, 0
sosa.chiba.jp, 0
sosnowiec.pl, 0
soundandvision.museum, 0
+soundcast.me, 4
southcarolina.museum, 0
southwest.museum, 0
sowa.ibaraki.jp, 0
@@ -6833,8 +6937,10 @@ spb.su, 4
spdns.de, 4
spdns.eu, 4
spdns.org, 4
+spectrum.myjino.ru, 6
spiegel, 0
spjelkavik.no, 0
+sport, 0
sport.hu, 0
spot, 0
spreadbetting, 0
@@ -7105,6 +7211,7 @@ taxi.br, 0
tc, 0
tci, 0
tcm.museum, 0
+tcp4.me, 4
td, 0
tdk, 0
te.it, 0
@@ -7139,6 +7246,7 @@ termez.su, 4
terni.it, 0
ternopil.ua, 0
teshikaga.hokkaido.jp, 0
+test-iserv.de, 4
test.ru, 0
test.tj, 0
teva, 0
@@ -7335,6 +7443,10 @@ travelers, 0
travelersinsurance, 0
trd.br, 0
tree.museum, 0
+trentin-sud-tirol.it, 0
+trentin-sudtirol.it, 0
+trentin-sued-tirol.it, 0
+trentin-suedtirol.it, 0
trentino-a-adige.it, 0
trentino-aadige.it, 0
trentino-alto-adige.it, 0
@@ -7356,6 +7468,10 @@ trentinosud-tirol.it, 0
trentinosudtirol.it, 0
trentinosued-tirol.it, 0
trentinosuedtirol.it, 0
+trentinsud-tirol.it, 0
+trentinsudtirol.it, 0
+trentinsued-tirol.it, 0
+trentinsuedtirol.it, 0
trento.it, 0
treviso.it, 0
trieste.it, 0
@@ -7445,10 +7561,13 @@ tysvar.no, 0
tz, 0
u.bg, 0
u.se, 0
+u2-local.xnbay.com, 4
+u2.xnbay.com, 4
ua, 0
ubank, 0
ube.yamaguchi.jp, 0
uber.space, 4
+uberspace.de, 6
ubs, 0
uchihara.ibaraki.jp, 0
uchiko.ehime.jp, 0
@@ -7477,6 +7596,7 @@ uk.eu.org, 4
uk.net, 4
uki.kumamoto.jp, 0
ukiha.fukuoka.jp, 0
+uklugs.org, 4
ullensaker.no, 0
ullensvang.no, 0
ulm.museum, 0
@@ -7548,6 +7668,7 @@ ushiku.ibaraki.jp, 0
ushistory.museum, 0
ushuaia.museum, 0
uslivinghistory.museum, 0
+usr.cloud.muni.cz, 4
ustka.pl, 0
usui.fukuoka.jp, 0
usuki.oita.jp, 0
@@ -7559,6 +7680,7 @@ utazu.kagawa.jp, 0
uto.kumamoto.jp, 0
utsira.no, 0
utsunomiya.tochigi.jp, 0
+utwente.io, 4
uvic.museum, 0
uw.gov.pl, 0
uwajima.ehime.jp, 0
@@ -7595,7 +7717,9 @@ valleaosta.it, 0
valled-aosta.it, 0
valledaosta.it, 0
vallee-aoste.it, 0
+vallee-d-aoste.it, 0
valleeaoste.it, 0
+valleedaoste.it, 0
valley.museum, 0
vana, 0
vang.no, 0
@@ -7673,7 +7797,9 @@ vip, 0
vipsinaapp.com, 4
virgin, 0
virginia.museum, 0
+virtual-user.de, 4
virtual.museum, 0
+virtualuser.de, 4
virtueeldomein.nl, 4
virtuel.museum, 0
visa, 0
@@ -7707,7 +7833,9 @@ vote, 0
voting, 0
voto, 0
voyage, 0
+vpndns.net, 4
vpnplus.to, 4
+vps.myjino.ru, 6
vr.it, 0
vs.it, 0
vt.it, 0
@@ -7854,6 +7982,7 @@ wy.us, 0
wzmiuw.gov.pl, 0
x.bg, 0
x.se, 0
+x443.pw, 4
xbox, 0
xen.prgmr.com, 4
xenapponazure.com, 4
@@ -7895,6 +8024,7 @@ xn--55qw42g, 0
xn--55qx5d, 0
xn--55qx5d.cn, 0
xn--55qx5d.hk, 0
+xn--55qx5d.xn--j6w193g, 0
xn--5js045d.jp, 0
xn--5rtp49c.jp, 0
xn--5rtq34k.jp, 0
@@ -7930,6 +8060,7 @@ xn--avery-yua.no, 0
xn--b-5ga.nordland.no, 0
xn--b-5ga.telemark.no, 0
xn--b4w605ferd, 0
+xn--balsan-sdtirol-nsb.it, 0
xn--bck1b9a5dre4c, 0
xn--bdddj-mrabd.no, 0
xn--bearalvhki-y4a.no, 0
@@ -7943,15 +8074,19 @@ xn--bjddar-pta.no, 0
xn--blt-elab.no, 0
xn--bmlo-gra.no, 0
xn--bod-2na.no, 0
+xn--bozen-sdtirol-2ob.it, 0
xn--brnny-wuac.no, 0
xn--brnnysund-m8ac.no, 0
xn--brum-voa.no, 0
xn--btsfjord-9za.no, 0
+xn--bulsan-sdtirol-nsb.it, 0
xn--c1avg, 0
xn--c1avg.xn--90a3ac, 0
xn--c2br7g, 0
xn--c3s14m.jp, 0
xn--cck2b3b, 0
+xn--cesena-forl-mcb.it, 0
+xn--cesenaforl-i8a.it, 0
xn--cg4bki, 0
xn--ciqpn.hk, 0
xn--clchc0ea0b2g2a9gcd, 0
@@ -7992,6 +8127,8 @@ xn--fjq720a, 0
xn--fl-zia.no, 0
xn--flor-jra.no, 0
xn--flw351e, 0
+xn--forl-cesena-fcb.it, 0
+xn--forlcesena-c8a.it, 0
xn--fpcrj9c3d, 0
xn--frde-gra.no, 0
xn--frna-woa.no, 0
@@ -8009,6 +8146,7 @@ xn--gk3at1e, 0
xn--gls-elac.no, 0
xn--gmq050i.hk, 0
xn--gmqw5a.hk, 0
+xn--gmqw5a.xn--j6w193g, 0
xn--h-2fa.no, 0
xn--h1aegh.museum, 0
xn--h2breg3eve, 0
@@ -8102,6 +8240,7 @@ xn--mgbai9a5eva00b, 0
xn--mgbai9azgqp6j, 0
xn--mgbayh7gpa, 0
xn--mgbb9fbpob, 0
+xn--mgbbh1a, 0
xn--mgbbh1a71e, 0
xn--mgbc0a9azcg, 0
xn--mgbca7dzdo, 0
@@ -8134,6 +8273,7 @@ xn--mtta-vrjjat-k7af.no, 0
xn--muost-0qa.no, 0
xn--mxtq1m, 0
xn--mxtq1m.hk, 0
+xn--mxtq1m.xn--j6w193g, 0
xn--ngbc5azd, 0
xn--ngbe9e0a, 0
xn--ngbrx, 0
@@ -8155,11 +8295,13 @@ xn--o3cw4h, 0
xn--o3cyx2a.xn--o3cw4h, 0
xn--od0alg.cn, 0
xn--od0alg.hk, 0
+xn--od0alg.xn--j6w193g, 0
xn--od0aq3b.hk, 0
xn--ogbpf8fl, 0
xn--oppegrd-ixa.no, 0
xn--ostery-fya.no, 0
xn--osyro-wua.no, 0
+xn--otu796d, 0
xn--p1acf, 0
xn--p1ai, 0
xn--pbt977c, 0
@@ -8200,6 +8342,7 @@ xn--s-1fa.no, 0
xn--s9brj9c, 0
xn--sandnessjen-ogb.no, 0
xn--sandy-yua.no, 0
+xn--sdtirol-n2a.it, 0
xn--seral-lra.no, 0
xn--ses554g, 0
xn--sgne-gra.no, 0
@@ -8234,12 +8377,21 @@ xn--tn0ag.hk, 0
xn--tnsberg-q1a.no, 0
xn--tor131o.jp, 0
xn--trany-yua.no, 0
+xn--trentin-sd-tirol-rzb.it, 0
+xn--trentin-sdtirol-7vb.it, 0
+xn--trentino-sd-tirol-c3b.it, 0
+xn--trentino-sdtirol-szb.it, 0
+xn--trentinosd-tirol-rzb.it, 0
+xn--trentinosdtirol-7vb.it, 0
+xn--trentinsd-tirol-6vb.it, 0
+xn--trentinsdtirol-nsb.it, 0
xn--trgstad-r1a.no, 0
xn--trna-woa.no, 0
xn--troms-zua.no, 0
xn--tysvr-vra.no, 0
xn--uc0atv.hk, 0
xn--uc0atv.tw, 0
+xn--uc0atv.xn--j6w193g, 0
xn--uc0ay4a.hk, 0
xn--uist22h.jp, 0
xn--uisz3g.jp, 0
@@ -8247,6 +8399,10 @@ xn--unjrga-rta.no, 0
xn--unup4y, 0
xn--uuwu58a.jp, 0
xn--vads-jra.no, 0
+xn--valle-aoste-ebb.it, 0
+xn--valle-d-aoste-ehb.it, 0
+xn--valleaoste-e7a.it, 0
+xn--valledaoste-ebb.it, 0
xn--vard-jra.no, 0
xn--vegrshei-c0a.no, 0
xn--vermgensberater-ctb, 0
@@ -8266,6 +8422,7 @@ xn--vuq861b, 0
xn--w4r85el8fhu5dnra, 0
xn--w4rs40l, 0
xn--wcvs22d.hk, 0
+xn--wcvs22d.xn--j6w193g, 0
xn--wgbh1c, 0
xn--wgbl6a, 0
xn--xhq521b, 0
@@ -8281,6 +8438,7 @@ xn--zbx025d.jp, 0
xn--zf0ao64a.tw, 0
xn--zf0avx.hk, 0
xn--zfr164b, 0
+xnbay.com, 4
xperia, 0
xs4all.space, 4
xxx, 0
@@ -8428,6 +8586,7 @@ zaporizhzhe.ua, 0
zaporizhzhia.ua, 0
zappos, 0
zapto.org, 4
+zapto.xyz, 4
zara, 0
zarow.pl, 0
zentsuji.kagawa.jp, 0
@@ -8442,6 +8601,7 @@ zj.cn, 0
zlg.br, 0
zm, 0
zone, 0
+zone.id, 4
zoological.museum, 0
zoology.museum, 0
zp.gov.pl, 0
diff --git a/chromium/net/base/test_proxy_delegate.cc b/chromium/net/base/test_proxy_delegate.cc
index 633687b4ddb..5ac1dbea263 100644
--- a/chromium/net/base/test_proxy_delegate.cc
+++ b/chromium/net/base/test_proxy_delegate.cc
@@ -5,6 +5,7 @@
#include "net/base/test_proxy_delegate.h"
#include "net/proxy_resolution/proxy_info.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -29,6 +30,8 @@ void TestProxyDelegate::OnResolveProxy(
}
}
result->UseProxyList(new_proxy_list);
+ result->set_traffic_annotation(
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
}
// Only set |alternative_proxy_server_| as the alternative proxy if the
@@ -38,6 +41,8 @@ void TestProxyDelegate::OnResolveProxy(
alternative_proxy_info.DeprioritizeBadProxies(proxy_retry_info);
if (!alternative_proxy_info.is_empty())
result->SetAlternativeProxy(alternative_proxy_info.proxy_server());
+ result->set_traffic_annotation(
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
}
void TestProxyDelegate::OnFallback(const ProxyServer& bad_proxy,
diff --git a/chromium/net/base/unescape_url_component_fuzzer.cc b/chromium/net/base/unescape_url_component_fuzzer.cc
index 0053011c1f5..2a4575c4789 100644
--- a/chromium/net/base/unescape_url_component_fuzzer.cc
+++ b/chromium/net/base/unescape_url_component_fuzzer.cc
@@ -13,10 +13,10 @@ static const int kMaxUnescapeRule = 31;
// Entry point for LibFuzzer.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- std::string path(reinterpret_cast<const char*>(data), size);
+ base::StringPiece path(reinterpret_cast<const char*>(data), size);
for (int i = 0; i <= kMaxUnescapeRule; i++) {
- (void)net::UnescapeURLComponent(path,
- static_cast<net::UnescapeRule::Type>(i));
+ net::UnescapeURLComponent(path, static_cast<net::UnescapeRule::Type>(i));
}
+
return 0;
}
diff --git a/chromium/net/base/upload_data_stream.h b/chromium/net/base/upload_data_stream.h
index 1c6e554b0df..b9645ec5a09 100644
--- a/chromium/net/base/upload_data_stream.h
+++ b/chromium/net/base/upload_data_stream.h
@@ -124,7 +124,7 @@ class NET_EXPORT UploadDataStream {
virtual int ReadInternal(IOBuffer* buf, int buf_len) = 0;
// Resets state and cancels any pending callbacks. Guaranteed to be called
- // before all but the first call to InitInternal.
+ // at least once before every call to InitInternal.
virtual void ResetInternal() = 0;
uint64_t total_size_;
diff --git a/chromium/net/base/url_util.cc b/chromium/net/base/url_util.cc
index 3bd93aa4006..57d180e870e 100644
--- a/chromium/net/base/url_util.cc
+++ b/chromium/net/base/url_util.cc
@@ -154,25 +154,19 @@ bool GetValueForKeyInQuery(const GURL& url,
return false;
}
-bool ParseHostAndPort(std::string::const_iterator host_and_port_begin,
- std::string::const_iterator host_and_port_end,
- std::string* host,
- int* port) {
- if (host_and_port_begin >= host_and_port_end)
+bool ParseHostAndPort(base::StringPiece input, std::string* host, int* port) {
+ if (input.empty())
return false;
- // When using url, we use char*.
- const char* auth_begin = &(*host_and_port_begin);
- int auth_len = host_and_port_end - host_and_port_begin;
-
- url::Component auth_component(0, auth_len);
+ url::Component auth_component(0, input.size());
url::Component username_component;
url::Component password_component;
url::Component hostname_component;
url::Component port_component;
- url::ParseAuthority(auth_begin, auth_component, &username_component,
- &password_component, &hostname_component, &port_component);
+ url::ParseAuthority(input.data(), auth_component, &username_component,
+ &password_component, &hostname_component,
+ &port_component);
// There shouldn't be a username/password.
if (username_component.is_valid() || password_component.is_valid())
@@ -183,7 +177,7 @@ bool ParseHostAndPort(std::string::const_iterator host_and_port_begin,
int parsed_port_number = -1;
if (port_component.is_nonempty()) {
- parsed_port_number = url::ParsePort(auth_begin, port_component);
+ parsed_port_number = url::ParsePort(input.data(), port_component);
// If parsing failed, port_number will be either PORT_INVALID or
// PORT_UNSPECIFIED, both of which are negative.
@@ -198,11 +192,10 @@ bool ParseHostAndPort(std::string::const_iterator host_and_port_begin,
// If the hostname starts with a bracket, it is either an IPv6 literal or
// invalid. If it is an IPv6 literal then strip the brackets.
- if (hostname_component.len > 0 &&
- auth_begin[hostname_component.begin] == '[') {
- if (auth_begin[hostname_component.end() - 1] == ']' &&
- url::IPv6AddressToNumber(
- auth_begin, hostname_component, tmp_ipv6_addr)) {
+ if (hostname_component.len > 0 && input[hostname_component.begin] == '[') {
+ if (input[hostname_component.end() - 1] == ']' &&
+ url::IPv6AddressToNumber(input.data(), hostname_component,
+ tmp_ipv6_addr)) {
// Strip the brackets.
hostname_component.begin++;
hostname_component.len -= 2;
@@ -212,19 +205,12 @@ bool ParseHostAndPort(std::string::const_iterator host_and_port_begin,
}
// Pass results back to caller.
- host->assign(auth_begin + hostname_component.begin, hostname_component.len);
+ host->assign(input.data() + hostname_component.begin, hostname_component.len);
*port = parsed_port_number;
return true; // Success.
}
-bool ParseHostAndPort(const std::string& host_and_port,
- std::string* host,
- int* port) {
- return ParseHostAndPort(
- host_and_port.begin(), host_and_port.end(), host, port);
-}
-
std::string GetHostAndPort(const GURL& url) {
// For IPv6 literals, GURL::host() already includes the brackets so it is
@@ -315,7 +301,7 @@ bool IsHostnameNonUnique(const std::string& hostname) {
return false;
// If |hostname| is an IP address, check to see if it's in an IANA-reserved
- // range.
+ // range reserved for non-publicly routable networks.
if (host_info.IsIPAddress()) {
IPAddress host_addr;
if (!host_addr.AssignFromIPLiteral(hostname.substr(
@@ -325,7 +311,7 @@ bool IsHostnameNonUnique(const std::string& hostname) {
switch (host_info.family) {
case url::CanonHostInfo::IPV4:
case url::CanonHostInfo::IPV6:
- return host_addr.IsReserved();
+ return !host_addr.IsPubliclyRoutable();
case url::CanonHostInfo::NEUTRAL:
case url::CanonHostInfo::BROKEN:
return false;
diff --git a/chromium/net/base/url_util.h b/chromium/net/base/url_util.h
index 97e7724cfd3..0b820a70557 100644
--- a/chromium/net/base/url_util.h
+++ b/chromium/net/base/url_util.h
@@ -98,12 +98,7 @@ NET_EXPORT bool GetValueForKeyInQuery(const GURL& url,
// [::1]:90 and [::1]
//
// The resultant |*host| in both cases will be "::1" (not bracketed).
-NET_EXPORT bool ParseHostAndPort(
- std::string::const_iterator host_and_port_begin,
- std::string::const_iterator host_and_port_end,
- std::string* host,
- int* port);
-NET_EXPORT bool ParseHostAndPort(const std::string& host_and_port,
+NET_EXPORT bool ParseHostAndPort(base::StringPiece input,
std::string* host,
int* port);
@@ -139,7 +134,7 @@ NET_EXPORT bool IsCanonicalizedHostCompliant(const std::string& host);
// Returns true if |hostname| contains a non-registerable or non-assignable
// domain name (eg: a gTLD that has not been assigned by IANA) or an IP address
-// that falls in an IANA-reserved range.
+// that falls in an range reserved for non-publicly routable networks.
NET_EXPORT bool IsHostnameNonUnique(const std::string& hostname);
// Returns true if the host part of |url| is a local host name according to
diff --git a/chromium/net/cert/cert_database_nss.cc b/chromium/net/cert/cert_database_nss.cc
index 403ffbe48e6..832f901347d 100644
--- a/chromium/net/cert/cert_database_nss.cc
+++ b/chromium/net/cert/cert_database_nss.cc
@@ -5,13 +5,11 @@
#include "net/cert/cert_database.h"
#include "base/observer_list_threadsafe.h"
-#include "crypto/nss_util.h"
namespace net {
CertDatabase::CertDatabase()
: observer_list_(new base::ObserverListThreadSafe<Observer>) {
- crypto::EnsureNSSInit();
}
CertDatabase::~CertDatabase() = default;
diff --git a/chromium/net/cert/cert_status_flags_list.h b/chromium/net/cert/cert_status_flags_list.h
index d2854723b89..cbde71f8b6a 100644
--- a/chromium/net/cert/cert_status_flags_list.h
+++ b/chromium/net/cert/cert_status_flags_list.h
@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// This file intentionally does not have header guards, it's included
+// inside a macro to generate enum values. The following line silences a
+// presubmit warning that would otherwise be triggered by this:
+// no-include-guard-because-multiply-included
+
// This is the list of CertStatus flags and their values.
//
// Defines the values using a macro CERT_STATUS_FLAG,
diff --git a/chromium/net/cert/cert_verifier.h b/chromium/net/cert/cert_verifier.h
index c083c86ebfc..8c0ac02e54e 100644
--- a/chromium/net/cert/cert_verifier.h
+++ b/chromium/net/cert/cert_verifier.h
@@ -43,27 +43,9 @@ class NET_EXPORT CertVerifier {
// certificate chain.
VERIFY_REV_CHECKING_ENABLED = 1 << 0,
- // If set, and the certificate being verified may be an EV certificate,
- // attempt to verify the certificate according to the EV processing
- // guidelines. In order to successfully verify a certificate as EV,
- // either an online or offline revocation check must be successfully
- // completed. To ensure it's possible to complete a revocation check,
- // callers should also specify either VERIFY_REV_CHECKING_ENABLED or
- // VERIFY_REV_CHECKING_ENABLED_EV_ONLY (to enable online checks), and
- // VERIFY_CERT_IO_ENABLED (to enable network fetches for online checks).
- VERIFY_EV_CERT = 1 << 1,
-
- // If set, permits NSS to use the network when verifying certificates,
- // such as to fetch missing intermediates or to check OCSP or CRLs.
- // TODO(rsleevi): http://crbug.com/143300 - Define this flag for all
- // verification engines with well-defined semantics, rather than being
- // NSS only.
- VERIFY_CERT_IO_ENABLED = 1 << 2,
-
- // If set, enables online revocation checking via CRLs or OCSP when the
- // chain is not covered by a fresh CRLSet, but only for certificates which
- // may be EV, and only when VERIFY_EV_CERT is also set.
- VERIFY_REV_CHECKING_ENABLED_EV_ONLY = 1 << 3,
+ // 1 << 1 is reserved (used to be VERIFY_EV_CERT).
+ // 1 << 2 is reserved (used to be VERIY_CERT_IO_ENABLED).
+ // 1 << 3 is reserved (used to be VERIFY_REV_CHECKING_ENABLED_EV_ONLY).
// If set, this is equivalent to VERIFY_REV_CHECKING_ENABLED, in that it
// enables online revocation checking via CRLs or OCSP, but only
@@ -80,7 +62,8 @@ class NET_EXPORT CertVerifier {
// they are issued by non-public trust anchors.
VERIFY_ENABLE_SHA1_LOCAL_ANCHORS = 1 << 5,
- // 1 << 6 is reserved.
+ // 1 << 6 is reserved (used to be
+ // VERIFY_ENABLE_COMMON_NAME_FALLBACK_LOCAL_ANCHORS).
// If set, disables the policy enforcement described at
// https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html
diff --git a/chromium/net/cert/cert_verifier_unittest.cc b/chromium/net/cert/cert_verifier_unittest.cc
index b54f00fa3ab..fa76bedd4ba 100644
--- a/chromium/net/cert/cert_verifier_unittest.cc
+++ b/chromium/net/cert/cert_verifier_unittest.cc
@@ -87,7 +87,7 @@ TEST(CertVerifierTest, RequestParamsComparators) {
// The same certificate, chain, and host, but with different flags
// are different validation keys.
CertVerifier::RequestParams(ok_cert, "www.example.test",
- CertVerifier::VERIFY_EV_CERT,
+ CertVerifier::VERIFY_REV_CHECKING_ENABLED,
std::string(), empty_list),
CertVerifier::RequestParams(ok_cert, "www.example.test", 0,
std::string(), empty_list),
diff --git a/chromium/net/cert/cert_verify_proc.cc b/chromium/net/cert/cert_verify_proc.cc
index ba51d3a1efe..a43741e8c2c 100644
--- a/chromium/net/cert/cert_verify_proc.cc
+++ b/chromium/net/cert/cert_verify_proc.cc
@@ -290,7 +290,13 @@ void RecordTLSFeatureExtensionWithPrivateRoot(
// This also accounts for situations in which a new CA is introduced, and
// has been cross-signed by an existing CA. Assessing impact should use the
// most-specific trust anchor, when possible.
-void RecordTrustAnchorHistogram(const HashValueVector& spki_hashes) {
+//
+// This also histograms for divergence between the root store and
+// |spki_hashes| - that is, situations in which the OS methods of detecting
+// a known root flag a certificate as known, but its hash is not known as part
+// of the built-in list.
+void RecordTrustAnchorHistogram(const HashValueVector& spki_hashes,
+ bool is_issued_by_known_root) {
int32_t id = 0;
for (const auto& hash : spki_hashes) {
id = GetNetTrustAnchorHistogramIdForSPKI(hash);
@@ -298,6 +304,14 @@ void RecordTrustAnchorHistogram(const HashValueVector& spki_hashes) {
break;
}
base::UmaHistogramSparse("Net.Certificate.TrustAnchor.Verify", id);
+
+ // Record when a known trust anchor is not found within the chain, but the
+ // certificate is flagged as being from a known root (meaning a fallback to
+ // OS-based methods of determination).
+ if (id == 0) {
+ UMA_HISTOGRAM_BOOLEAN("Net.Certificate.TrustAnchor.VerifyOutOfDate",
+ is_issued_by_known_root);
+ }
}
// Comparison functor used for binary searching whether a given HashValue,
@@ -508,13 +522,6 @@ int CertVerifyProc::Verify(X509Certificate* cert,
return ERR_CERT_REVOKED;
}
- // We do online revocation checking for EV certificates that aren't covered
- // by a fresh CRLSet.
- // TODO(rsleevi): http://crbug.com/142974 - Allow preferences to fully
- // disable revocation checking.
- if (flags & CertVerifier::VERIFY_EV_CERT)
- flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY;
-
int rv = VerifyInternal(cert, hostname, ocsp_response, flags, crl_set,
additional_trust_anchors, verify_result);
@@ -639,8 +646,10 @@ int CertVerifyProc::Verify(X509Certificate* cert,
RecordTLSFeatureExtensionWithPrivateRoot(cert, verify_result->ocsp_result);
// Record a histogram for per-verification usage of root certs.
- if (rv == OK)
- RecordTrustAnchorHistogram(verify_result->public_key_hashes);
+ if (rv == OK) {
+ RecordTrustAnchorHistogram(verify_result->public_key_hashes,
+ verify_result->is_issued_by_known_root);
+ }
return rv;
}
@@ -860,23 +869,6 @@ bool CertVerifyProc::HasTooLongValidity(const X509Certificate& cert) {
return true;
}
- base::Time::Exploded exploded_start;
- base::Time::Exploded exploded_expiry;
- cert.valid_start().UTCExplode(&exploded_start);
- cert.valid_expiry().UTCExplode(&exploded_expiry);
-
- if (exploded_expiry.year - exploded_start.year > 10)
- return true;
-
- int month_diff = (exploded_expiry.year - exploded_start.year) * 12 +
- (exploded_expiry.month - exploded_start.month);
-
- base::TimeDelta days_diff = cert.valid_expiry() - cert.valid_start();
-
- // Add any remainder as a full month.
- if (exploded_expiry.day_of_month > exploded_start.day_of_month)
- ++month_diff;
-
// These dates are derived from the transitions noted in Section 1.2.2
// (Relevant Dates) of the Baseline Requirements.
const base::Time time_2012_07_01 =
@@ -888,22 +880,41 @@ bool CertVerifyProc::HasTooLongValidity(const X509Certificate& cert) {
const base::Time time_2019_07_01 =
base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(1561939200);
+ // Compute the maximally permissive interpretations, accounting for leap
+ // years.
+ // 10 years - two possible leap years.
+ constexpr base::TimeDelta kTenYears =
+ base::TimeDelta::FromDays((365 * 8) + (366 * 2));
+ // 5 years - two possible leap years (year 0/year 4 or year 1/year 5).
+ constexpr base::TimeDelta kSixtyMonths =
+ base::TimeDelta::FromDays((365 * 3) + (366 * 2));
+ // 39 months - one possible leap year, two at 365 days, and the longest
+ // monthly sequence of 31/31/30 days (June/July/August).
+ constexpr base::TimeDelta kThirtyNineMonths =
+ base::TimeDelta::FromDays(366 + 365 + 365 + 31 + 31 + 30);
+
+ base::TimeDelta validity_duration = cert.valid_expiry() - cert.valid_start();
+
// For certificates issued before the BRs took effect.
- if (start < time_2012_07_01 && (month_diff > 120 || expiry > time_2019_07_01))
+ if (start < time_2012_07_01 &&
+ (validity_duration > kTenYears || expiry > time_2019_07_01)) {
return true;
+ }
// For certificates issued after the BR effective date of 1 July 2012: 60
// months.
- if (start >= time_2012_07_01 && month_diff > 60)
+ if (start >= time_2012_07_01 && validity_duration > kSixtyMonths)
return true;
// For certificates issued after 1 April 2015: 39 months.
- if (start >= time_2015_04_01 && month_diff > 39)
+ if (start >= time_2015_04_01 && validity_duration > kThirtyNineMonths)
return true;
// For certificates issued after 1 March 2018: 825 days.
- if (start >= time_2018_03_01 && days_diff > base::TimeDelta::FromDays(825))
+ if (start >= time_2018_03_01 &&
+ validity_duration > base::TimeDelta::FromDays(825)) {
return true;
+ }
return false;
}
diff --git a/chromium/net/cert/cert_verify_proc_builtin.cc b/chromium/net/cert/cert_verify_proc_builtin.cc
index 50dcda98452..95cf8ffb253 100644
--- a/chromium/net/cert/cert_verify_proc_builtin.cc
+++ b/chromium/net/cert/cert_verify_proc_builtin.cc
@@ -185,8 +185,7 @@ class PathBuilderDelegateImpl : public SimplePathBuilderDelegate {
!certs.empty() && !ssl_trust_store_->IsKnownRoot(certs.back().get())) {
RevocationPolicy policy;
policy.check_revocation = true;
- policy.networking_allowed =
- (flags_ & CertVerifier::VERIFY_CERT_IO_ENABLED);
+ policy.networking_allowed = true;
policy.allow_missing_info = true;
policy.allow_network_failure = false;
@@ -206,12 +205,7 @@ class PathBuilderDelegateImpl : public SimplePathBuilderDelegate {
RevocationPolicy policy;
policy.check_revocation = true;
- // TODO(eroman): This definition for |networking_allowed| is redundant.
- // Perhaps VERIFY_EV_CERT should imply revocation checking.
- policy.networking_allowed =
- (flags_ & CertVerifier::VERIFY_CERT_IO_ENABLED) &&
- ((flags_ & CertVerifier::VERIFY_REV_CHECKING_ENABLED) ||
- (flags_ & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY));
+ policy.networking_allowed = true;
policy.allow_missing_info = false;
policy.allow_network_failure = false;
return policy;
@@ -221,7 +215,7 @@ class PathBuilderDelegateImpl : public SimplePathBuilderDelegate {
if (flags_ & CertVerifier::VERIFY_REV_CHECKING_ENABLED) {
RevocationPolicy policy;
policy.check_revocation = true;
- policy.networking_allowed = flags_ & CertVerifier::VERIFY_CERT_IO_ENABLED;
+ policy.networking_allowed = true;
policy.allow_missing_info = true;
policy.allow_network_failure = true;
return policy;
@@ -449,14 +443,11 @@ void TryBuildPath(const scoped_refptr<ParsedCertificate>& target,
// Allow the path builder to discover intermediates through AIA fetching.
std::unique_ptr<CertIssuerSourceAia> aia_cert_issuer_source;
- if (flags & CertVerifier::VERIFY_CERT_IO_ENABLED) {
- if (net_fetcher) {
- aia_cert_issuer_source =
- std::make_unique<CertIssuerSourceAia>(net_fetcher);
- path_builder.AddCertIssuerSource(aia_cert_issuer_source.get());
- } else {
- LOG(ERROR) << "VERIFY_CERT_IO_ENABLED specified but no net_fetcher";
- }
+ if (net_fetcher) {
+ aia_cert_issuer_source = std::make_unique<CertIssuerSourceAia>(net_fetcher);
+ path_builder.AddCertIssuerSource(aia_cert_issuer_source.get());
+ } else {
+ LOG(ERROR) << "No net_fetcher for performing AIA chasing.";
}
path_builder.Run();
@@ -585,10 +576,9 @@ int CertVerifyProcBuiltin::VerifyInternal(
// setting output flag CERT_STATUS_REV_CHECKING_ENABLED).
bool checked_revocation_for_some_path = false;
- // Only attempt to build EV paths if it was requested by the caller AND the
- // target could possibly be an EV certificate.
- const bool should_try_ev = (flags & CertVerifier::VERIFY_EV_CERT) &&
- IsEVCandidate(ev_metadata, target.get());
+ // Only attempt to build EV paths if the target could possibly be an EV
+ // certificate.
+ const bool should_try_ev = IsEVCandidate(ev_metadata, target.get());
// Run path building with the different parameters (attempts) until a valid
// path is found. Earlier successful attempts have priority over later
diff --git a/chromium/net/cert/cert_verify_proc_ios.cc b/chromium/net/cert/cert_verify_proc_ios.cc
index a388b8ed3d1..ecb3e232584 100644
--- a/chromium/net/cert/cert_verify_proc_ios.cc
+++ b/chromium/net/cert/cert_verify_proc_ios.cc
@@ -205,6 +205,12 @@ CertStatus CertVerifyProcIOS::GetCertFailureStatusFromTrust(SecTrustRef trust) {
CFBundleCopyLocalizedString(bundle, hostname_mismatch_string,
hostname_mismatch_string,
CFSTR("SecCertificate")));
+ CFStringRef policy_requirements_not_met_string =
+ CFSTR("Policy requirements not met.");
+ ScopedCFTypeRef<CFStringRef> policy_requirements_not_met_error(
+ CFBundleCopyLocalizedString(bundle, policy_requirements_not_met_string,
+ policy_requirements_not_met_string,
+ CFSTR("SecCertificate")));
for (CFIndex i = 0; i < properties_length; ++i) {
CFDictionaryRef dict = reinterpret_cast<CFDictionaryRef>(
@@ -220,6 +226,8 @@ CertStatus CertVerifyProcIOS::GetCertFailureStatusFromTrust(SecTrustRef trust) {
reason |= CERT_STATUS_WEAK_KEY;
} else if (CFEqual(error, hostname_mismatch_error)) {
reason |= CERT_STATUS_COMMON_NAME_INVALID;
+ } else if (CFEqual(error, policy_requirements_not_met_error)) {
+ reason |= CERT_STATUS_INVALID | CERT_STATUS_AUTHORITY_INVALID;
} else {
reason |= CERT_STATUS_INVALID;
}
diff --git a/chromium/net/cert/cert_verify_proc_ios_unittest.cc b/chromium/net/cert/cert_verify_proc_ios_unittest.mm
index e76b2b7373c..76bb129de38 100644
--- a/chromium/net/cert/cert_verify_proc_ios_unittest.cc
+++ b/chromium/net/cert/cert_verify_proc_ios_unittest.mm
@@ -14,6 +14,7 @@
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
namespace {
@@ -49,25 +50,31 @@ base::ScopedCFTypeRef<SecTrustRef> CreateSecTrust(
namespace net {
+using CertVerifyProcIOSTest = PlatformTest;
+
// Tests |GetCertFailureStatusFromTrust| with null trust object.
-TEST(CertVerifyProcIOSTest, StatusForNullTrust) {
+TEST_F(CertVerifyProcIOSTest, StatusForNullTrust) {
EXPECT_EQ(CERT_STATUS_INVALID,
CertVerifyProcIOS::GetCertFailureStatusFromTrust(nullptr));
}
// Tests |GetCertFailureStatusFromTrust| with trust object that has not been
// evaluated backed by ok_cert.pem cert.
-TEST(CertVerifyProcIOSTest, StatusForNotEvaluatedTrust) {
+TEST_F(CertVerifyProcIOSTest, StatusForNotEvaluatedTrust) {
CertStatus status = CertVerifyProcIOS::GetCertFailureStatusFromTrust(
CreateSecTrust("ok_cert.pem"));
EXPECT_TRUE(status & CERT_STATUS_COMMON_NAME_INVALID);
EXPECT_TRUE(status & CERT_STATUS_AUTHORITY_INVALID);
- EXPECT_FALSE(status & CERT_STATUS_DATE_INVALID);
+ if (@available(iOS 11.4, *)) {
+ // Prior to iOS 11.4 non-evaluated certs report CERT_STATUS_DATE_INVALID.
+ } else {
+ EXPECT_FALSE(status & CERT_STATUS_DATE_INVALID);
+ }
}
// Tests |GetCertFailureStatusFromTrust| with evaluated trust object backed by
// expired_cert.pem cert.
-TEST(CertVerifyProcIOSTest, StatusForEvaluatedTrust) {
+TEST_F(CertVerifyProcIOSTest, StatusForEvaluatedTrust) {
base::ScopedCFTypeRef<SecTrustRef> trust(CreateSecTrust("expired_cert.pem"));
ASSERT_TRUE(trust);
SecTrustEvaluate(trust, nullptr);
diff --git a/chromium/net/cert/cert_verify_proc_mac.cc b/chromium/net/cert/cert_verify_proc_mac.cc
index 6e482e1eeb0..7484f58456f 100644
--- a/chromium/net/cert/cert_verify_proc_mac.cc
+++ b/chromium/net/cert/cert_verify_proc_mac.cc
@@ -1003,10 +1003,9 @@ int CertVerifyProcMac::VerifyInternal(
// verification with different flags.
const CertVerifyResult input_verify_result(*verify_result);
- // If EV verification is enabled, check for EV policy in leaf cert.
+ // Check for EV policy in leaf cert.
std::string candidate_ev_policy_oid;
- if (flags & CertVerifier::VERIFY_EV_CERT)
- GetCandidateEVPolicy(cert, &candidate_ev_policy_oid);
+ GetCandidateEVPolicy(cert, &candidate_ev_policy_oid);
CRLSetResult completed_chain_crl_result;
int rv = VerifyWithGivenFlags(cert, hostname, flags, crl_set, verify_result,
@@ -1020,7 +1019,6 @@ int CertVerifyProcMac::VerifyInternal(
// EV policies check out and the verification succeeded. See if revocation
// checking still needs to be done before it can be marked as EV.
if (completed_chain_crl_result == kCRLSetUnknown &&
- (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY) &&
!(flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED)) {
// If this is an EV cert and it wasn't covered by CRLSets and revocation
// checking wasn't already on, try again with revocation forced on.
diff --git a/chromium/net/cert/cert_verify_proc_mac_unittest.cc b/chromium/net/cert/cert_verify_proc_mac_unittest.cc
index 79a0a08d311..d8134385022 100644
--- a/chromium/net/cert/cert_verify_proc_mac_unittest.cc
+++ b/chromium/net/cert/cert_verify_proc_mac_unittest.cc
@@ -170,7 +170,6 @@ TEST(CertVerifyProcMacTest, MacKeychainReordering) {
CertificateList(), &verify_result);
ASSERT_EQ(OK, error);
- EXPECT_EQ(0U, verify_result.cert_status);
EXPECT_FALSE(verify_result.has_sha1);
ASSERT_TRUE(verify_result.verified_cert.get());
diff --git a/chromium/net/cert/cert_verify_proc_nss.cc b/chromium/net/cert/cert_verify_proc_nss.cc
index 9860ac3a8c3..195a9015014 100644
--- a/chromium/net/cert/cert_verify_proc_nss.cc
+++ b/chromium/net/cert/cert_verify_proc_nss.cc
@@ -34,6 +34,7 @@
#include "net/cert/known_roots_nss.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util_nss.h"
+#include "net/cert_net/nss_ocsp.h"
#include <dlfcn.h>
@@ -383,10 +384,10 @@ SECStatus CheckChainRevocationWithCRLSet(void* is_chain_valid_arg,
}
// Forward declarations.
-SECStatus RetryPKIXVerifyCertWithWorkarounds(
- CERTCertificate* cert_handle, int num_policy_oids,
- bool cert_io_enabled, std::vector<CERTValInParam>* cvin,
- CERTValOutParam* cvout);
+SECStatus RetryPKIXVerifyCertWithWorkarounds(CERTCertificate* cert_handle,
+ int num_policy_oids,
+ std::vector<CERTValInParam>* cvin,
+ CERTValOutParam* cvout);
SECOidTag GetFirstCertPolicy(CERTCertificate* cert_handle);
// Call CERT_PKIXVerifyCert for the cert_handle.
@@ -405,7 +406,6 @@ SECOidTag GetFirstCertPolicy(CERTCertificate* cert_handle);
SECStatus PKIXVerifyCert(CERTCertificate* cert_handle,
bool check_revocation,
bool hard_fail,
- bool cert_io_enabled,
const SECOidTag* policy_oids,
int num_policy_oids,
CERTCertList* additional_trust_anchors,
@@ -510,8 +510,8 @@ SECStatus PKIXVerifyCert(CERTCertificate* cert_handle,
SECStatus rv = CERT_PKIXVerifyCert(cert_handle, certificateUsageSSLServer,
&cvin[0], cvout, NULL);
if (rv != SECSuccess) {
- rv = RetryPKIXVerifyCertWithWorkarounds(cert_handle, num_policy_oids,
- cert_io_enabled, &cvin, cvout);
+ rv = RetryPKIXVerifyCertWithWorkarounds(cert_handle, num_policy_oids, &cvin,
+ cvout);
}
return rv;
}
@@ -519,10 +519,10 @@ SECStatus PKIXVerifyCert(CERTCertificate* cert_handle,
// PKIXVerifyCert calls this function to work around some bugs in
// CERT_PKIXVerifyCert. All the arguments of this function are either the
// arguments or local variables of PKIXVerifyCert.
-SECStatus RetryPKIXVerifyCertWithWorkarounds(
- CERTCertificate* cert_handle, int num_policy_oids,
- bool cert_io_enabled, std::vector<CERTValInParam>* cvin,
- CERTValOutParam* cvout) {
+SECStatus RetryPKIXVerifyCertWithWorkarounds(CERTCertificate* cert_handle,
+ int num_policy_oids,
+ std::vector<CERTValInParam>* cvin,
+ CERTValOutParam* cvout) {
// We call this function when the first CERT_PKIXVerifyCert call in
// PKIXVerifyCert failed, so we initialize |rv| to SECFailure.
SECStatus rv = SECFailure;
@@ -538,8 +538,7 @@ SECStatus RetryPKIXVerifyCertWithWorkarounds(
// missing intermediate CA certificate, and fail with the
// SEC_ERROR_BAD_SIGNATURE error (NSS bug 524013), so we also retry with
// cert_pi_useAIACertFetch on SEC_ERROR_BAD_SIGNATURE.
- if (cert_io_enabled &&
- (nss_error == SEC_ERROR_UNKNOWN_ISSUER ||
+ if ((nss_error == SEC_ERROR_UNKNOWN_ISSUER ||
nss_error == SEC_ERROR_BAD_SIGNATURE)) {
DCHECK_EQ(cvin->back().type, cert_pi_end);
cvin->pop_back();
@@ -755,7 +754,6 @@ bool VerifyEV(CERTCertificate* cert_handle,
cert_handle,
rev_checking_enabled,
true, /* hard fail is implied in EV. */
- flags & CertVerifier::VERIFY_CERT_IO_ENABLED,
&ev_policy_oid,
1,
additional_trust_anchors,
@@ -828,6 +826,9 @@ int CertVerifyProcNSS::VerifyInternalImpl(
const CertificateList& additional_trust_anchors,
CERTChainVerifyCallback* chain_verify_callback,
CertVerifyResult* verify_result) {
+ crypto::EnsureNSSInit();
+ EnsureNSSHttpIOInit();
+
// Convert the whole input chain into NSS certificates. Even though only the
// target cert is explicitly referred to in this function, creating NSS
// certificates for the intermediates is required for PKIXVerifyCert to find
@@ -893,11 +894,8 @@ int CertVerifyProcNSS::VerifyInternalImpl(
EVRootCAMetadata* metadata = EVRootCAMetadata::GetInstance();
SECOidTag ev_policy_oid = SEC_OID_UNKNOWN;
bool is_ev_candidate =
- (flags & CertVerifier::VERIFY_EV_CERT) &&
IsEVCandidate(metadata, cert_handle, &ev_policy_oid);
- bool cert_io_enabled = flags & CertVerifier::VERIFY_CERT_IO_ENABLED;
bool check_revocation =
- cert_io_enabled &&
(flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED);
if (check_revocation)
verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
@@ -909,8 +907,8 @@ int CertVerifyProcNSS::VerifyInternalImpl(
}
SECStatus status =
- PKIXVerifyCert(cert_handle, check_revocation, false, cert_io_enabled,
- NULL, 0, trust_anchors.get(), &crlset_callback, cvout);
+ PKIXVerifyCert(cert_handle, check_revocation, false, NULL, 0,
+ trust_anchors.get(), &crlset_callback, cvout);
bool known_root = false;
HashValueVector hashes;
@@ -929,7 +927,7 @@ int CertVerifyProcNSS::VerifyInternalImpl(
// NSS tests for that feature.
scoped_cvout.Clear();
verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
- status = PKIXVerifyCert(cert_handle, true, true, cert_io_enabled, NULL, 0,
+ status = PKIXVerifyCert(cert_handle, true, true, NULL, 0,
trust_anchors.get(), &crlset_callback, cvout);
if (status == SECSuccess) {
AppendPublicKeyHashesAndTestKnownRoot(
@@ -998,11 +996,8 @@ int CertVerifyProcNSS::VerifyInternalImpl(
if (IsCertStatusError(verify_result->cert_status))
return MapCertStatusToNetError(verify_result->cert_status);
- if ((flags & CertVerifier::VERIFY_EV_CERT) && is_ev_candidate) {
- check_revocation |=
- crl_set_result != kCRLSetOk &&
- cert_io_enabled &&
- (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY);
+ if (is_ev_candidate) {
+ check_revocation |= crl_set_result != kCRLSetOk;
if (check_revocation)
verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
diff --git a/chromium/net/cert/cert_verify_proc_unittest.cc b/chromium/net/cert/cert_verify_proc_unittest.cc
index 74fe7c97674..b31eb2c420f 100644
--- a/chromium/net/cert/cert_verify_proc_unittest.cc
+++ b/chromium/net/cert/cert_verify_proc_unittest.cc
@@ -67,6 +67,8 @@ const char kTLSFeatureExtensionHistogram[] =
const char kTLSFeatureExtensionOCSPHistogram[] =
"Net.Certificate.TLSFeatureExtensionWithPrivateRootHasOCSP";
const char kTrustAnchorVerifyHistogram[] = "Net.Certificate.TrustAnchor.Verify";
+const char kTrustAnchorVerifyOutOfDateHistogram[] =
+ "Net.Certificate.TrustAnchor.VerifyOutOfDate";
// Mock CertVerifyProc that sets the CertVerifyResult to a given value for
// all certificates that are Verify()'d
@@ -236,10 +238,12 @@ class CertVerifyProcInternalTest
bool SupportsReturningVerifiedChain() const {
#if defined(OS_ANDROID)
- // Before API level 17, Android does not expose the APIs necessary to get at
- // the verified certificate chain.
+ // Before API level 17 (SDK_VERSION_JELLY_BEAN_MR1), Android does
+ // not expose the APIs necessary to get at the verified
+ // certificate chain.
if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID &&
- base::android::BuildInfo::GetInstance()->sdk_int() < 17)
+ base::android::BuildInfo::GetInstance()->sdk_int() <
+ base::android::SDK_VERSION_JELLY_BEAN_MR1)
return false;
#endif
return true;
@@ -247,10 +251,12 @@ class CertVerifyProcInternalTest
bool SupportsDetectingKnownRoots() const {
#if defined(OS_ANDROID)
- // Before API level 17, Android does not expose the APIs necessary to get at
- // the verified certificate chain and detect known roots.
+ // Before API level 17 (SDK_VERSION_JELLY_BEAN_MR1), Android does not expose
+ // the APIs necessary to get at the verified certificate chain and detect
+ // known roots.
if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID)
- return base::android::BuildInfo::GetInstance()->sdk_int() >= 17;
+ return base::android::BuildInfo::GetInstance()->sdk_int() >=
+ base::android::SDK_VERSION_JELLY_BEAN_MR1;
#endif
// iOS does not expose the APIs necessary to get the known system roots.
@@ -344,7 +350,7 @@ TEST_P(CertVerifyProcInternalTest, EVVerificationMultipleOID) {
CRLSet::ForTesting(false, &spki_sha256, "", "", {}));
CertVerifyResult verify_result;
- int flags = CertVerifier::VERIFY_EV_CERT;
+ int flags = 0;
int error = Verify(chain.get(), "trustcenter.websecurity.symantec.com", flags,
crl_set.get(), CertificateList(), &verify_result);
EXPECT_THAT(error, IsOk());
@@ -366,7 +372,7 @@ TEST_P(CertVerifyProcInternalTest, TrustedTargetCertWithEVPolicy) {
ScopedTestRoot scoped_test_root(cert.get());
CertVerifyResult verify_result;
- int flags = CertVerifier::VERIFY_EV_CERT;
+ int flags = 0;
int error = Verify(cert.get(), "policy_test.example", flags,
nullptr /*crl_set*/, CertificateList(), &verify_result);
if (ScopedTestRootCanTrustTargetCert(verify_proc_type())) {
@@ -403,7 +409,7 @@ TEST_P(CertVerifyProcInternalTest,
ScopedTestRoot scoped_test_root(cert.get());
CertVerifyResult verify_result;
- int flags = CertVerifier::VERIFY_EV_CERT;
+ int flags = 0;
int error = Verify(cert.get(), "policy_test.example", flags,
nullptr /*crl_set*/, CertificateList(), &verify_result);
if (ScopedTestRootCanTrustTargetCert(verify_proc_type())) {
@@ -1237,6 +1243,7 @@ TEST(CertVerifyProcTest, TestHasTooLongValidity) {
{"825_days_after_2018_03_01.pem", false},
{"826_days_after_2018_03_01.pem", true},
{"825_days_1_second_after_2018_03_01.pem", true},
+ {"39_months_based_on_last_day.pem", false},
};
base::FilePath certs_dir = GetTestCertsDirectory();
@@ -2659,7 +2666,6 @@ TEST(CertVerifyProcTest, HasTrustAnchorVerifyUMA) {
int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags,
NULL, CertificateList(), &verify_result);
EXPECT_EQ(OK, error);
- histograms.ExpectTotalCount(kTrustAnchorVerifyHistogram, 1);
histograms.ExpectUniqueSample(kTrustAnchorVerifyHistogram,
kGTSRootR4HistogramID, 1);
}
@@ -2708,9 +2714,45 @@ TEST(CertVerifyProcTest, LogsOnlyMostSpecificTrustAnchorUMA) {
EXPECT_EQ(OK, error);
// Only GTS Root R3 should be recorded.
- histograms.ExpectTotalCount(kTrustAnchorVerifyHistogram, 1);
histograms.ExpectUniqueSample(kTrustAnchorVerifyHistogram,
kGTSRootR3HistogramID, 1);
}
+// Test that trust anchors histograms record whether or not
+// is_issued_by_known_root was derived from the OS.
+TEST(CertVerifyProcTest, HasTrustAnchorVerifyOutOfDateUMA) {
+ base::HistogramTester histograms;
+ scoped_refptr<X509Certificate> cert(ImportCertFromFile(
+ GetTestCertsDirectory(), "39_months_based_on_last_day.pem"));
+ ASSERT_TRUE(cert);
+
+ CertVerifyResult result;
+
+ // Simulate a certificate chain that is recognized as trusted (from a known
+ // root), but no certificates in the chain are tracked as known trust
+ // anchors.
+ SHA256HashValue leaf_hash = {{0}};
+ SHA256HashValue intermediate_hash = {{1}};
+ SHA256HashValue root_hash = {{2}};
+ result.public_key_hashes.push_back(HashValue(leaf_hash));
+ result.public_key_hashes.push_back(HashValue(intermediate_hash));
+ result.public_key_hashes.push_back(HashValue(root_hash));
+ result.is_issued_by_known_root = true;
+
+ scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result);
+
+ histograms.ExpectTotalCount(kTrustAnchorVerifyHistogram, 0);
+ histograms.ExpectTotalCount(kTrustAnchorVerifyOutOfDateHistogram, 0);
+
+ int flags = 0;
+ CertVerifyResult verify_result;
+ int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags,
+ NULL, CertificateList(), &verify_result);
+ EXPECT_EQ(OK, error);
+ const base::HistogramBase::Sample kUnknownRootHistogramID = 0;
+ histograms.ExpectUniqueSample(kTrustAnchorVerifyHistogram,
+ kUnknownRootHistogramID, 1);
+ histograms.ExpectUniqueSample(kTrustAnchorVerifyOutOfDateHistogram, true, 1);
+}
+
} // namespace net
diff --git a/chromium/net/cert/cert_verify_proc_win.cc b/chromium/net/cert/cert_verify_proc_win.cc
index 97770534481..505122bf5c0 100644
--- a/chromium/net/cert/cert_verify_proc_win.cc
+++ b/chromium/net/cert/cert_verify_proc_win.cc
@@ -623,7 +623,8 @@ class RevocationInjector {
RevocationInjector() {
const CRYPT_OID_FUNC_ENTRY kInterceptFunction[] = {
- {CRYPT_DEFAULT_OID, &CertDllVerifyRevocationWithCRLSet},
+ {CRYPT_DEFAULT_OID,
+ reinterpret_cast<void*>(&CertDllVerifyRevocationWithCRLSet)},
};
BOOL ok = CryptInstallOIDFunctionAddress(
NULL, X509_ASN_ENCODING, CRYPT_OID_VERIFY_REVOCATION_FUNC,
@@ -890,24 +891,22 @@ int CertVerifyProcWin::VerifyInternal(
// Get the certificatePolicies extension of the certificate.
std::unique_ptr<CERT_POLICIES_INFO, base::FreeDeleter> policies_info;
LPSTR ev_policy_oid = NULL;
- if (flags & CertVerifier::VERIFY_EV_CERT) {
- GetCertPoliciesInfo(cert_list.get(), &policies_info);
- if (policies_info.get()) {
- EVRootCAMetadata* metadata = EVRootCAMetadata::GetInstance();
- for (DWORD i = 0; i < policies_info->cPolicyInfo; ++i) {
- LPSTR policy_oid = policies_info->rgPolicyInfo[i].pszPolicyIdentifier;
- if (metadata->IsEVPolicyOID(policy_oid)) {
- ev_policy_oid = policy_oid;
- chain_para.RequestedIssuancePolicy.dwType = USAGE_MATCH_TYPE_AND;
- chain_para.RequestedIssuancePolicy.Usage.cUsageIdentifier = 1;
- chain_para.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier =
- &ev_policy_oid;
-
- // De-prioritize the CA/Browser forum Extended Validation policy
- // (2.23.140.1.1). See crbug.com/705285.
- if (!EVRootCAMetadata::IsCaBrowserForumEvOid(ev_policy_oid))
- break;
- }
+ GetCertPoliciesInfo(cert_list.get(), &policies_info);
+ if (policies_info) {
+ EVRootCAMetadata* metadata = EVRootCAMetadata::GetInstance();
+ for (DWORD i = 0; i < policies_info->cPolicyInfo; ++i) {
+ LPSTR policy_oid = policies_info->rgPolicyInfo[i].pszPolicyIdentifier;
+ if (metadata->IsEVPolicyOID(policy_oid)) {
+ ev_policy_oid = policy_oid;
+ chain_para.RequestedIssuancePolicy.dwType = USAGE_MATCH_TYPE_AND;
+ chain_para.RequestedIssuancePolicy.Usage.cUsageIdentifier = 1;
+ chain_para.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier =
+ &ev_policy_oid;
+
+ // De-prioritize the CA/Browser forum Extended Validation policy
+ // (2.23.140.1.1). See https://crbug.com/705285.
+ if (!EVRootCAMetadata::IsCaBrowserForumEvOid(ev_policy_oid))
+ break;
}
}
}
@@ -1030,10 +1029,8 @@ int CertVerifyProcWin::VerifyInternal(
if (crl_set_result == kCRLSetRevoked) {
verify_result->cert_status |= CERT_STATUS_REVOKED;
- } else if (crl_set_result == kCRLSetUnknown &&
- (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY) &&
- !rev_checking_enabled &&
- ev_policy_oid != NULL) {
+ } else if (crl_set_result == kCRLSetUnknown && !rev_checking_enabled &&
+ ev_policy_oid) {
// We don't have fresh information about this chain from the CRLSet and
// it's probably an EV certificate. Retry with online revocation checking.
rev_checking_enabled = true;
diff --git a/chromium/net/cert/cert_verify_result.cc b/chromium/net/cert/cert_verify_result.cc
index f77bf8f3fe1..7c4ecfa5d6f 100644
--- a/chromium/net/cert/cert_verify_result.cc
+++ b/chromium/net/cert/cert_verify_result.cc
@@ -35,7 +35,8 @@ void CertVerifyResult::Reset() {
bool CertVerifyResult::operator==(const CertVerifyResult& other) const {
return (!!verified_cert == !!other.verified_cert) &&
- (!verified_cert || verified_cert->Equals(other.verified_cert.get())) &&
+ (!verified_cert ||
+ verified_cert->EqualsIncludingChain(other.verified_cert.get())) &&
std::tie(cert_status, has_md2, has_md4, has_md5, has_sha1,
has_sha1_leaf, public_key_hashes, is_issued_by_known_root,
is_issued_by_additional_trust_anchor, ocsp_result) ==
diff --git a/chromium/net/cert/cert_verify_result.h b/chromium/net/cert/cert_verify_result.h
index 8d50fd29c58..c81257804ac 100644
--- a/chromium/net/cert/cert_verify_result.h
+++ b/chromium/net/cert/cert_verify_result.h
@@ -26,6 +26,8 @@ class NET_EXPORT CertVerifyResult {
void Reset();
+ // Returns true if all the members of |this| are equal to |other|'s (including
+ // the |verified_cert| intermediates).
bool operator==(const CertVerifyResult& other) const;
// The certificate chain that was constructed during verification.
diff --git a/chromium/net/cert/ct_known_logs.cc b/chromium/net/cert/ct_known_logs.cc
index a1e80c7f380..52340361e89 100644
--- a/chromium/net/cert/ct_known_logs.cc
+++ b/chromium/net/cert/ct_known_logs.cc
@@ -37,8 +37,8 @@ CreateLogVerifiersForKnownLogs() {
// Add all qualified logs.
for (const auto& log : kCTLogList) {
base::StringPiece key(log.log_key, log.log_key_length);
- verifiers.push_back(CTLogVerifier::Create(key, log.log_name, log.log_url,
- log.log_dns_domain));
+ verifiers.push_back(
+ CTLogVerifier::Create(key, log.log_name, log.log_dns_domain));
// Make sure no null logs enter verifiers. Parsing of all known logs should
// succeed.
CHECK(verifiers.back().get());
@@ -49,8 +49,8 @@ CreateLogVerifiersForKnownLogs() {
for (const auto& disqualified_log : kDisqualifiedCTLogList) {
const CTLogInfo& log = disqualified_log.log_info;
base::StringPiece key(log.log_key, log.log_key_length);
- verifiers.push_back(CTLogVerifier::Create(key, log.log_name, log.log_url,
- log.log_dns_domain));
+ verifiers.push_back(
+ CTLogVerifier::Create(key, log.log_name, log.log_dns_domain));
// Make sure no null logs enter verifiers. Parsing of all known logs should
// succeed.
CHECK(verifiers.back().get());
diff --git a/chromium/net/cert/ct_log_verifier.cc b/chromium/net/cert/ct_log_verifier.cc
index e017e360ca9..c6387fb76b0 100644
--- a/chromium/net/cert/ct_log_verifier.cc
+++ b/chromium/net/cert/ct_log_verifier.cc
@@ -60,28 +60,21 @@ const EVP_MD* GetEvpAlg(ct::DigitallySigned::HashAlgorithm alg) {
scoped_refptr<const CTLogVerifier> CTLogVerifier::Create(
const base::StringPiece& public_key,
const base::StringPiece& description,
- const base::StringPiece& url,
const base::StringPiece& dns_domain) {
- GURL log_url(url);
- if (!log_url.is_valid())
- return nullptr;
scoped_refptr<CTLogVerifier> result(
- new CTLogVerifier(description, log_url, dns_domain));
+ new CTLogVerifier(description, dns_domain));
if (!result->Init(public_key))
return nullptr;
return result;
}
CTLogVerifier::CTLogVerifier(const base::StringPiece& description,
- const GURL& url,
const base::StringPiece& dns_domain)
: description_(description.as_string()),
- url_(url),
dns_domain_(dns_domain.as_string()),
hash_algorithm_(ct::DigitallySigned::HASH_ALGO_NONE),
signature_algorithm_(ct::DigitallySigned::SIG_ALGO_ANONYMOUS),
public_key_(NULL) {
- DCHECK(url_.is_valid());
DCHECK(!dns_domain_.empty());
}
diff --git a/chromium/net/cert/ct_log_verifier.h b/chromium/net/cert/ct_log_verifier.h
index 7c03581b167..d28bccec530 100644
--- a/chromium/net/cert/ct_log_verifier.h
+++ b/chromium/net/cert/ct_log_verifier.h
@@ -12,7 +12,6 @@
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
#include "net/cert/signed_certificate_timestamp.h"
-#include "url/gurl.h"
// Forward declare the crypto types to avoid having to include the full
// headers.
@@ -44,15 +43,12 @@ class NET_EXPORT CTLogVerifier
static scoped_refptr<const CTLogVerifier> Create(
const base::StringPiece& public_key,
const base::StringPiece& description,
- const base::StringPiece& url,
const base::StringPiece& dns_domain);
// Returns the log's key ID (RFC6962, Section 3.2)
const std::string& key_id() const { return key_id_; }
// Returns the log's human-readable description.
const std::string& description() const { return description_; }
- // Returns the log's URL
- const GURL& url() const { return url_; }
// Returns the log's DNS domain for CT over DNS queries, as described in
// https://github.com/google/certificate-transparency-rfcs/blob/master/dns/draft-ct-over-dns.md.
@@ -88,7 +84,6 @@ class NET_EXPORT CTLogVerifier
friend class base::RefCountedThreadSafe<CTLogVerifier>;
CTLogVerifier(const base::StringPiece& description,
- const GURL& url,
const base::StringPiece& dns_domain);
~CTLogVerifier();
@@ -107,7 +102,6 @@ class NET_EXPORT CTLogVerifier
std::string key_id_;
std::string description_;
- GURL url_;
std::string dns_domain_;
ct::DigitallySigned::HashAlgorithm hash_algorithm_;
ct::DigitallySigned::SignatureAlgorithm signature_algorithm_;
diff --git a/chromium/net/cert/ct_log_verifier_unittest.cc b/chromium/net/cert/ct_log_verifier_unittest.cc
index 4ec13ff886c..56c06d0d2be 100644
--- a/chromium/net/cert/ct_log_verifier_unittest.cc
+++ b/chromium/net/cert/ct_log_verifier_unittest.cc
@@ -204,7 +204,7 @@ class CTLogVerifierTest : public ::testing::Test {
public:
void SetUp() override {
log_ = CTLogVerifier::Create(ct::GetTestPublicKey(), "testlog",
- "https://ct.example.com", "ct.example.com");
+ "ct.example.com");
ASSERT_TRUE(log_);
EXPECT_EQ(ct::GetTestPublicKeyId(), log_->key_id());
@@ -465,8 +465,8 @@ TEST_F(CTLogVerifierTest, ExcessDataInPublicKey) {
std::string key = ct::GetTestPublicKey();
key += "extra";
- scoped_refptr<const CTLogVerifier> log = CTLogVerifier::Create(
- key, "testlog", "https://ct.example.com", "ct.example.com");
+ scoped_refptr<const CTLogVerifier> log =
+ CTLogVerifier::Create(key, "testlog", "ct.example.com");
EXPECT_FALSE(log);
}
diff --git a/chromium/net/cert/ct_objects_extractor_unittest.cc b/chromium/net/cert/ct_objects_extractor_unittest.cc
index 8152d023191..ce1a7284761 100644
--- a/chromium/net/cert/ct_objects_extractor_unittest.cc
+++ b/chromium/net/cert/ct_objects_extractor_unittest.cc
@@ -33,7 +33,7 @@ class CTObjectsExtractorTest : public ::testing::Test {
ASSERT_TRUE(test_cert_);
log_ = CTLogVerifier::Create(ct::GetTestPublicKey(), "testlog",
- "https://ct.example.com", "dns.example.com");
+ "dns.example.com");
ASSERT_TRUE(log_);
}
diff --git a/chromium/net/cert/ct_policy_enforcer_unittest.cc b/chromium/net/cert/ct_policy_enforcer_unittest.cc
index d39017f2f82..906cfc9cbb8 100644
--- a/chromium/net/cert/ct_policy_enforcer_unittest.cc
+++ b/chromium/net/cert/ct_policy_enforcer_unittest.cc
@@ -431,7 +431,7 @@ TEST_F(CTPolicyEnforcerTest,
// Create a self-signed certificate with exactly the validity period.
std::string cert_data;
ASSERT_TRUE(x509_util::CreateSelfSignedCert(
- private_key.get(), x509_util::DIGEST_SHA256, "CN=test",
+ private_key->key(), x509_util::DIGEST_SHA256, "CN=test",
i * 10 + required_scts, start, end, &cert_data));
scoped_refptr<X509Certificate> cert(
X509Certificate::CreateFromBytes(cert_data.data(), cert_data.size()));
diff --git a/chromium/net/cert/internal/name_constraints.h b/chromium/net/cert/internal/name_constraints.h
index c156dd6b297..e131d42b302 100644
--- a/chromium/net/cert/internal/name_constraints.h
+++ b/chromium/net/cert/internal/name_constraints.h
@@ -83,6 +83,9 @@ class NET_EXPORT NameConstraints {
// either process the constraint or reject the certificate.
int constrained_name_types() const { return constrained_name_types_; }
+ const GeneralNames& permitted_subtrees() const { return permitted_subtrees_; }
+ const GeneralNames& excluded_subtrees() const { return excluded_subtrees_; }
+
private:
bool Parse(const der::Input& extension_value,
bool is_critical,
diff --git a/chromium/net/cert/known_roots.cc b/chromium/net/cert/known_roots.cc
index 1a59ec5dde5..fa376cd615c 100644
--- a/chromium/net/cert/known_roots.cc
+++ b/chromium/net/cert/known_roots.cc
@@ -29,18 +29,31 @@ struct HashValueToRootCertDataComp {
}
};
+const RootCertData* GetRootCertData(const HashValue& spki_hash) {
+ if (spki_hash.tag() != HASH_VALUE_SHA256)
+ return nullptr;
+
+ auto* it = std::lower_bound(std::begin(kRootCerts), std::end(kRootCerts),
+ spki_hash, HashValueToRootCertDataComp());
+ if (it == std::end(kRootCerts) ||
+ HashValueToRootCertDataComp()(spki_hash, *it)) {
+ return nullptr;
+ }
+ return it;
+}
+
} // namespace
int32_t GetNetTrustAnchorHistogramIdForSPKI(const HashValue& spki_hash) {
- if (spki_hash.tag() != HASH_VALUE_SHA256)
+ const RootCertData* root_data = GetRootCertData(spki_hash);
+ if (!root_data)
return 0;
+ return root_data->histogram_id;
+}
- auto* it = std::lower_bound(std::begin(kRootCerts), std::end(kRootCerts),
- spki_hash, HashValueToRootCertDataComp());
- return (it != std::end(kRootCerts) &&
- !HashValueToRootCertDataComp()(spki_hash, *it))
- ? it->histogram_id
- : 0;
+bool IsLegacyPubliclyTrustedCA(const HashValue& spki_hash) {
+ const RootCertData* root_data = GetRootCertData(spki_hash);
+ return root_data && root_data->legacy_ca;
}
} // namespace net
diff --git a/chromium/net/cert/known_roots.h b/chromium/net/cert/known_roots.h
index 826660fa70a..d3bdbcd1a0f 100644
--- a/chromium/net/cert/known_roots.h
+++ b/chromium/net/cert/known_roots.h
@@ -20,6 +20,13 @@ class HashValue;
NET_EXPORT int32_t
GetNetTrustAnchorHistogramIdForSPKI(const HashValue& spki_hash);
+// Returns true if the CA identified by |spki_hash| is known as a Legacy CA,
+// which means that they are known as a well-known root, but are not trusted
+// on the ChromiumOS or Android platforms. This indicates a CA that either has
+// been removed from public trust (generally, voluntarily) or has not (or not
+// yet) undergone a public review and discussion for broad public trust.
+NET_EXPORT bool IsLegacyPubliclyTrustedCA(const HashValue& spki_hash);
+
} // namespace net
#endif // NET_CERT_KNOWN_ROOTS_H_
diff --git a/chromium/net/cert/multi_log_ct_verifier_unittest.cc b/chromium/net/cert/multi_log_ct_verifier_unittest.cc
index e12a567d314..d4736cf07ae 100644
--- a/chromium/net/cert/multi_log_ct_verifier_unittest.cc
+++ b/chromium/net/cert/multi_log_ct_verifier_unittest.cc
@@ -54,9 +54,8 @@ class MockSCTObserver : public CTVerifier::Observer {
class MultiLogCTVerifierTest : public ::testing::Test {
public:
void SetUp() override {
- scoped_refptr<const CTLogVerifier> log(
- CTLogVerifier::Create(ct::GetTestPublicKey(), kLogDescription,
- "https://ct.example.com", "dns.example.com"));
+ scoped_refptr<const CTLogVerifier> log(CTLogVerifier::Create(
+ ct::GetTestPublicKey(), kLogDescription, "dns.example.com"));
ASSERT_TRUE(log);
log_verifiers_.push_back(log);
diff --git a/chromium/net/cert/multi_threaded_cert_verifier.cc b/chromium/net/cert/multi_threaded_cert_verifier.cc
index 9b4437c70a0..dd866a933cc 100644
--- a/chromium/net/cert/multi_threaded_cert_verifier.cc
+++ b/chromium/net/cert/multi_threaded_cert_verifier.cc
@@ -12,6 +12,7 @@
#include "base/callback_helpers.h"
#include "base/compiler_specific.h"
#include "base/containers/linked_list.h"
+#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram_macros.h"
#include "base/sha1.h"
@@ -233,7 +234,7 @@ class CertVerifierJob {
key_.hostname(), key_.ocsp_response(), key_.flags(),
crl_set, key_.additional_trust_anchors()),
base::BindOnce(&CertVerifierJob::OnJobCompleted,
- weak_ptr_factory_.GetWeakPtr()));
+ weak_ptr_factory_.GetWeakPtr(), crl_set));
}
~CertVerifierJob() {
@@ -277,26 +278,32 @@ class CertVerifierJob {
NetLogEventType::CERT_VERIFIER_JOB,
base::Bind(&CertVerifyResultCallback, verify_result.result));
base::TimeDelta latency = base::TimeTicks::Now() - start_time_;
- UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertVerifier_Job_Latency",
- latency,
- base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromMinutes(10),
- 100);
- if (is_first_job_) {
- UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertVerifier_First_Job_Latency",
- latency,
+ if (cert_verifier_->should_record_histograms_) {
+ UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertVerifier_Job_Latency", latency,
base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromMinutes(10),
- 100);
+ base::TimeDelta::FromMinutes(10), 100);
+ if (is_first_job_) {
+ UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertVerifier_First_Job_Latency",
+ latency,
+ base::TimeDelta::FromMilliseconds(1),
+ base::TimeDelta::FromMinutes(10), 100);
+ }
}
}
- void OnJobCompleted(std::unique_ptr<ResultHelper> verify_result) {
+ void OnJobCompleted(scoped_refptr<CRLSet> crl_set,
+ std::unique_ptr<ResultHelper> verify_result) {
TRACE_EVENT0(kNetTracingCategory, "CertVerifierJob::OnJobCompleted");
std::unique_ptr<CertVerifierJob> keep_alive =
cert_verifier_->RemoveJob(this);
LogMetrics(*verify_result);
+ if (cert_verifier_->verify_complete_callback_) {
+ cert_verifier_->verify_complete_callback_.Run(
+ key_, std::move(crl_set), net_log_, verify_result->error,
+ verify_result->result, base::TimeTicks::Now() - start_time_,
+ is_first_job_);
+ }
cert_verifier_ = nullptr;
// TODO(eroman): If the cert_verifier_ is deleted from within one of the
@@ -331,6 +338,17 @@ MultiThreadedCertVerifier::~MultiThreadedCertVerifier() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
}
+// static
+std::unique_ptr<MultiThreadedCertVerifier>
+MultiThreadedCertVerifier::CreateForDualVerificationTrial(
+ scoped_refptr<CertVerifyProc> verify_proc,
+ VerifyCompleteCallback verify_complete_callback,
+ bool should_record_histograms) {
+ return base::WrapUnique(new net::MultiThreadedCertVerifier(
+ std::move(verify_proc), std::move(verify_complete_callback),
+ should_record_histograms));
+}
+
int MultiThreadedCertVerifier::Verify(const RequestParams& params,
CRLSet* crl_set,
CertVerifyResult* verify_result,
@@ -382,6 +400,16 @@ bool MultiThreadedCertVerifier::JobComparator::operator()(
return job1->key() < job2->key();
}
+MultiThreadedCertVerifier::MultiThreadedCertVerifier(
+ scoped_refptr<CertVerifyProc> verify_proc,
+ VerifyCompleteCallback verify_complete_callback,
+ bool should_record_histograms)
+ : requests_(0),
+ inflight_joins_(0),
+ verify_proc_(verify_proc),
+ verify_complete_callback_(std::move(verify_complete_callback)),
+ should_record_histograms_(should_record_histograms) {}
+
std::unique_ptr<CertVerifierJob> MultiThreadedCertVerifier::RemoveJob(
CertVerifierJob* job) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
diff --git a/chromium/net/cert/multi_threaded_cert_verifier.h b/chromium/net/cert/multi_threaded_cert_verifier.h
index 9787fc88173..9dc93fe434e 100644
--- a/chromium/net/cert/multi_threaded_cert_verifier.h
+++ b/chromium/net/cert/multi_threaded_cert_verifier.h
@@ -31,12 +31,35 @@ class CertVerifyProc;
// synchronous CertVerifier implementations on worker threads.
class NET_EXPORT_PRIVATE MultiThreadedCertVerifier : public CertVerifier {
public:
+ using VerifyCompleteCallback =
+ base::RepeatingCallback<void(const RequestParams&,
+ scoped_refptr<CRLSet> crl_set,
+ const NetLogWithSource&,
+ int,
+ const CertVerifyResult&,
+ base::TimeDelta,
+ bool)>;
+
explicit MultiThreadedCertVerifier(scoped_refptr<CertVerifyProc> verify_proc);
// When the verifier is destroyed, all certificate verifications requests are
// canceled, and their completion callbacks will not be called.
~MultiThreadedCertVerifier() override;
+ // Creates a MultiThreadedCertVerifier that will call
+ // |verify_complete_callback| once for each verification that has completed
+ // (if it is non-null). Histograms will have |histogram_suffix| appended, if
+ // it is non-empty.
+ // This factory method is temporary, and should not be used without
+ // consulting with OWNERS.
+ // TODO(mattm): remove this once the dual verification trial is complete.
+ // (See https://crbug.com/649026.)
+ static std::unique_ptr<MultiThreadedCertVerifier>
+ CreateForDualVerificationTrial(
+ scoped_refptr<CertVerifyProc> verify_proc,
+ VerifyCompleteCallback verify_complete_callback,
+ bool should_record_histograms);
+
// CertVerifier implementation
int Verify(const RequestParams& params,
CRLSet* crl_set,
@@ -61,6 +84,12 @@ class NET_EXPORT_PRIVATE MultiThreadedCertVerifier : public CertVerifier {
const CertVerifierJob* job2) const;
};
+ // TODO(mattm): remove this once the dual verification trial is complete.
+ // (See https://crbug.com/649026.)
+ MultiThreadedCertVerifier(scoped_refptr<CertVerifyProc> verify_proc,
+ VerifyCompleteCallback verify_complete_callback,
+ bool should_record_histograms);
+
// Returns an inflight job for |key|. If there is no such job then returns
// null.
CertVerifierJob* FindJob(const RequestParams& key);
@@ -85,6 +114,11 @@ class NET_EXPORT_PRIVATE MultiThreadedCertVerifier : public CertVerifier {
scoped_refptr<CertVerifyProc> verify_proc_;
+ // Members for dual verification trial. TODO(mattm): Remove these.
+ // (See https://crbug.com/649026.)
+ VerifyCompleteCallback verify_complete_callback_;
+ bool should_record_histograms_ = true;
+
THREAD_CHECKER(thread_checker_);
DISALLOW_COPY_AND_ASSIGN(MultiThreadedCertVerifier);
diff --git a/chromium/net/cert/nss_cert_database.cc b/chromium/net/cert/nss_cert_database.cc
index a36d647e3b4..77a643309fa 100644
--- a/chromium/net/cert/nss_cert_database.cc
+++ b/chromium/net/cert/nss_cert_database.cc
@@ -74,7 +74,6 @@ NSSCertDatabase::NSSCertDatabase(crypto::ScopedPK11Slot public_slot,
weak_factory_(this) {
CHECK(public_slot_);
- // This also makes sure that NSS has been initialized.
CertDatabase* cert_db = CertDatabase::GetInstance();
cert_notification_forwarder_.reset(new CertNotificationForwarder(cert_db));
AddObserver(cert_notification_forwarder_.get());
diff --git a/chromium/net/cert/nss_cert_database_unittest.cc b/chromium/net/cert/nss_cert_database_unittest.cc
index 7781ea4fd5f..5c1ebab00e2 100644
--- a/chromium/net/cert/nss_cert_database_unittest.cc
+++ b/chromium/net/cert/nss_cert_database_unittest.cc
@@ -124,7 +124,10 @@ class CertDatabaseNSSTest : public testing::Test {
}
std::unique_ptr<NSSCertDatabase> cert_db_;
- const CertificateList empty_cert_list_;
+ // When building with libstdc++, |empty_cert_list_| does not have a default
+ // constructor. Initialize it explicitly so that CertDatabaseNSSTest gets a
+ // default constructor.
+ const CertificateList empty_cert_list_ = CertificateList();
crypto::ScopedTestNSSDB test_nssdb_;
crypto::ScopedPK11Slot public_slot_;
};
diff --git a/chromium/net/cert/root_cert_list_generated.h b/chromium/net/cert/root_cert_list_generated.h
index 26c4b55a786..58aebc26f28 100644
--- a/chromium/net/cert/root_cert_list_generated.h
+++ b/chromium/net/cert/root_cert_list_generated.h
@@ -23,2950 +23,3457 @@ const struct RootCertData {
// The SHA-256 hash of the associated certificate's subjectPublicKeyInfo.
unsigned char sha256_spki_hash[32];
- // A value suitable for histograms using the NetTrustAnchors enum. The value
- // 0 is reserved (not used), for use as a sentinel value.
- int16_t histogram_id;
+ // A value suitable for histograms using the NetTrustAnchors enum.
+ int16_t histogram_id : 15;
+
+ // If true, indicates the CA is considered a "Legacy" CA, formerly trusted
+ // or not yet trusted.
+ bool legacy_ca : 1;
} kRootCerts[] = {
{{
0x00, 0x41, 0x24, 0xAD, 0x60, 0x37, 0xFD, 0x5F, 0x33, 0x19, 0xE7,
0xA2, 0x3D, 0x4D, 0x9C, 0x81, 0x1F, 0x55, 0x98, 0xD6, 0x6C, 0x47,
0x54, 0x15, 0x5B, 0x0A, 0xAA, 0x9E, 0x8F, 0x00, 0x62, 0x1F,
},
- 357},
+ 357,
+ true},
{{
0x00, 0x6C, 0xB2, 0x26, 0xA7, 0x72, 0xC7, 0x18, 0x2D, 0x77, 0x72,
0x38, 0x3E, 0x37, 0x3F, 0x0F, 0x22, 0x9E, 0x7D, 0xFE, 0x34, 0x44,
0x81, 0x0A, 0x8D, 0x6E, 0x50, 0x90, 0x5D, 0x20, 0xD6, 0x61,
},
- 251},
+ 251,
+ true},
{{
0x00, 0x6D, 0x7B, 0xE7, 0x55, 0x5D, 0xD8, 0x20, 0x26, 0x44, 0x2C,
0x4F, 0x1A, 0x27, 0xA8, 0x0E, 0x89, 0xA1, 0x98, 0x9C, 0xB8, 0x7B,
0x34, 0x44, 0x8E, 0xD2, 0x19, 0x4C, 0x18, 0x19, 0x6D, 0x5E,
},
- 55},
+ 55,
+ false},
{{
0x01, 0xD0, 0xD8, 0xE0, 0x7B, 0xC5, 0xA9, 0x2D, 0xA7, 0xE7, 0xB8,
0x1E, 0x9A, 0x56, 0x9F, 0xE3, 0xA2, 0xD6, 0x3A, 0x99, 0x7D, 0xAC,
0x59, 0x60, 0x02, 0xC5, 0xDC, 0x81, 0x0C, 0xAD, 0x17, 0xBD,
},
- 283},
+ 283,
+ true},
{{
0x02, 0x06, 0xEA, 0xD1, 0x63, 0xB1, 0x0E, 0xA2, 0xF8, 0x62, 0x08,
0x68, 0xEB, 0xD7, 0xA1, 0x5F, 0x64, 0xA2, 0x02, 0x50, 0xD1, 0x6C,
0xD5, 0x7D, 0x6E, 0x87, 0xC4, 0xFF, 0xF1, 0xA2, 0x19, 0x7C,
},
- 456},
+ 456,
+ true},
{{
0x02, 0x37, 0x6D, 0x09, 0x08, 0xAC, 0x23, 0x04, 0x1C, 0xC7, 0xD6,
0x66, 0xD9, 0xDA, 0xF1, 0x92, 0x55, 0x4F, 0x7F, 0xC3, 0x63, 0x17,
0xAA, 0x9C, 0xB8, 0x00, 0x90, 0x86, 0x16, 0xB2, 0x8A, 0xF8,
},
- 411},
+ 411,
+ true},
{{
0x02, 0x3C, 0x81, 0xCC, 0xE8, 0xE7, 0xC6, 0x4F, 0xA9, 0x42, 0xD3,
0xC1, 0x50, 0x48, 0x70, 0x7D, 0x35, 0xD9, 0xBB, 0x5B, 0x87, 0xF4,
0xF5, 0x44, 0xC5, 0xBF, 0x1B, 0xC5, 0x64, 0x3A, 0xF2, 0xFA,
},
- 69},
+ 69,
+ true},
{{
0x04, 0xA6, 0xEA, 0x65, 0x4B, 0x23, 0x65, 0x89, 0x73, 0xC9, 0x81,
0x98, 0xC6, 0x4A, 0x3A, 0x69, 0x1C, 0x0D, 0xA7, 0x2E, 0xBE, 0xBD,
0x9A, 0xEB, 0xF7, 0x53, 0x24, 0xCD, 0xE6, 0x96, 0x0E, 0xAA,
},
- 157},
+ 157,
+ true},
{{
0x05, 0x1C, 0xF9, 0xFA, 0x95, 0xE4, 0x0E, 0x9B, 0x83, 0xED, 0xAE,
0xDA, 0x69, 0x61, 0xF6, 0x16, 0x8C, 0x78, 0x79, 0xC4, 0x66, 0x01,
0x72, 0x47, 0x9C, 0xDD, 0x51, 0xAB, 0x03, 0xCE, 0xA6, 0x2B,
},
- 73},
+ 73,
+ false},
{{
0x05, 0x2B, 0x68, 0x71, 0x07, 0xEC, 0x84, 0xE8, 0x73, 0x03, 0x82,
0x45, 0x2E, 0xC2, 0xA2, 0x74, 0x51, 0x74, 0x5D, 0x74, 0x85, 0xA5,
0x7D, 0x6F, 0x46, 0x4E, 0x0D, 0xA7, 0xA1, 0xB6, 0xAF, 0x2A,
},
- 136},
+ 136,
+ true},
{{
0x05, 0x57, 0x0A, 0xE6, 0xEB, 0x0F, 0xCE, 0xB4, 0x21, 0x0E, 0x6D,
0xB7, 0x94, 0x86, 0xB7, 0x09, 0x4C, 0xAF, 0x20, 0x04, 0x01, 0xE1,
0x49, 0xB6, 0x67, 0x74, 0x41, 0xB5, 0xF2, 0x5E, 0x44, 0x9B,
},
- 36},
+ 36,
+ false},
{{
0x05, 0xE7, 0x7E, 0xF1, 0xFD, 0xFE, 0x05, 0xE2, 0xDC, 0xA5, 0x22,
0xCA, 0xE6, 0x4D, 0x83, 0x79, 0xA0, 0x41, 0xB7, 0xB4, 0xF1, 0x6C,
0x7C, 0xAE, 0x36, 0x06, 0x7A, 0x7F, 0x72, 0xA1, 0x48, 0x72,
},
- 37},
+ 37,
+ false},
{{
0x05, 0xEC, 0x08, 0x97, 0xB2, 0x19, 0x95, 0xA4, 0xA9, 0x89, 0x9F,
0x8F, 0xCB, 0x06, 0x60, 0x1A, 0xDE, 0x61, 0xC0, 0x43, 0x89, 0x96,
0x9D, 0x13, 0x8F, 0xE3, 0x2C, 0xD6, 0xCF, 0xC7, 0x46, 0xAB,
},
- 309},
+ 309,
+ true},
{{
0x06, 0x56, 0xF5, 0x95, 0x52, 0x04, 0xC8, 0xD2, 0xBC, 0x8B, 0x1C,
0xA4, 0x75, 0xE2, 0xA4, 0xFA, 0x6E, 0x12, 0x4D, 0x12, 0x45, 0x12,
0x78, 0x41, 0x57, 0xC8, 0x58, 0xB5, 0x54, 0x71, 0x14, 0x1A,
},
- 78},
+ 78,
+ true},
{{
0x06, 0xC7, 0xBD, 0x95, 0x53, 0xF7, 0x10, 0xE0, 0x58, 0xEB, 0x27,
0xB1, 0x5D, 0x47, 0xDD, 0x62, 0xD7, 0xFD, 0x43, 0x52, 0xD9, 0x1D,
0xA9, 0x6E, 0x1E, 0xFC, 0x50, 0xE1, 0x53, 0x54, 0xB8, 0xD7,
},
- 302},
+ 302,
+ true},
{{
0x07, 0xE8, 0x54, 0xF2, 0x6A, 0x7C, 0xBD, 0x38, 0x99, 0x27, 0xAA,
0x04, 0x1B, 0xFE, 0xF1, 0xB6, 0xCD, 0x21, 0xDD, 0x14, 0x38, 0x18,
0xAD, 0x94, 0x7D, 0xC6, 0x55, 0xA9, 0xE5, 0x87, 0xFE, 0x88,
},
- 190},
+ 190,
+ false},
{{
0x08, 0x6D, 0xCD, 0x7B, 0xCF, 0x86, 0x4A, 0xAA, 0xD5, 0xEF, 0x8C,
0x1C, 0x57, 0x7B, 0xB6, 0x8A, 0x13, 0x1E, 0x05, 0x5C, 0x93, 0xF6,
0x3B, 0x9C, 0x47, 0xEE, 0x26, 0xEE, 0xF1, 0x5B, 0xE7, 0xAB,
},
- 338},
+ 338,
+ true},
{{
0x08, 0xB3, 0xA6, 0x33, 0x5F, 0xCE, 0x5E, 0xF4, 0x8F, 0x8F, 0x0E,
0x54, 0x39, 0x86, 0xC0, 0x7F, 0xD1, 0x8A, 0x3B, 0x12, 0x26, 0x12,
0x9F, 0x61, 0x86, 0x4B, 0xBD, 0x5B, 0xDD, 0x1F, 0x1C, 0xC9,
},
- 180},
+ 180,
+ false},
{{
0x09, 0x3D, 0xB7, 0x67, 0x88, 0x8F, 0x6B, 0x13, 0x27, 0x55, 0x5D,
0xBD, 0x42, 0xBB, 0x5C, 0x93, 0xFE, 0xDE, 0xC5, 0x04, 0x4C, 0x7A,
0x84, 0xBC, 0x6E, 0xA3, 0x2A, 0x57, 0x8C, 0x22, 0x35, 0xC0,
},
- 114},
+ 114,
+ true},
{{
0x09, 0x99, 0xBF, 0x90, 0x0B, 0xD5, 0xC2, 0x97, 0x86, 0x5E, 0x21,
0xE1, 0xAA, 0xDE, 0x6C, 0xF6, 0xBB, 0x3A, 0x94, 0xD1, 0x1A, 0xE5,
0xEA, 0x79, 0x84, 0x42, 0xA4, 0xE2, 0xF8, 0x13, 0x24, 0x1F,
},
- 329},
+ 329,
+ true},
{{
0x0B, 0x9F, 0xA5, 0xA5, 0x9E, 0xED, 0x71, 0x5C, 0x26, 0xC1, 0x02,
0x0C, 0x71, 0x1B, 0x4F, 0x6E, 0xC4, 0x2D, 0x58, 0xB0, 0x01, 0x5E,
0x14, 0x33, 0x7A, 0x39, 0xDA, 0xD3, 0x01, 0xC5, 0xAF, 0xC3,
},
- 200},
+ 200,
+ false},
{{
0x0B, 0xDD, 0x5A, 0xBE, 0x94, 0x0C, 0xAA, 0xAB, 0xE8, 0xB2, 0xBB,
0xA8, 0x83, 0x48, 0xFB, 0x6F, 0x4A, 0xA4, 0xCC, 0x84, 0x43, 0x6F,
0x88, 0x0B, 0xEC, 0xE6, 0x6B, 0x48, 0xBD, 0xA9, 0x13, 0xD8,
},
- 250},
+ 250,
+ true},
{{
0x0C, 0x7A, 0xCA, 0xA7, 0x10, 0x22, 0x67, 0x20, 0xBB, 0xC9, 0x40,
0x34, 0x9E, 0xE2, 0xE6, 0x14, 0x86, 0x52, 0xA8, 0x9D, 0xBF, 0x40,
0x6A, 0x23, 0x2C, 0x89, 0x5F, 0x6D, 0xC7, 0x8E, 0xBB, 0x9A,
},
- 91},
+ 91,
+ false},
{{
0x0D, 0x47, 0xE9, 0x85, 0x88, 0x45, 0x2C, 0xF0, 0x77, 0x8A, 0xF6,
0xAF, 0x03, 0xD4, 0x42, 0x72, 0x1D, 0xC0, 0x83, 0x66, 0x0A, 0x4B,
0xB2, 0x3C, 0x69, 0x74, 0x41, 0xFE, 0x2B, 0xB8, 0x4F, 0x9B,
},
- 314},
+ 314,
+ true},
{{
0x0F, 0x9C, 0x12, 0x99, 0x55, 0x75, 0x98, 0xCF, 0x75, 0x21, 0xBC,
0xC8, 0x79, 0x84, 0x20, 0xA1, 0x55, 0xCE, 0xC1, 0xBB, 0x23, 0xA5,
0x7A, 0xC3, 0x7F, 0x51, 0x20, 0xFC, 0x9A, 0x20, 0x57, 0xF8,
},
- 433},
+ 433,
+ true},
{{
0x0F, 0xE1, 0x4C, 0x26, 0x4B, 0x17, 0xBB, 0x6F, 0x0D, 0x65, 0x3E,
0x7A, 0x70, 0xEB, 0x36, 0x3D, 0xBF, 0x54, 0xBE, 0x15, 0x80, 0x39,
0xED, 0xDA, 0xE5, 0xC2, 0x57, 0x11, 0xDF, 0x48, 0xC1, 0x03,
},
- 270},
+ 270,
+ true},
{{
0x10, 0x69, 0xFA, 0x47, 0xA0, 0xAA, 0x4F, 0x8C, 0xF7, 0x11, 0x1B,
0x1C, 0xAE, 0xA3, 0x65, 0xEE, 0xAE, 0xD1, 0x0B, 0xFF, 0xF3, 0x26,
0x60, 0xDE, 0xF6, 0xE0, 0x61, 0x4B, 0xFA, 0xE7, 0x08, 0x75,
},
- 45},
+ 45,
+ true},
{{
0x10, 0xBA, 0x34, 0x85, 0xCA, 0x8B, 0xB6, 0x88, 0x0A, 0xB9, 0x53,
0x1A, 0x40, 0x63, 0xE4, 0x00, 0x15, 0x55, 0x56, 0x1C, 0x7F, 0x2E,
0x05, 0x51, 0x65, 0xF4, 0x9B, 0x2D, 0x74, 0xFC, 0x5F, 0x6B,
},
- 62},
+ 62,
+ false},
{{
0x11, 0x1C, 0x24, 0xA2, 0x43, 0x06, 0x1D, 0xA7, 0x6E, 0x57, 0xE3,
0xB1, 0x24, 0x3E, 0xDA, 0x90, 0x87, 0x9F, 0xFB, 0x75, 0x05, 0x52,
0x39, 0x54, 0x43, 0xFA, 0x8C, 0x34, 0xDC, 0x0E, 0xD7, 0x37,
},
- 442},
+ 442,
+ true},
{{
0x11, 0x24, 0x32, 0xE4, 0xBB, 0x84, 0x8C, 0x45, 0x54, 0x9F, 0xCB,
0xF0, 0xC7, 0x10, 0xC5, 0x66, 0xD0, 0x08, 0x2B, 0xBB, 0xC4, 0xE9,
0xB3, 0x8E, 0x6C, 0x76, 0xAD, 0x46, 0x44, 0x81, 0x28, 0xFC,
},
- 388},
+ 388,
+ true},
{{
0x12, 0x55, 0xCA, 0xBE, 0x81, 0x52, 0xFA, 0x64, 0xDF, 0x94, 0x2F,
0x7A, 0x47, 0x41, 0x7E, 0x29, 0xF9, 0x6C, 0x1C, 0xE1, 0x1B, 0xF8,
0xC8, 0x4E, 0xCB, 0xE2, 0x81, 0x5C, 0xC1, 0x28, 0x08, 0x10,
},
- 469},
+ 469,
+ true},
{{
0x14, 0x62, 0x00, 0x9B, 0x2D, 0xE6, 0x5D, 0x6D, 0x4D, 0x39, 0xBE,
0x89, 0x2B, 0xD2, 0xC1, 0x86, 0x49, 0x05, 0x31, 0xCE, 0x65, 0x90,
0xE4, 0x8F, 0xE1, 0x96, 0x07, 0x0D, 0x31, 0x7B, 0x60, 0xB0,
},
- 330},
+ 330,
+ true},
{{
0x14, 0x9F, 0x2E, 0xE6, 0x3B, 0x9A, 0x5E, 0x58, 0x03, 0x24, 0x0A,
0x77, 0x0D, 0xC9, 0x91, 0xFC, 0x2E, 0x34, 0x45, 0xE6, 0x28, 0x31,
0xC2, 0x45, 0xA4, 0x9B, 0xC4, 0xF1, 0xF7, 0x38, 0xFF, 0x9C,
},
- 196},
+ 196,
+ false},
{{
0x15, 0x28, 0x39, 0x7D, 0xA2, 0x12, 0x89, 0x0A, 0x83, 0x0B, 0x0B,
0x95, 0xA5, 0x99, 0x68, 0xCE, 0xF2, 0x34, 0x77, 0x37, 0x79, 0xDF,
0x51, 0x81, 0xCF, 0x10, 0xFA, 0x64, 0x75, 0x34, 0xBB, 0x65,
},
- 146},
+ 146,
+ true},
{{
0x15, 0xBB, 0x28, 0xD9, 0x20, 0x7E, 0x13, 0xF8, 0xBC, 0x95, 0x57,
0xDD, 0x78, 0x5E, 0xBA, 0x77, 0x3B, 0xEA, 0x94, 0x4E, 0x04, 0xD7,
0xE0, 0x8F, 0xF8, 0xAA, 0x55, 0xEF, 0x31, 0x94, 0xAA, 0x20,
},
- 400},
+ 400,
+ true},
{{
0x15, 0xE7, 0xE7, 0x17, 0xB4, 0x28, 0xFE, 0xEE, 0x3A, 0xF3, 0xAF,
0xD9, 0x15, 0x0D, 0xBA, 0xD4, 0x97, 0x00, 0x8D, 0x3A, 0x3F, 0xF0,
0x16, 0x96, 0x47, 0x19, 0x90, 0x7B, 0xDB, 0x01, 0xA6, 0x45,
},
- 40},
+ 40,
+ false},
{{
0x15, 0xEE, 0xD3, 0x39, 0x59, 0x4B, 0x30, 0x4F, 0x8C, 0xF8, 0x47,
0xB4, 0x77, 0x37, 0x1D, 0x8D, 0x6F, 0xEC, 0x61, 0xF4, 0xDB, 0x2B,
0x01, 0xAF, 0x58, 0x9E, 0x7C, 0x53, 0xB3, 0x5C, 0xAE, 0x4C,
},
- 174},
+ 174,
+ false},
{{
0x15, 0xF1, 0x4A, 0xC4, 0x5C, 0x9C, 0x7D, 0xA2, 0x33, 0xD3, 0x47,
0x91, 0x64, 0xE8, 0x13, 0x7F, 0xE3, 0x5E, 0xE0, 0xF3, 0x8A, 0xE8,
0x58, 0x18, 0x3F, 0x08, 0x41, 0x0E, 0xA8, 0x2A, 0xC4, 0xB4,
},
- 22},
+ 22,
+ false},
{{
0x16, 0x1E, 0x83, 0xEA, 0x32, 0xD4, 0x76, 0x41, 0xE2, 0x3C, 0xBE,
0x0E, 0xB4, 0x13, 0xA3, 0xE0, 0xB0, 0x68, 0x59, 0x92, 0x2A, 0x49,
0xD1, 0xA2, 0x0C, 0xFA, 0x05, 0xA4, 0x1E, 0x28, 0x0C, 0xFC,
},
- 300},
+ 300,
+ true},
{{
0x16, 0xA9, 0xE0, 0x12, 0xD3, 0x23, 0x29, 0xF2, 0x82, 0xB1, 0x0B,
0xBF, 0x57, 0xC7, 0xC0, 0xB4, 0x2A, 0xE8, 0x0F, 0x6A, 0xC9, 0x54,
0x2E, 0xB4, 0x09, 0xBC, 0x1C, 0x2C, 0xDE, 0x50, 0xD3, 0x22,
},
- 229},
+ 229,
+ true},
{{
0x16, 0xD8, 0x2D, 0x67, 0xA1, 0xED, 0x8E, 0x89, 0xF9, 0xAB, 0x58,
0xF7, 0xD0, 0xFD, 0x3E, 0xB0, 0xD0, 0x01, 0x76, 0x87, 0xFC, 0xAE,
0xEC, 0xD4, 0x04, 0x75, 0xF1, 0x00, 0x83, 0xA5, 0xB5, 0x93,
},
- 165},
+ 165,
+ true},
{{
0x17, 0x75, 0x5A, 0x5C, 0x29, 0x5F, 0x3D, 0x2D, 0x72, 0xE6, 0xF0,
0x31, 0xA1, 0xF0, 0x7F, 0x40, 0x0C, 0x58, 0x8B, 0x9E, 0x58, 0x2B,
0x22, 0xF1, 0x7E, 0xAE, 0x31, 0xA1, 0x59, 0x0D, 0x11, 0x85,
},
- 52},
+ 52,
+ true},
{{
0x18, 0xCF, 0xA6, 0x45, 0x18, 0xE9, 0x16, 0xCA, 0xFE, 0x98, 0x55,
0x61, 0x51, 0x3C, 0xAB, 0x7A, 0x89, 0x7A, 0x54, 0xBD, 0x23, 0xB8,
0xE2, 0x68, 0x74, 0xC5, 0xC7, 0xCB, 0xD1, 0x24, 0x9C, 0xFC,
},
- 317},
+ 317,
+ true},
{{
0x19, 0x06, 0xC6, 0x12, 0x4D, 0xBB, 0x43, 0x85, 0x78, 0xD0, 0x0E,
0x06, 0x6D, 0x50, 0x54, 0xC6, 0xC3, 0x7F, 0x0F, 0xA6, 0x02, 0x8C,
0x05, 0x54, 0x5E, 0x09, 0x94, 0xED, 0xDA, 0xEC, 0x86, 0x29,
},
- 63},
+ 63,
+ false},
{{
0x19, 0x16, 0xF3, 0x50, 0x8E, 0xC3, 0xFA, 0xD7, 0x95, 0xF8, 0xDC,
0x4B, 0xD3, 0x16, 0xF9, 0xC6, 0x08, 0x5A, 0x64, 0xDE, 0x3C, 0x41,
0x53, 0xAC, 0x6D, 0x62, 0xD5, 0xEA, 0x19, 0x51, 0x5D, 0x39,
},
- 162},
+ 162,
+ true},
{{
0x19, 0xAD, 0x98, 0xDE, 0x02, 0x15, 0x5D, 0x7E, 0x33, 0xE9, 0xDD,
0x21, 0xF0, 0xE4, 0x56, 0x10, 0xFD, 0x11, 0xD2, 0x80, 0x44, 0xB8,
0x31, 0x8B, 0xBE, 0xBF, 0x9F, 0x63, 0x37, 0x88, 0x8D, 0xF0,
},
- 417},
+ 417,
+ true},
{{
0x1A, 0x42, 0x12, 0x23, 0xE8, 0x9B, 0xD8, 0x7C, 0x40, 0x3B, 0x48,
0xFA, 0x61, 0x69, 0x48, 0x47, 0x0D, 0x0F, 0x2C, 0x21, 0xCE, 0x2A,
0xC7, 0xBD, 0xD2, 0x27, 0x55, 0x06, 0x1C, 0x62, 0xBA, 0x92,
},
- 304},
+ 304,
+ true},
{{
0x1A, 0x7A, 0x3A, 0x1A, 0x68, 0xDD, 0x23, 0x61, 0xE3, 0xF3, 0xBB,
0x85, 0x5F, 0x3B, 0x26, 0xFC, 0xD8, 0x8B, 0x19, 0x7D, 0x8D, 0xD4,
0xDE, 0x06, 0xCF, 0x1B, 0x36, 0x2A, 0xC8, 0x9E, 0xC1, 0x3B,
},
- 39},
+ 39,
+ false},
{{
0x1B, 0x8A, 0x89, 0x53, 0x17, 0x01, 0x60, 0x8C, 0x9E, 0xF3, 0xC6,
0x5F, 0x5D, 0x60, 0xA9, 0x48, 0xB1, 0xBA, 0xDB, 0x97, 0x53, 0x62,
0x2A, 0x2E, 0x81, 0xC0, 0xA4, 0xA2, 0x84, 0xBE, 0x63, 0xCC,
},
- 419},
+ 419,
+ true},
{{
0x1C, 0x29, 0x4B, 0xC2, 0x52, 0x43, 0x76, 0x89, 0x13, 0xED, 0x4A,
0xD5, 0xED, 0x61, 0xCB, 0x02, 0xBF, 0xBA, 0xE0, 0xBC, 0xE6, 0xE6,
0xE7, 0x2E, 0x5F, 0x96, 0x58, 0xF3, 0x46, 0xB4, 0x24, 0x96,
},
- 244},
+ 244,
+ true},
{{
0x1D, 0x75, 0xD0, 0x83, 0x1B, 0x9E, 0x08, 0x85, 0x39, 0x4D, 0x32,
0xC7, 0xA1, 0xBF, 0xDB, 0x3D, 0xBC, 0x1C, 0x28, 0xE2, 0xB0, 0xE8,
0x39, 0x1F, 0xB1, 0x35, 0x98, 0x1D, 0xBC, 0x5B, 0xA9, 0x36,
},
- 1},
+ 1,
+ false},
{{
0x1E, 0xA3, 0xC5, 0xE4, 0x3E, 0xD6, 0x6C, 0x2D, 0xA2, 0x98, 0x3A,
0x42, 0xA4, 0xA7, 0x9B, 0x1E, 0x90, 0x67, 0x86, 0xCE, 0x9F, 0x1B,
0x58, 0x62, 0x14, 0x19, 0xA0, 0x04, 0x63, 0xA8, 0x7D, 0x38,
},
- 38},
+ 38,
+ false},
{{
0x1E, 0xB9, 0xCF, 0x90, 0x1F, 0x08, 0x58, 0xAA, 0x17, 0xC3, 0x99,
0xBA, 0xBE, 0xBB, 0xDD, 0x8C, 0xB3, 0x03, 0xA4, 0xEF, 0x4E, 0x12,
0x20, 0xC4, 0x93, 0xCC, 0xA2, 0xF7, 0x5A, 0x3F, 0x91, 0x4E,
},
- 416},
+ 416,
+ true},
{{
0x1F, 0x42, 0x24, 0xCE, 0xC8, 0x4F, 0xC9, 0x9C, 0xED, 0x88, 0x1F,
0xF6, 0xFC, 0xFD, 0x3E, 0x21, 0xF8, 0xC5, 0x19, 0xC5, 0x47, 0xAA,
0x6A, 0x5D, 0xD3, 0xDE, 0x24, 0x73, 0x02, 0xCE, 0x50, 0xD1,
},
- 88},
+ 88,
+ true},
{{
0x20, 0x21, 0x91, 0x7E, 0x98, 0x26, 0x39, 0x45, 0xC8, 0x59, 0xC4,
0x3F, 0x1D, 0x73, 0xCB, 0x41, 0x39, 0x05, 0x3C, 0x41, 0x4F, 0xA0,
0x3C, 0xA3, 0xBC, 0x7E, 0xE8, 0x86, 0x14, 0x29, 0x8F, 0x3B,
},
- 179},
+ 179,
+ false},
{{
0x20, 0x26, 0x65, 0xE4, 0xC5, 0xC3, 0x80, 0xB4, 0x49, 0x0A, 0x81,
0x77, 0x3D, 0xB5, 0xDB, 0xA6, 0x2A, 0x90, 0xDB, 0x6F, 0x5B, 0xE6,
0xE0, 0xE5, 0x4D, 0x11, 0x99, 0x2F, 0xB1, 0xE6, 0x55, 0xFD,
},
- 398},
+ 398,
+ true},
{{
0x20, 0xE2, 0x4A, 0x5A, 0x33, 0x93, 0xD6, 0xC3, 0xAD, 0xC3, 0x84,
0xFA, 0xF9, 0x51, 0x52, 0xE1, 0xF9, 0xAA, 0x72, 0x22, 0x77, 0x40,
0x28, 0xB5, 0x3C, 0x5A, 0x34, 0xED, 0x0C, 0x6C, 0xB3, 0x99,
},
- 351},
+ 351,
+ true},
{{
0x21, 0xAE, 0x41, 0x25, 0x66, 0x32, 0x47, 0x25, 0xFF, 0xEF, 0xC1,
0xDC, 0xCF, 0x88, 0xF1, 0x6F, 0x8D, 0x6B, 0xF4, 0xDB, 0xBB, 0x37,
0xFE, 0x8C, 0xAB, 0xA4, 0x7E, 0x8D, 0x66, 0xC2, 0xCD, 0xF9,
},
- 477},
+ 477,
+ true},
{{
0x22, 0x05, 0x0A, 0x92, 0x83, 0x64, 0x81, 0xC2, 0xF3, 0xC1, 0xF8,
0x41, 0x7D, 0x37, 0x44, 0x7A, 0x16, 0x70, 0x07, 0xAC, 0x9B, 0xA6,
0x4E, 0xA2, 0x28, 0xCB, 0x6A, 0x1E, 0x14, 0xC6, 0x4B, 0x8B,
},
- 379},
+ 379,
+ true},
{{
0x22, 0x07, 0x6E, 0x5A, 0xEF, 0x44, 0xBB, 0x9A, 0x41, 0x6A, 0x28,
0xB7, 0xD1, 0xC4, 0x43, 0x22, 0xD7, 0x05, 0x9F, 0x60, 0xFE, 0xFF,
0xA5, 0xCA, 0xF6, 0xC5, 0xBE, 0x84, 0x47, 0x89, 0x13, 0x03,
},
- 226},
+ 226,
+ true},
{{
0x23, 0x2C, 0xBE, 0x2D, 0x9E, 0x69, 0x94, 0xC1, 0xCE, 0xB7, 0xFB,
0xEE, 0x23, 0xAB, 0x16, 0x57, 0xDE, 0xFB, 0x6B, 0x35, 0x64, 0x72,
0x6F, 0x1E, 0x78, 0x95, 0x1C, 0xEF, 0x3A, 0x2B, 0x09, 0x5D,
},
- 339},
+ 339,
+ true},
{{
0x23, 0x64, 0xD6, 0x92, 0xDC, 0xCA, 0xE1, 0x3D, 0xA5, 0x6A, 0xD4,
0xA0, 0x7C, 0x13, 0x25, 0xDC, 0x57, 0x52, 0x15, 0xFF, 0x1A, 0x07,
0x16, 0x81, 0xDF, 0xCA, 0x5D, 0xD6, 0xED, 0x7C, 0x84, 0x52,
},
- 422},
+ 422,
+ true},
{{
0x23, 0x84, 0x9D, 0x09, 0x49, 0x23, 0xD4, 0x4A, 0x48, 0x81, 0xB6,
0x3A, 0xB1, 0x85, 0xE9, 0xBE, 0x15, 0xAA, 0xC8, 0xEF, 0x2C, 0x30,
0x44, 0xD9, 0x34, 0xBC, 0x7F, 0x26, 0xE2, 0xD2, 0xCD, 0x69,
},
- 115},
+ 115,
+ true},
{{
0x23, 0xF2, 0xED, 0xFF, 0x3E, 0xDE, 0x90, 0x25, 0x9A, 0x9E, 0x30,
0xF4, 0x0A, 0xF8, 0xF9, 0x12, 0xA5, 0xE5, 0xB3, 0x69, 0x4E, 0x69,
0x38, 0x44, 0x03, 0x41, 0xF6, 0x06, 0x0E, 0x01, 0x4F, 0xFA,
},
- 64},
+ 64,
+ false},
{{
0x24, 0x48, 0x03, 0xCF, 0xA3, 0x59, 0x53, 0x38, 0x5D, 0x06, 0x65,
0x7A, 0xC4, 0xE5, 0xAB, 0x4F, 0x2B, 0xC0, 0x40, 0x52, 0x77, 0xBE,
0x66, 0x2A, 0xDB, 0x90, 0x5E, 0x14, 0x98, 0xB1, 0xDE, 0xFD,
},
- 460},
+ 460,
+ true},
{{
0x25, 0x96, 0x90, 0x4D, 0xC4, 0xD6, 0x99, 0xAE, 0x20, 0xC2, 0xCE,
0xF4, 0xDC, 0xE4, 0x7F, 0x28, 0x59, 0x37, 0xD7, 0x74, 0x64, 0xAC,
0x37, 0x07, 0x46, 0xF5, 0x2D, 0xEA, 0x76, 0xBA, 0x0C, 0x28,
},
- 116},
+ 116,
+ false},
{{
0x25, 0xAE, 0xEC, 0x63, 0xF3, 0xCC, 0xD7, 0x3D, 0xD6, 0x1C, 0xB4,
0xFB, 0xBD, 0x13, 0x60, 0x37, 0x22, 0xE0, 0x2C, 0xB5, 0x4E, 0x03,
0x04, 0x77, 0x37, 0x08, 0x42, 0x11, 0x07, 0x1D, 0x78, 0x50,
},
- 61},
+ 61,
+ true},
{{
0x25, 0xB4, 0x1B, 0x50, 0x6E, 0x49, 0x30, 0x95, 0x28, 0x23, 0xA6,
0xEB, 0x9F, 0x1D, 0x31, 0xDE, 0xF6, 0x45, 0xEA, 0x38, 0xA5, 0xC6,
0xC6, 0xA9, 0x6D, 0x71, 0x95, 0x7E, 0x38, 0x4D, 0xF0, 0x58,
},
- 152},
+ 152,
+ false},
{{
0x25, 0xD4, 0x91, 0x3C, 0xF5, 0x87, 0x09, 0x74, 0x14, 0xD2, 0x9D,
0x26, 0xF6, 0xC1, 0xB1, 0x94, 0x2C, 0xD6, 0xD6, 0x4E, 0xAF, 0x45,
0xD0, 0xFC, 0xF8, 0x15, 0x26, 0xAD, 0xBA, 0x96, 0xD3, 0x24,
},
- 59},
+ 59,
+ false},
{{
0x26, 0xC1, 0x8D, 0xC6, 0xEE, 0xA6, 0xF6, 0x32, 0xF6, 0x76, 0xBC,
0xEB, 0xA1, 0xD8, 0xC2, 0xB4, 0x83, 0x52, 0xF2, 0x9C, 0x2D, 0x5F,
0xCD, 0xA8, 0x78, 0xE0, 0x9D, 0xCB, 0x83, 0x2D, 0xD6, 0xE5,
},
- 140},
+ 140,
+ true},
{{
0x27, 0x8A, 0x63, 0x91, 0xD3, 0xD3, 0x6B, 0x49, 0xAA, 0x40, 0x80,
0xF5, 0x6A, 0x36, 0xB3, 0xC1, 0x0F, 0xBA, 0x4E, 0x28, 0xAA, 0x6A,
0x95, 0x92, 0xA8, 0x2E, 0x75, 0x35, 0x11, 0x3A, 0x12, 0xD3,
},
- 163},
+ 163,
+ true},
{{
0x28, 0x2F, 0xB5, 0xCF, 0xBA, 0xF0, 0x15, 0x18, 0xD9, 0x70, 0x4D,
0xE7, 0x88, 0x4D, 0x7A, 0x25, 0xFF, 0x01, 0xCF, 0x88, 0x2E, 0x99,
0x42, 0x90, 0xD5, 0x99, 0x5D, 0x5E, 0xB6, 0xC4, 0x49, 0x88,
},
- 489},
+ 489,
+ true},
{{
0x28, 0x33, 0x10, 0x81, 0x9F, 0x5E, 0x09, 0x20, 0x49, 0x95, 0xD8,
0xAD, 0x9F, 0xF6, 0xFC, 0x10, 0x74, 0x62, 0x97, 0xB5, 0xC0, 0xAE,
0x06, 0xBD, 0xD1, 0xE1, 0x12, 0x4B, 0x10, 0xA0, 0xD7, 0xAD,
},
- 343},
+ 343,
+ true},
{{
0x28, 0x96, 0xB4, 0xDD, 0xBE, 0x61, 0x45, 0x71, 0x83, 0xCC, 0x7E,
0xD2, 0x7B, 0xD7, 0x8A, 0xC5, 0x0A, 0x20, 0x7F, 0x69, 0x01, 0xC5,
0xC5, 0x2E, 0x53, 0xDC, 0x16, 0x76, 0xF9, 0xBB, 0x1E, 0x06,
},
- 241},
+ 241,
+ true},
{{
0x29, 0xE7, 0xFD, 0xDA, 0x48, 0x9E, 0x46, 0xEE, 0x48, 0x6E, 0xFD,
0x75, 0xAC, 0xC4, 0x8F, 0x25, 0x19, 0x32, 0xDC, 0x9D, 0xA1, 0x87,
0x2B, 0x31, 0x75, 0x3C, 0xD6, 0x47, 0x19, 0x56, 0x7A, 0xA5,
},
- 441},
+ 441,
+ true},
{{
0x2A, 0x29, 0x33, 0x7C, 0x3D, 0x62, 0x24, 0xCC, 0x53, 0xF0, 0xBB,
0x5E, 0x5D, 0x58, 0x20, 0xC0, 0xD8, 0x84, 0x8B, 0x04, 0x87, 0x13,
0x28, 0xF0, 0x90, 0xFE, 0xE3, 0xCD, 0x6B, 0xF8, 0x21, 0xB4,
},
- 83},
+ 83,
+ true},
{{
0x2A, 0x42, 0x12, 0x60, 0x5A, 0xA3, 0xE8, 0xAE, 0xCB, 0x0F, 0xC1,
0x98, 0x06, 0xCF, 0x3B, 0x40, 0xB5, 0x3B, 0x95, 0xF1, 0xA3, 0x4D,
0xBB, 0xD6, 0xE3, 0xED, 0x27, 0x23, 0x03, 0x24, 0xAB, 0xB3,
},
- 102},
+ 102,
+ false},
{{
0x2A, 0x4F, 0x49, 0xEE, 0x77, 0x01, 0xA3, 0x95, 0xAC, 0x93, 0x2E,
0x44, 0x42, 0x92, 0x67, 0x15, 0x88, 0xAD, 0xE2, 0x12, 0x59, 0xCE,
0x29, 0x6E, 0x19, 0x49, 0x40, 0x36, 0x87, 0x02, 0xEA, 0x7F,
},
- 359},
+ 359,
+ true},
{{
0x2A, 0x8B, 0xED, 0x32, 0xAE, 0x68, 0x0D, 0x2D, 0x18, 0x7B, 0x9A,
0x7A, 0xFD, 0x17, 0x1D, 0x83, 0xFD, 0x0B, 0x93, 0x5E, 0xAF, 0x9E,
0x2C, 0x1B, 0x43, 0xE8, 0x02, 0x78, 0xD2, 0x06, 0x3E, 0x39,
},
- 161},
+ 161,
+ true},
{{
0x2A, 0x8F, 0x2D, 0x8A, 0xF0, 0xEB, 0x12, 0x38, 0x98, 0xF7, 0x4C,
0x86, 0x6A, 0xC3, 0xFA, 0x66, 0x90, 0x54, 0xE2, 0x3C, 0x17, 0xBC,
0x7A, 0x95, 0xBD, 0x02, 0x34, 0x19, 0x2D, 0xC6, 0x35, 0xD0,
},
- 113},
+ 113,
+ false},
{{
0x2B, 0x07, 0x1C, 0x59, 0xA0, 0xA0, 0xAE, 0x76, 0xB0, 0xEA, 0xDB,
0x2B, 0xAD, 0x23, 0xBA, 0xD4, 0x58, 0x0B, 0x69, 0xC3, 0x60, 0x1B,
0x63, 0x0C, 0x2E, 0xAF, 0x06, 0x13, 0xAF, 0xA8, 0x3F, 0x92,
},
- 6},
+ 6,
+ false},
{{
0x2B, 0xB5, 0xC2, 0x8A, 0x34, 0xC9, 0xA3, 0x7D, 0xD9, 0x60, 0x45,
0x00, 0xCA, 0x9B, 0x30, 0x38, 0xD0, 0x05, 0x28, 0xB4, 0x74, 0x77,
0x3A, 0x27, 0x32, 0xAE, 0xA7, 0x9E, 0x49, 0x05, 0xC2, 0x34,
},
- 311},
+ 311,
+ true},
{{
0x2B, 0xCE, 0xE8, 0x58, 0x15, 0x8C, 0xF5, 0x46, 0x5F, 0xC9, 0xD7,
0x6F, 0x0D, 0xFA, 0x31, 0x2F, 0xEF, 0x25, 0xA4, 0xDC, 0xA8, 0x50,
0x1D, 0xA9, 0xB4, 0x6B, 0x67, 0xD1, 0xFB, 0xFA, 0x1B, 0x64,
},
- 109},
+ 109,
+ false},
{{
0x2D, 0x6D, 0x69, 0x0C, 0x16, 0xB1, 0x18, 0x53, 0x88, 0x4B, 0xBE,
0xA2, 0x72, 0x37, 0x25, 0x26, 0x7E, 0x3F, 0x9B, 0x54, 0xA6, 0xCF,
0x07, 0xAD, 0x46, 0x90, 0xAB, 0x1E, 0x7C, 0xFB, 0x75, 0xE8,
},
- 438},
+ 438,
+ true},
{{
0x2D, 0xA8, 0xF9, 0xEA, 0x34, 0x54, 0xD2, 0x11, 0x46, 0x46, 0x4A,
0x3F, 0x9D, 0x02, 0x8D, 0xC4, 0xC7, 0xFB, 0xB5, 0x7B, 0x1C, 0x52,
0xC7, 0x3C, 0x2B, 0x05, 0x72, 0xA2, 0xF5, 0x99, 0xA2, 0xD3,
},
- 269},
+ 269,
+ true},
{{
0x2D, 0xC9, 0x47, 0x0B, 0xE6, 0x3E, 0xF4, 0xAC, 0xF1, 0xBD, 0x82,
0x86, 0x09, 0x40, 0x2B, 0xB7, 0xB8, 0x7B, 0xD9, 0x96, 0x38, 0xA6,
0x43, 0x93, 0x4E, 0x88, 0x68, 0x2D, 0x1B, 0xE8, 0xC3, 0x08,
},
- 248},
+ 248,
+ true},
{{
0x2D, 0xEE, 0x51, 0x71, 0x59, 0x6A, 0xB8, 0xF3, 0xCD, 0x3C, 0x76,
0x35, 0xFE, 0xA8, 0xE6, 0xC3, 0x00, 0x6A, 0xA9, 0xE3, 0x1D, 0xB3,
0x9D, 0x03, 0xA7, 0x48, 0x0D, 0xDB, 0x24, 0x28, 0xA3, 0x3E,
},
- 264},
+ 264,
+ true},
{{
0x2E, 0x00, 0x91, 0x5A, 0x9F, 0x7B, 0xE0, 0x6A, 0xB2, 0x37, 0x0C,
0x7B, 0x7C, 0x20, 0x0C, 0x0A, 0x96, 0xD5, 0xAC, 0x6A, 0x50, 0xCE,
0x18, 0x74, 0xDB, 0xEF, 0xDE, 0x40, 0x22, 0xD4, 0xDE, 0x8E,
},
- 272},
+ 272,
+ true},
{{
0x2F, 0xC5, 0x66, 0x7A, 0x4B, 0x9A, 0x26, 0x78, 0xED, 0x6A, 0xC6,
0xAD, 0x25, 0x46, 0x5F, 0xCB, 0xF6, 0x09, 0x4B, 0xFC, 0xD9, 0x50,
0x40, 0x97, 0xC7, 0xA8, 0xFA, 0x47, 0xAD, 0xE5, 0xE8, 0x88,
},
- 206},
+ 206,
+ false},
{{
0x2F, 0xCC, 0x99, 0xF5, 0xC9, 0xD0, 0x0F, 0x9A, 0x20, 0xDA, 0x61,
0x31, 0xDE, 0xA5, 0xC0, 0x27, 0xD9, 0x26, 0x36, 0xD6, 0x8C, 0xD9,
0xCD, 0xBE, 0x95, 0x29, 0x0A, 0x3C, 0x40, 0x89, 0x19, 0xE0,
},
- 427},
+ 427,
+ true},
{{
0x30, 0x27, 0xA2, 0x98, 0xFA, 0x57, 0x31, 0x4D, 0xC0, 0xE3, 0xDD,
0x10, 0x19, 0x41, 0x1B, 0x8F, 0x40, 0x4C, 0x43, 0xC3, 0xF9, 0x34,
0xCE, 0x3B, 0xDF, 0x85, 0x65, 0x12, 0xC8, 0x0A, 0xA1, 0x5C,
},
- 256},
+ 256,
+ true},
{{
0x30, 0x9F, 0x13, 0xD4, 0x9E, 0xA6, 0x6F, 0x52, 0x32, 0x41, 0xB5,
0x55, 0x24, 0x74, 0x44, 0x64, 0xE2, 0x8C, 0xC1, 0xB8, 0x2E, 0xF7,
0x9B, 0x64, 0xE4, 0xD5, 0x81, 0x88, 0x0D, 0xCD, 0x77, 0x1F,
},
- 237},
+ 237,
+ true},
{{
0x30, 0xAB, 0x1B, 0xCD, 0x7B, 0xED, 0x1F, 0xF2, 0x67, 0x9F, 0x71,
0x22, 0x88, 0x20, 0x42, 0x0A, 0x70, 0x63, 0xC6, 0xCE, 0xAD, 0x7E,
0xC3, 0x0D, 0x4A, 0x01, 0x61, 0x54, 0x87, 0x6D, 0xDD, 0xB5,
},
- 280},
+ 280,
+ true},
{{
0x30, 0xB7, 0x1C, 0x4F, 0x91, 0x22, 0x47, 0x6E, 0x76, 0x1E, 0x62,
0x0E, 0xEC, 0x42, 0xBF, 0xA5, 0xF8, 0x4C, 0x49, 0x3C, 0xD4, 0x9B,
0xBB, 0x18, 0x34, 0xB2, 0x6E, 0x55, 0x5F, 0x60, 0xDE, 0x40,
},
- 360},
+ 360,
+ true},
{{
0x31, 0x51, 0x26, 0x80, 0x23, 0x3F, 0x5F, 0x2A, 0x1F, 0x29, 0x43,
0x7F, 0x56, 0xD4, 0x98, 0x8C, 0xF0, 0xAF, 0xC4, 0x1C, 0xC6, 0xC5,
0xDA, 0x62, 0x75, 0x92, 0x8E, 0x9C, 0x0B, 0xEA, 0xDE, 0x27,
},
- 254},
+ 254,
+ true},
{{
0x31, 0xDE, 0x0C, 0xB1, 0x9F, 0x2A, 0xDB, 0xB0, 0xD1, 0xCD, 0x7B,
0x1B, 0x31, 0xEF, 0x8E, 0xE3, 0xEB, 0x59, 0xB7, 0x44, 0x59, 0xAE,
0xF9, 0x4B, 0x48, 0x0B, 0xEE, 0xEE, 0xB8, 0x5C, 0x64, 0xC9,
},
- 147},
+ 147,
+ true},
{{
0x32, 0x19, 0xB0, 0x91, 0x14, 0xFF, 0x49, 0x5A, 0x3E, 0xB6, 0xEB,
0x00, 0xC2, 0xEF, 0xEA, 0xB3, 0x40, 0x02, 0xAE, 0x5F, 0x0A, 0x56,
0xC7, 0x67, 0x9E, 0xA0, 0x87, 0xA3, 0xFA, 0x03, 0x7E, 0x4F,
},
- 125},
+ 125,
+ false},
{{
0x32, 0xD1, 0x80, 0xED, 0x31, 0xC9, 0x35, 0x58, 0x9E, 0xC9, 0xDB,
0xBB, 0x72, 0x21, 0x23, 0xB8, 0x83, 0xB5, 0xFC, 0x2D, 0xC1, 0x0F,
0x9F, 0xCA, 0x3A, 0x95, 0xD7, 0x7E, 0x1B, 0xFC, 0xB5, 0x34,
},
- 27},
+ 27,
+ false},
{{
0x33, 0x29, 0xBF, 0xA1, 0x3B, 0x60, 0x07, 0xAB, 0x5F, 0xC3, 0x71,
0x3F, 0x0A, 0xCB, 0x28, 0x94, 0x26, 0xE2, 0xFB, 0xC9, 0x9C, 0xC5,
0xC1, 0x10, 0xA9, 0x14, 0xB1, 0x39, 0x57, 0x16, 0x00, 0xB6,
},
- 471},
+ 471,
+ true},
{{
0x33, 0x80, 0x70, 0x9A, 0xF3, 0xB0, 0x96, 0xBE, 0x3C, 0xC2, 0xA4,
0x05, 0x48, 0x14, 0x2C, 0x0A, 0x52, 0x00, 0x28, 0xDB, 0x09, 0xE2,
0xCB, 0x77, 0xAE, 0x22, 0x06, 0x61, 0x6A, 0xB6, 0xCB, 0xB4,
},
- 130},
+ 130,
+ false},
{{
0x33, 0xAF, 0x58, 0xB5, 0x58, 0x9E, 0xCE, 0xA7, 0x92, 0x62, 0x52,
0x47, 0x78, 0x38, 0xBA, 0x40, 0x24, 0x7A, 0xB3, 0x7B, 0x6F, 0xB3,
0x9E, 0x34, 0xFC, 0xBD, 0x55, 0x2C, 0xD5, 0xA8, 0xC6, 0x6D,
},
- 233},
+ 233,
+ true},
{{
0x33, 0xFA, 0x5A, 0x53, 0x00, 0x61, 0x3D, 0x46, 0x6E, 0x6F, 0x85,
0xC8, 0x05, 0x16, 0x95, 0xBE, 0xD5, 0xD1, 0xFA, 0xD5, 0x9F, 0x25,
0xE0, 0x40, 0xAC, 0xDA, 0x04, 0x72, 0xA7, 0x4F, 0x3C, 0x20,
},
- 458},
+ 458,
+ true},
{{
0x34, 0x87, 0x67, 0xCD, 0xAD, 0x3B, 0xDD, 0x28, 0xB2, 0xB8, 0xDD,
0x53, 0x51, 0xAE, 0xC3, 0x0C, 0x68, 0xCE, 0xC5, 0xCD, 0x69, 0xD2,
0x76, 0xDF, 0x38, 0x27, 0xDB, 0xC4, 0xF5, 0x80, 0x64, 0x64,
},
- 295},
+ 295,
+ false},
{{
0x34, 0x99, 0xF9, 0x3F, 0xD3, 0x94, 0x52, 0x3B, 0xFB, 0x1E, 0xC4,
0xC3, 0xAD, 0x4D, 0xFB, 0x31, 0x01, 0x31, 0xFB, 0xE9, 0xEE, 0x54,
0x76, 0xBD, 0xE6, 0x29, 0x5D, 0xE8, 0x08, 0xD5, 0xDD, 0x8F,
},
- 138},
+ 138,
+ true},
{{
0x35, 0x51, 0xDE, 0x58, 0xA7, 0xD7, 0x9C, 0xD9, 0x80, 0x28, 0x3D,
0xF8, 0x17, 0x90, 0xD6, 0x3A, 0x98, 0x2C, 0x1A, 0x63, 0xB3, 0x04,
0x82, 0xEC, 0x58, 0x21, 0xDB, 0x76, 0x61, 0x55, 0x4E, 0xF9,
},
- 150},
+ 150,
+ true},
{{
0x36, 0xAB, 0xC3, 0x26, 0x56, 0xAC, 0xFC, 0x64, 0x5C, 0x61, 0xB7,
0x16, 0x13, 0xC4, 0xBF, 0x21, 0xC7, 0x87, 0xF5, 0xCA, 0xBB, 0xEE,
0x48, 0x34, 0x8D, 0x58, 0x59, 0x78, 0x03, 0xD7, 0xAB, 0xC9,
},
- 205},
+ 205,
+ false},
{{
0x36, 0xC2, 0x23, 0x14, 0x13, 0x1A, 0x5F, 0xBF, 0x1B, 0x70, 0xEA,
0x4C, 0xCF, 0x4B, 0xC1, 0x3A, 0x77, 0x7D, 0x93, 0x8E, 0xC6, 0x5E,
0x1D, 0xA2, 0x4E, 0x3C, 0x2C, 0xFD, 0x01, 0xD3, 0xD1, 0x63,
},
- 94},
+ 94,
+ false},
{{
0x36, 0xEC, 0xC6, 0x1F, 0xC7, 0xE5, 0xF1, 0x92, 0x3D, 0x16, 0x7E,
0x67, 0xDF, 0xDE, 0x34, 0x60, 0x85, 0x49, 0xB3, 0x4A, 0x63, 0xC7,
0xC6, 0xE6, 0x0F, 0xFD, 0x5C, 0x18, 0x40, 0x38, 0x1F, 0x5C,
},
- 74},
+ 74,
+ false},
{{
0x38, 0x07, 0x39, 0x62, 0x0E, 0x13, 0x33, 0x58, 0x05, 0xEA, 0xDA,
0x8F, 0x9F, 0x8B, 0x81, 0x55, 0x4D, 0x3B, 0xD3, 0xC0, 0x01, 0x7F,
0x36, 0x32, 0xC2, 0x67, 0x76, 0x69, 0xCA, 0xC7, 0xA2, 0xBF,
},
- 459},
+ 459,
+ true},
{{
0x38, 0x1A, 0x3F, 0xC7, 0xA8, 0xB0, 0x82, 0xFA, 0x28, 0x61, 0x3A,
0x4D, 0x07, 0xF2, 0xC7, 0x55, 0x3F, 0x4E, 0x19, 0x18, 0xEE, 0x07,
0xCA, 0xA9, 0xE8, 0xB7, 0xCE, 0xDE, 0x5A, 0x9C, 0xA0, 0x6A,
},
- 192},
+ 192,
+ true},
{{
0x38, 0x61, 0xD7, 0xB6, 0x96, 0x1F, 0xCD, 0xB2, 0x12, 0x04, 0x56,
0xFF, 0x6F, 0xC2, 0xEB, 0x77, 0x04, 0xB1, 0xA7, 0x41, 0xB4, 0xBD,
0x93, 0x3A, 0x83, 0x76, 0xF5, 0xE1, 0x91, 0x5C, 0xA6, 0x98,
},
- 101},
+ 101,
+ true},
{{
0x3A, 0x0D, 0x88, 0x5C, 0xB3, 0x46, 0xD8, 0xF0, 0x1F, 0xD3, 0x00,
0xAF, 0x15, 0x46, 0xF6, 0x35, 0x5C, 0x00, 0x69, 0x0E, 0x34, 0x0E,
0xD9, 0x8F, 0x34, 0x6E, 0x77, 0xB5, 0x74, 0xBE, 0x3F, 0xD8,
},
- 303},
+ 303,
+ true},
{{
0x3A, 0x6C, 0x24, 0xE8, 0x0F, 0x68, 0x1D, 0x8B, 0x10, 0x47, 0xCE,
0xC0, 0x51, 0xC2, 0x75, 0x94, 0xF8, 0x85, 0xBA, 0x08, 0x87, 0xA2,
0x63, 0x79, 0x09, 0x2D, 0xFE, 0xF5, 0x06, 0x16, 0x0E, 0x9B,
},
- 279},
+ 279,
+ true},
{{
0x3A, 0x80, 0x3E, 0x7C, 0x0A, 0x43, 0xA2, 0x9F, 0xD7, 0x36, 0x72,
0xE3, 0xD0, 0xBB, 0x2C, 0x36, 0x53, 0xD9, 0x48, 0xED, 0xE0, 0xB3,
0xCB, 0x1D, 0xB4, 0xCE, 0x75, 0xA8, 0x57, 0xE8, 0x9A, 0xF1,
},
- 143},
+ 143,
+ true},
{{
0x3B, 0x0D, 0x73, 0xB4, 0xBE, 0x4A, 0x85, 0x4A, 0xDC, 0x3E, 0x51,
0xD7, 0xEF, 0x9F, 0xA4, 0x8A, 0xEF, 0xBB, 0x2C, 0xDD, 0x82, 0x4D,
0x67, 0xBD, 0xC7, 0xD7, 0xD0, 0x9A, 0x2A, 0xBC, 0x2D, 0x43,
},
- 128},
+ 128,
+ false},
{{
0x3B, 0x45, 0x91, 0x82, 0x05, 0xC5, 0x91, 0x29, 0x8A, 0x19, 0x22,
0xA5, 0x8B, 0x49, 0x21, 0xD0, 0x1F, 0x64, 0x8F, 0xA9, 0xD2, 0x8B,
0xDD, 0xDF, 0xAD, 0x24, 0xAE, 0xEC, 0x59, 0x42, 0xCF, 0xBF,
},
- 14},
+ 14,
+ true},
{{
0x3B, 0xDE, 0x97, 0x68, 0x6E, 0x3A, 0xF5, 0x1D, 0x3F, 0x57, 0x2C,
0x48, 0x88, 0xC1, 0x2B, 0xD1, 0xD1, 0xE0, 0x97, 0xF1, 0x2F, 0x49,
0xEC, 0x3C, 0x92, 0x89, 0x65, 0x51, 0xE3, 0x6F, 0x00, 0x85,
},
- 245},
+ 245,
+ true},
{{
0x3C, 0x19, 0x6F, 0x84, 0xE2, 0xA0, 0xC6, 0x1F, 0xEC, 0x18, 0xBA,
0xCA, 0xBD, 0x31, 0x78, 0x3B, 0x57, 0x45, 0x17, 0xAA, 0xD8, 0xEB,
0xC6, 0xCE, 0x6D, 0x1D, 0x7D, 0xC8, 0x2B, 0x3C, 0x50, 0xDF,
},
- 318},
+ 318,
+ true},
{{
0x3C, 0x35, 0xE1, 0x64, 0xBE, 0xDD, 0x2C, 0xF1, 0x2B, 0xEB, 0x83,
0xEC, 0xFF, 0x78, 0xB5, 0xE8, 0x0D, 0xA8, 0x15, 0x8D, 0x28, 0x30,
0x21, 0x7E, 0x4E, 0xBF, 0xFC, 0xE8, 0x92, 0x88, 0x99, 0xA6,
},
- 13},
+ 13,
+ false},
{{
0x3C, 0x84, 0xD9, 0x96, 0x72, 0x2B, 0x3C, 0x18, 0x72, 0xF5, 0x3D,
0xDD, 0x77, 0x17, 0xBB, 0x2F, 0xA5, 0x0E, 0xBF, 0xA0, 0x7B, 0x3F,
0x3B, 0x4A, 0x39, 0x53, 0x35, 0xC5, 0x67, 0x12, 0xFD, 0x69,
},
- 315},
+ 315,
+ true},
{{
0x3D, 0x8D, 0x06, 0x1E, 0xDC, 0xF7, 0xB3, 0xD4, 0x59, 0x95, 0xBA,
0x43, 0x41, 0x32, 0x8D, 0x1B, 0xE7, 0xB7, 0xEB, 0x4E, 0x9D, 0x14,
0xFE, 0xE7, 0x0D, 0x2F, 0x18, 0xAD, 0x68, 0xBE, 0xA7, 0xC5,
},
- 436},
+ 436,
+ true},
{{
0x3E, 0xA7, 0xB5, 0xC0, 0x45, 0xA9, 0x9A, 0x97, 0x71, 0xE2, 0xDE,
0xA8, 0xE8, 0x09, 0x8B, 0xA2, 0x73, 0x2D, 0x17, 0xCE, 0xEE, 0x82,
0x27, 0x95, 0x52, 0xFE, 0xEE, 0x90, 0x55, 0x30, 0xF3, 0x5F,
},
- 420},
+ 420,
+ true},
{{
0x3E, 0xC1, 0x8D, 0xFE, 0xB8, 0x94, 0xA9, 0xEA, 0x20, 0xEB, 0x2C,
0xD4, 0x0C, 0x69, 0x3E, 0x2A, 0x29, 0x14, 0x4F, 0xE2, 0xEC, 0x60,
0xB4, 0xF7, 0xB8, 0x90, 0x26, 0x04, 0x0B, 0x39, 0xAE, 0xBE,
},
- 461},
+ 461,
+ true},
{{
0x3E, 0xE6, 0xB3, 0x41, 0x40, 0x28, 0x51, 0xB2, 0x7E, 0x64, 0x02,
0x1A, 0x30, 0x23, 0xAA, 0xC7, 0xC1, 0xA0, 0xD2, 0xDE, 0xF2, 0x7D,
0x5B, 0xCE, 0x5C, 0x2D, 0xBE, 0xB0, 0xB2, 0x2D, 0xCC, 0x71,
},
- 481},
+ 481,
+ true},
{{
0x3F, 0xAB, 0x78, 0x4F, 0xC3, 0xC9, 0xAB, 0x9E, 0xED, 0xC1, 0x2E,
0xCD, 0xC0, 0xDB, 0x55, 0x0F, 0x4C, 0x3D, 0xBF, 0xD3, 0xE8, 0x6D,
0x78, 0x81, 0x53, 0x33, 0xC5, 0xEB, 0xA5, 0x18, 0xCB, 0x9D,
},
- 225},
+ 225,
+ true},
{{
0x3F, 0xB6, 0x3C, 0x29, 0xF4, 0x7B, 0xCC, 0x4E, 0x6A, 0xAD, 0xB3,
0x57, 0x7C, 0xE7, 0xCA, 0x85, 0x43, 0xE0, 0xBB, 0xAB, 0xA5, 0x53,
0x67, 0x6B, 0x8F, 0xD1, 0x61, 0x29, 0x5B, 0xDB, 0x90, 0x11,
},
- 368},
+ 368,
+ true},
{{
0x40, 0x02, 0xFC, 0xD3, 0x11, 0xD0, 0x73, 0x31, 0x56, 0x7E, 0x71,
0xBC, 0xD9, 0x71, 0xE4, 0x60, 0x48, 0xC8, 0xDC, 0xE8, 0xD1, 0x65,
0x97, 0x11, 0x75, 0x3B, 0x3D, 0xAA, 0x2A, 0x26, 0x9A, 0xFA,
},
- 47},
+ 47,
+ true},
{{
0x40, 0xFC, 0xFC, 0x28, 0x87, 0x5D, 0xCC, 0xBF, 0xEB, 0xCB, 0xDF,
0x6C, 0xD7, 0x43, 0x33, 0x12, 0xDA, 0x63, 0xC4, 0xEF, 0xCF, 0x3B,
0xD7, 0xB1, 0xB5, 0x05, 0xC2, 0x20, 0x20, 0xAE, 0x02, 0x74,
},
- 35},
+ 35,
+ false},
{{
0x41, 0x79, 0xED, 0xD9, 0x81, 0xEF, 0x74, 0x74, 0x77, 0xB4, 0x96,
0x26, 0x40, 0x8A, 0xF4, 0x3D, 0xAA, 0x2C, 0xA7, 0xAB, 0x7F, 0x9E,
0x08, 0x2C, 0x10, 0x60, 0xF8, 0x40, 0x96, 0x77, 0x43, 0x48,
},
- 485},
+ 485,
+ true},
{{
0x42, 0x23, 0x89, 0x40, 0x03, 0xA8, 0x81, 0xC5, 0xDF, 0x6B, 0xAB,
0x16, 0x3D, 0xB2, 0x35, 0xC2, 0x21, 0xA1, 0x8D, 0x54, 0xBF, 0x75,
0x99, 0x45, 0x82, 0x0E, 0x67, 0x0D, 0xA8, 0x2E, 0x3F, 0x39,
},
- 187},
+ 187,
+ false},
{{
0x42, 0xA7, 0x09, 0x84, 0xFF, 0xD3, 0x99, 0xC4, 0xEA, 0xF0, 0xE7,
0x02, 0xA4, 0x4B, 0xEF, 0x2A, 0xD8, 0xA7, 0x9B, 0x8B, 0xF4, 0x64,
0x8F, 0x6B, 0xB2, 0x10, 0xE1, 0x23, 0xFD, 0x07, 0x57, 0x93,
},
- 409},
+ 409,
+ true},
{{
0x42, 0xA8, 0x07, 0xCE, 0xC5, 0xAE, 0x9C, 0x0F, 0x03, 0xB4, 0x0C,
0xA0, 0x43, 0xAC, 0x70, 0x46, 0x8B, 0x52, 0x19, 0xBD, 0x75, 0xCC,
0x5B, 0xBE, 0xA5, 0x1D, 0x92, 0x1D, 0xD1, 0x00, 0x15, 0x6F,
},
- 466},
+ 466,
+ true},
{{
0x43, 0x1B, 0x79, 0xFD, 0x93, 0x55, 0xD1, 0x0D, 0xC1, 0xB5, 0x0D,
0xBF, 0x6A, 0x6B, 0x62, 0xD7, 0xA5, 0xB6, 0xD3, 0x56, 0x54, 0x1C,
0x27, 0x60, 0x52, 0x55, 0xCA, 0x4C, 0xA7, 0x94, 0x20, 0xC1,
},
- 340},
+ 340,
+ true},
{{
0x43, 0x76, 0xA9, 0x93, 0x96, 0x76, 0x9F, 0xD4, 0x87, 0x24, 0x0E,
0xE8, 0xB5, 0x73, 0xAD, 0x49, 0x70, 0x6A, 0x5B, 0x94, 0x73, 0x61,
0x6A, 0xCE, 0xF3, 0x84, 0x09, 0xE9, 0x15, 0x86, 0xDC, 0x1E,
},
- 444},
+ 444,
+ true},
{{
0x43, 0x9C, 0x19, 0xFF, 0x3E, 0xDB, 0x26, 0x5E, 0xF1, 0xA9, 0x20,
0xF7, 0x4A, 0x48, 0x02, 0xD3, 0xDD, 0x95, 0xAC, 0xE0, 0x24, 0xE2,
0x1E, 0x5A, 0x6C, 0xE8, 0xE0, 0x64, 0xDC, 0x15, 0x66, 0xCD,
},
- 447},
+ 447,
+ true},
{{
0x43, 0xC7, 0x42, 0x62, 0xF7, 0x49, 0x26, 0x62, 0xD2, 0x45, 0x9B,
0xCC, 0x98, 0x99, 0xBA, 0xC5, 0x4A, 0x4E, 0xCC, 0x01, 0xE1, 0xA3,
0xF5, 0xE7, 0x65, 0x58, 0x99, 0x2B, 0x40, 0x15, 0x24, 0x18,
},
- 414},
+ 414,
+ true},
{{
0x43, 0xCF, 0xFC, 0x35, 0x9F, 0x2E, 0x8C, 0xAA, 0x57, 0x38, 0x8E,
0xE9, 0xF6, 0xF1, 0xDB, 0xE9, 0x3B, 0xF0, 0x93, 0x68, 0x2A, 0x69,
0x9A, 0xC3, 0x85, 0x2E, 0x6D, 0x1F, 0x85, 0x79, 0xE7, 0xF9,
},
- 56},
+ 56,
+ true},
{{
0x44, 0x62, 0xC1, 0x07, 0xC4, 0x85, 0xDD, 0x6A, 0x54, 0x43, 0xF5,
0xE7, 0xA1, 0x60, 0x44, 0x16, 0x03, 0x4A, 0x37, 0x4C, 0x3F, 0x4D,
0x10, 0x87, 0x5F, 0x1C, 0x37, 0x15, 0x02, 0x75, 0x63, 0xAF,
},
- 156},
+ 156,
+ true},
{{
0x44, 0xA3, 0xD8, 0x0D, 0x3F, 0x53, 0x48, 0x59, 0x6D, 0x80, 0xA0,
0x98, 0x42, 0xC2, 0x3A, 0x39, 0x77, 0x44, 0x39, 0xF8, 0xB0, 0xB9,
0x19, 0x23, 0x9D, 0x2A, 0x03, 0xDA, 0xC5, 0xCE, 0x52, 0x13,
},
- 403},
+ 403,
+ true},
{{
0x44, 0xAF, 0x8A, 0xFC, 0xF1, 0x39, 0x5D, 0x2A, 0x8E, 0x30, 0xEF,
0x81, 0x2C, 0xE1, 0x9C, 0xEB, 0x2E, 0x89, 0x48, 0xDF, 0xD2, 0x1E,
0x00, 0xFB, 0xAA, 0x34, 0x68, 0x9F, 0x9A, 0x24, 0x72, 0x1F,
},
- 51},
+ 51,
+ true},
{{
0x46, 0x3D, 0xBB, 0x9B, 0x0A, 0x26, 0xED, 0x26, 0x16, 0x39, 0x7B,
0x64, 0x31, 0x25, 0xFB, 0xD2, 0x9B, 0x66, 0xCF, 0x3A, 0x46, 0xFD,
0xB4, 0x38, 0x4B, 0x20, 0x9E, 0x78, 0x23, 0x7A, 0x1A, 0xFF,
},
- 353},
+ 353,
+ true},
{{
0x46, 0x91, 0xCB, 0xFD, 0xE8, 0x4A, 0x6B, 0x60, 0x52, 0xDD, 0xBE,
0x15, 0x2B, 0xB0, 0xC2, 0x16, 0xAE, 0x25, 0xA8, 0x6E, 0x57, 0x47,
0x81, 0x3D, 0xBC, 0x0F, 0x14, 0x7F, 0x33, 0x85, 0x70, 0xBE,
},
- 2},
+ 2,
+ true},
{{
0x46, 0x97, 0xA5, 0xAB, 0xEA, 0x00, 0x70, 0xA3, 0x95, 0x45, 0x6F,
0xD3, 0x58, 0xE9, 0x1F, 0x72, 0xF2, 0x27, 0xD5, 0x85, 0x09, 0x33,
0x22, 0x7F, 0x1E, 0x0B, 0xC7, 0x9F, 0xF8, 0x47, 0xBF, 0xAC,
},
- 352},
+ 352,
+ true},
{{
0x47, 0x9D, 0x13, 0x0B, 0xF3, 0xFC, 0x61, 0xDC, 0x2F, 0x1D, 0x50,
0x8D, 0x23, 0x9A, 0x13, 0x27, 0x6A, 0xE7, 0xB3, 0xC9, 0x84, 0x10,
0x11, 0xA0, 0x2C, 0x14, 0x02, 0xC7, 0xE6, 0x77, 0xBD, 0x5F,
},
- 263},
+ 263,
+ true},
{{
0x47, 0xC7, 0xA1, 0x49, 0xCA, 0x82, 0xFA, 0x7B, 0xA9, 0x40, 0xA4,
0xD7, 0x11, 0xD0, 0x10, 0x62, 0x5C, 0x6C, 0xB0, 0xB7, 0x48, 0xB1,
0x70, 0x16, 0xC4, 0x6E, 0x25, 0xCE, 0x7A, 0xCD, 0x2B, 0x0C,
},
- 266},
+ 266,
+ true},
{{
0x48, 0x2F, 0x76, 0xA2, 0xA9, 0x34, 0x6D, 0xBB, 0x07, 0x76, 0x19,
0xBB, 0xE1, 0xEF, 0xEC, 0xD5, 0x41, 0x07, 0xE9, 0x92, 0xFF, 0x4E,
0x8F, 0x4D, 0x70, 0xA3, 0x9E, 0x24, 0x05, 0xD9, 0x39, 0xD4,
},
- 278},
+ 278,
+ true},
{{
0x49, 0x05, 0x46, 0x66, 0x23, 0xAB, 0x41, 0x78, 0xBE, 0x92, 0xAC,
0x5C, 0xBD, 0x65, 0x84, 0xF7, 0xA1, 0xE1, 0x7F, 0x27, 0x65, 0x2D,
0x5A, 0x85, 0xAF, 0x89, 0x50, 0x4E, 0xA2, 0x39, 0xAA, 0xAA,
},
- 95},
+ 95,
+ false},
{{
0x49, 0x5A, 0x96, 0xBA, 0x6B, 0xAD, 0x78, 0x24, 0x07, 0xBD, 0x52,
0x1A, 0x00, 0xBA, 0xCE, 0x65, 0x7B, 0xB3, 0x55, 0x55, 0x5E, 0x4B,
0xB7, 0xF8, 0x14, 0x6C, 0x71, 0xBB, 0xA5, 0x7E, 0x7A, 0xCE,
},
- 79},
+ 79,
+ false},
{{
0x49, 0x8B, 0xC0, 0xCD, 0x5A, 0x49, 0xB7, 0x14, 0x07, 0x1E, 0xC7,
0x6A, 0x41, 0x66, 0x1C, 0xE2, 0xF2, 0x7F, 0xC3, 0x9F, 0xE4, 0x16,
0x8B, 0xC7, 0xB7, 0x79, 0x9A, 0x0A, 0xE2, 0x5F, 0x65, 0x28,
},
- 332},
+ 332,
+ true},
{{
0x49, 0xB8, 0x06, 0x85, 0xD3, 0x32, 0xE0, 0x72, 0xC0, 0xE7, 0xB7,
0x20, 0x03, 0x26, 0x47, 0xE8, 0x42, 0x10, 0x61, 0x04, 0xE0, 0xB1,
0x13, 0x9A, 0xB9, 0xE8, 0x11, 0xBF, 0xB1, 0x1E, 0xC0, 0x34,
},
- 285},
+ 285,
+ true},
{{
0x49, 0xCB, 0xD8, 0x3C, 0x03, 0xCA, 0xBF, 0xA0, 0x71, 0x3B, 0x97,
0xBC, 0x96, 0x48, 0x1D, 0x03, 0x5F, 0xD4, 0xEB, 0xE0, 0x6F, 0x07,
0xFA, 0xB5, 0x64, 0x0E, 0xD9, 0x23, 0x2D, 0x81, 0x10, 0xB2,
},
- 457},
+ 457,
+ true},
{{
0x4A, 0x26, 0x59, 0x66, 0x6D, 0xC0, 0x20, 0x3B, 0x91, 0x6F, 0x53,
0xD8, 0x0A, 0xD8, 0xF6, 0x1A, 0xC3, 0x0B, 0xEA, 0x16, 0x1F, 0x48,
0x5C, 0xC7, 0x52, 0x7E, 0x6A, 0x59, 0x37, 0xE4, 0x92, 0x16,
},
- 188},
+ 188,
+ true},
{{
0x4A, 0x49, 0xED, 0xBD, 0x2F, 0x8F, 0x82, 0x30, 0xBD, 0x55, 0x92,
0xB3, 0x13, 0x57, 0x3F, 0xE1, 0xC1, 0x72, 0xA4, 0x5F, 0xA9, 0x80,
0x11, 0xCC, 0x1E, 0xDD, 0xBB, 0x36, 0xAD, 0xE3, 0xFC, 0xE5,
},
- 169},
+ 169,
+ false},
{{
0x4B, 0x72, 0xDF, 0xED, 0x3E, 0xDC, 0xCB, 0x5F, 0x49, 0x45, 0x68,
0x2E, 0x29, 0x57, 0x31, 0xA0, 0x86, 0x4A, 0xC6, 0xB5, 0xB8, 0x5B,
0x19, 0x3E, 0xCD, 0x2F, 0x06, 0xB4, 0x90, 0x0C, 0x1C, 0xFD,
},
- 184},
+ 184,
+ false},
{{
0x4B, 0xA2, 0x49, 0x96, 0xDD, 0xEE, 0x6F, 0x8E, 0x1F, 0xCE, 0xC0,
0xAA, 0x9E, 0xCC, 0xFD, 0x3A, 0xA5, 0x47, 0x7B, 0x3E, 0xF8, 0xF5,
0xF8, 0x5F, 0x0A, 0x06, 0x07, 0x3F, 0x97, 0x52, 0x28, 0x57,
},
- 381},
+ 381,
+ true},
{{
0x4B, 0xA6, 0x03, 0x1C, 0xA3, 0x05, 0xB0, 0x9E, 0x53, 0xBD, 0xE3,
0x70, 0x51, 0x45, 0x48, 0x1D, 0x03, 0x32, 0xB6, 0x51, 0xFE, 0x30,
0x37, 0x0D, 0xD5, 0x25, 0x4C, 0xC4, 0xD2, 0xCB, 0x32, 0xF3,
},
- 328},
+ 328,
+ true},
{{
0x4B, 0xDC, 0x63, 0x6F, 0x48, 0xD2, 0x1F, 0xB6, 0x8C, 0x5A, 0x3C,
0xD4, 0xA2, 0x06, 0x85, 0x78, 0x80, 0x43, 0xBD, 0xB5, 0x24, 0xE7,
0xE8, 0x4D, 0x41, 0x92, 0xC4, 0x51, 0xEE, 0x34, 0x29, 0xB5,
},
- 131},
+ 131,
+ true},
{{
0x4C, 0xC2, 0x97, 0x58, 0xA2, 0xCB, 0x9B, 0x50, 0x10, 0x99, 0x87,
0xF3, 0x75, 0x37, 0xCF, 0x0C, 0x55, 0xBA, 0x2E, 0x67, 0x98, 0x93,
0x73, 0x07, 0xA0, 0x02, 0x96, 0xB0, 0x1D, 0xFF, 0xE4, 0x4A,
},
- 284},
+ 284,
+ true},
{{
0x4D, 0x40, 0xE7, 0xAF, 0x43, 0x04, 0xA0, 0x9D, 0xE8, 0x7F, 0xBF,
0x98, 0x96, 0x20, 0x4C, 0x05, 0x51, 0x41, 0xE3, 0xF8, 0x09, 0xB2,
0xFE, 0x73, 0x3B, 0xB2, 0x31, 0x0F, 0xDF, 0x98, 0xA1, 0x62,
},
- 155},
+ 155,
+ true},
{{
0x4E, 0x6C, 0x16, 0x16, 0x63, 0x71, 0x99, 0xB5, 0x07, 0x7A, 0x80,
0xAD, 0x0C, 0x22, 0x48, 0xC7, 0x25, 0xE5, 0x76, 0xFC, 0x8A, 0x71,
0x99, 0x89, 0x45, 0x6B, 0xC9, 0xCA, 0xFD, 0xDB, 0x75, 0x24,
},
- 454},
+ 454,
+ true},
{{
0x4E, 0xAD, 0xA9, 0xB5, 0x31, 0x1E, 0x71, 0x81, 0x99, 0xD9, 0x8E,
0xA8, 0x2B, 0x95, 0x00, 0x5C, 0xBA, 0x93, 0x19, 0x8A, 0xB1, 0xF9,
0x7E, 0xFC, 0xBE, 0x8D, 0xC6, 0x20, 0x16, 0x28, 0xF8, 0xAF,
},
- 100},
+ 100,
+ false},
{{
0x4E, 0xF7, 0xDA, 0xCF, 0x77, 0xED, 0xB7, 0x51, 0xF7, 0x04, 0x03,
0x5F, 0xB5, 0xC6, 0xC4, 0x42, 0x35, 0x1E, 0xC7, 0x22, 0x0A, 0xF9,
0x0B, 0xDF, 0x82, 0xFD, 0x04, 0x7B, 0xD3, 0xC2, 0x41, 0x87,
},
- 470},
+ 470,
+ true},
{{
0x4F, 0x71, 0x62, 0xB9, 0x74, 0x49, 0x1C, 0x98, 0x58, 0x5E, 0xC2,
0x8F, 0xE7, 0x59, 0xAA, 0x00, 0xC3, 0x30, 0xD0, 0xB4, 0x65, 0x19,
0x0A, 0x89, 0x6C, 0xC4, 0xB6, 0x16, 0x23, 0x18, 0x31, 0xFC,
},
- 476},
+ 476,
+ true},
{{
0x50, 0x8F, 0x8C, 0x61, 0x78, 0xAF, 0x32, 0x9B, 0xB6, 0xBB, 0x75,
0x3A, 0xB9, 0x43, 0xD9, 0x02, 0x3B, 0xE7, 0x96, 0xC3, 0xAD, 0xBB,
0x6C, 0x5C, 0xD4, 0x66, 0x4B, 0x66, 0xFE, 0xEC, 0xCA, 0xE5,
},
- 413},
+ 413,
+ true},
{{
0x50, 0x94, 0xB7, 0x3B, 0x73, 0x6A, 0xDF, 0x73, 0xA0, 0xCB, 0xF4,
0x3E, 0x27, 0xBF, 0x14, 0x40, 0x7B, 0x4A, 0x36, 0xAA, 0x36, 0x3A,
0x45, 0x7F, 0xCE, 0x33, 0x94, 0x9C, 0xEB, 0xA8, 0xE6, 0x49,
},
- 385},
+ 385,
+ true},
{{
0x50, 0xCC, 0x86, 0xBA, 0x96, 0xDB, 0x32, 0x63, 0xC7, 0x9A, 0x43,
0xEA, 0xD0, 0x75, 0x53, 0xD9, 0xF5, 0x66, 0x59, 0xE6, 0x90, 0x7E,
0x72, 0xD8, 0xC0, 0x26, 0x63, 0x7A, 0x1C, 0xDC, 0x85, 0xDC,
},
- 204},
+ 204,
+ false},
{{
0x51, 0x0D, 0x20, 0xE5, 0xC4, 0x7F, 0x63, 0xCF, 0x66, 0x6B, 0x20,
0xF6, 0x1A, 0xF6, 0x2B, 0xC0, 0x99, 0xA4, 0x2A, 0xC8, 0x24, 0xFF,
0xA4, 0x43, 0xA2, 0xDA, 0x7C, 0x90, 0xB1, 0x80, 0x8A, 0x91,
},
- 154},
+ 154,
+ false},
{{
0x51, 0x43, 0xE4, 0x75, 0x69, 0xA1, 0xD5, 0xFC, 0x86, 0x78, 0x93,
0xE0, 0xCC, 0x41, 0x2C, 0x41, 0xF5, 0x57, 0x15, 0xDA, 0x78, 0xE5,
0x9E, 0x9F, 0x8E, 0x43, 0x77, 0x00, 0x08, 0xCA, 0x42, 0xD2,
},
- 406},
+ 406,
+ true},
{{
0x51, 0x92, 0x43, 0x8E, 0xC3, 0x69, 0xD7, 0xEE, 0x0C, 0xE7, 0x1F,
0x5C, 0x6D, 0xB7, 0x5F, 0x94, 0x1E, 0xFB, 0xF7, 0x2E, 0x58, 0x44,
0x17, 0x15, 0xE9, 0x9E, 0xAB, 0x04, 0xC2, 0xC8, 0xAC, 0xEE,
},
- 58},
+ 58,
+ false},
{{
0x51, 0xB6, 0xEA, 0x64, 0x78, 0x68, 0x7B, 0x47, 0xD9, 0x63, 0xB6,
0x14, 0x90, 0x59, 0x78, 0x0C, 0xF0, 0x8A, 0x4F, 0x02, 0xF0, 0x42,
0xD6, 0x1B, 0x5B, 0xD5, 0x26, 0x39, 0x09, 0x5E, 0xE9, 0x10,
},
- 324},
+ 324,
+ true},
{{
0x52, 0x2C, 0x39, 0x60, 0x32, 0x80, 0x26, 0xA1, 0xE3, 0x22, 0x38,
0x9A, 0x8A, 0x08, 0xFE, 0xDC, 0x1B, 0x86, 0xD9, 0xC2, 0xB5, 0x9B,
0x33, 0x48, 0x4B, 0x77, 0xF7, 0xCE, 0x79, 0x06, 0x35, 0xD7,
},
- 320},
+ 320,
+ true},
{{
0x53, 0x75, 0x66, 0x26, 0x28, 0xFA, 0x0A, 0x68, 0x40, 0xAE, 0xC8,
0xC5, 0x92, 0xBF, 0x5D, 0x8D, 0xE5, 0x64, 0xED, 0x3E, 0xFB, 0x62,
0xC7, 0xC9, 0x32, 0xFC, 0xA8, 0xD7, 0x54, 0xD9, 0xBB, 0xD6,
},
- 203},
+ 203,
+ false},
{{
0x55, 0xE0, 0x0B, 0xE2, 0x77, 0xCE, 0xB0, 0x54, 0x52, 0x99, 0xF2,
0x4F, 0xD9, 0xF8, 0x77, 0xE2, 0xAC, 0xF3, 0x28, 0x52, 0xDB, 0x43,
0xFF, 0xCD, 0x29, 0xBC, 0xA7, 0x4B, 0x39, 0xB4, 0xC9, 0xFA,
},
- 287},
+ 287,
+ false},
{{
0x55, 0xF7, 0x7D, 0xE4, 0x1C, 0x03, 0x79, 0x24, 0x28, 0xF8, 0xD5,
0x18, 0xC5, 0x51, 0x04, 0x22, 0x5B, 0xE4, 0x3A, 0x55, 0x98, 0xD9,
0x26, 0xA5, 0x28, 0xAD, 0x65, 0x3E, 0x1C, 0xCE, 0xC7, 0xBF,
},
- 484},
+ 484,
+ true},
{{
0x56, 0x17, 0x4D, 0x3A, 0xD9, 0x71, 0xA8, 0x94, 0x49, 0x64, 0xB1,
0x89, 0x81, 0x1F, 0x30, 0x08, 0x49, 0x3A, 0x6A, 0x90, 0x42, 0x2E,
0x3C, 0x58, 0x04, 0xEC, 0x83, 0x8D, 0x4F, 0x94, 0xF6, 0x22,
},
- 90},
+ 90,
+ false},
{{
0x56, 0x32, 0xD9, 0x7B, 0xFA, 0x77, 0x5B, 0xF3, 0xC9, 0x9D, 0xDE,
0xA5, 0x2F, 0xC2, 0x55, 0x34, 0x10, 0x86, 0x40, 0x16, 0x72, 0x9C,
0x52, 0xDD, 0x65, 0x24, 0xC8, 0xA9, 0xC3, 0xB4, 0x48, 0x9F,
},
- 21},
+ 21,
+ false},
{{
0x56, 0x3B, 0x3C, 0xAF, 0x8C, 0xFE, 0xF3, 0x4C, 0x23, 0x35, 0xCA,
0xF5, 0x60, 0xA7, 0xA9, 0x59, 0x06, 0xE8, 0x48, 0x84, 0x62, 0xEB,
0x75, 0xAC, 0x59, 0x78, 0x48, 0x30, 0xDF, 0x9E, 0x5B, 0x2B,
},
- 10},
+ 10,
+ false},
{{
0x56, 0x7B, 0x82, 0x11, 0xFD, 0x20, 0xD3, 0xD2, 0x83, 0xEE, 0x0C,
0xD7, 0xCE, 0x06, 0x72, 0xCB, 0x9D, 0x99, 0xBC, 0x5B, 0x48, 0x7A,
0x58, 0xC9, 0xD5, 0x4E, 0xC6, 0x7F, 0x77, 0xD4, 0xA8, 0xF5,
},
- 121},
+ 121,
+ true},
{{
0x57, 0xA7, 0x42, 0xA8, 0x8D, 0x3E, 0x18, 0xFC, 0x0B, 0xC6, 0x11,
0xBC, 0x79, 0x76, 0xC2, 0x2E, 0xDC, 0x50, 0x01, 0x17, 0x57, 0x51,
0x2B, 0x1A, 0x7E, 0x2E, 0x1D, 0x06, 0x9B, 0x3E, 0xCB, 0xA0,
},
- 464},
+ 464,
+ true},
{{
0x58, 0x04, 0x46, 0x26, 0xC3, 0x4C, 0x1A, 0x7B, 0x15, 0x8D, 0xDB,
0x67, 0x6D, 0x9E, 0x2E, 0x65, 0x44, 0x3D, 0x81, 0x8D, 0xAB, 0x31,
0x16, 0x23, 0x1E, 0x2D, 0x62, 0xAB, 0x64, 0x26, 0xA0, 0xB7,
},
- 440},
+ 440,
+ true},
{{
0x58, 0x99, 0xD9, 0x13, 0xEA, 0xD1, 0x19, 0xB9, 0xCD, 0xB7, 0xBA,
0x2F, 0x30, 0xEF, 0xE0, 0xDF, 0x68, 0xAD, 0x2C, 0xD2, 0x25, 0xBD,
0xF4, 0x93, 0xE8, 0x32, 0x3A, 0x25, 0xAA, 0x4D, 0xBE, 0x23,
},
- 482},
+ 482,
+ true},
{{
0x58, 0xA2, 0xA6, 0x98, 0xD8, 0x6F, 0xD8, 0x49, 0x7D, 0x41, 0xF6,
0x8E, 0x4C, 0xAE, 0xB4, 0xA9, 0x88, 0x74, 0xF4, 0x33, 0xDA, 0x91,
0x3D, 0xD2, 0x6C, 0x5C, 0xA4, 0x4D, 0x08, 0xFF, 0x72, 0xFE,
},
- 401},
+ 401,
+ true},
{{
0x58, 0xDD, 0x61, 0xFE, 0xB3, 0x6E, 0xA7, 0xD2, 0x58, 0x72, 0x43,
0x71, 0x70, 0x91, 0x49, 0xCB, 0x12, 0x13, 0x37, 0x86, 0x4C, 0xAC,
0xB2, 0xD0, 0x99, 0x9A, 0xD2, 0x07, 0x39, 0xD0, 0x64, 0x77,
},
- 186},
+ 186,
+ false},
{{
0x59, 0x55, 0xAE, 0x29, 0x15, 0x74, 0xA9, 0x31, 0x34, 0x2C, 0xF7,
0x45, 0x0E, 0x16, 0x65, 0x2E, 0xDE, 0x1E, 0x0F, 0xB3, 0x09, 0x7E,
0x15, 0x71, 0xDF, 0xAC, 0x11, 0xC9, 0x15, 0x60, 0x15, 0x64,
},
- 81},
+ 81,
+ false},
{{
0x59, 0xDF, 0x31, 0x7B, 0xFA, 0x9F, 0x4F, 0x0A, 0xB7, 0xCA, 0x51,
0x4D, 0x77, 0x72, 0x29, 0x6A, 0xA2, 0xC7, 0x65, 0xB8, 0x76, 0x64,
0xD0, 0x8B, 0x96, 0xE5, 0x73, 0x99, 0xE3, 0x64, 0x72, 0x9C,
},
- 173},
+ 173,
+ false},
{{
0x5A, 0x88, 0x96, 0x47, 0x22, 0x0E, 0x54, 0xD6, 0xBD, 0x8A, 0x16,
0x81, 0x72, 0x24, 0x52, 0x0B, 0xB5, 0xC7, 0x8E, 0x58, 0x98, 0x4B,
0xD5, 0x70, 0x50, 0x63, 0x88, 0xB9, 0xDE, 0x0F, 0x07, 0x5F,
},
- 80},
+ 80,
+ false},
{{
0x5A, 0xAC, 0xF1, 0xB9, 0x65, 0xE8, 0x53, 0x01, 0x0F, 0xCB, 0x2A,
0x11, 0x03, 0x17, 0xD5, 0xFC, 0xE3, 0xEE, 0x35, 0x1E, 0x9C, 0xC9,
0x5B, 0xF4, 0x44, 0xA5, 0x71, 0xD7, 0xB8, 0xEF, 0x91, 0x62,
},
- 346},
+ 346,
+ true},
{{
0x5C, 0x41, 0xA7, 0x3A, 0xB2, 0xC3, 0x5D, 0xFC, 0xD7, 0x71, 0xF6,
0xFD, 0x6E, 0x3E, 0x8F, 0xAC, 0x9B, 0x46, 0x9D, 0x38, 0x6C, 0xAD,
0xDA, 0x56, 0xA9, 0x5B, 0x64, 0x6E, 0xB4, 0x8C, 0xCA, 0x34,
},
- 468},
+ 468,
+ true},
{{
0x5D, 0xEE, 0x74, 0xCC, 0x34, 0x3D, 0xB9, 0x3F, 0x8D, 0xEA, 0xF9,
0xE4, 0x1F, 0xBC, 0x65, 0xB3, 0x34, 0x25, 0x4B, 0x5B, 0x23, 0xB5,
0x68, 0xFA, 0x28, 0x14, 0xDB, 0x8B, 0x73, 0x21, 0xAC, 0x85,
},
- 296},
+ 296,
+ true},
{{
0x5E, 0x76, 0x73, 0xA1, 0x7A, 0x08, 0xD6, 0x14, 0x13, 0xCD, 0x51,
0xB5, 0x7D, 0xBA, 0xAC, 0xBE, 0xBF, 0xE5, 0xAC, 0xB9, 0x15, 0xE3,
0x96, 0x6E, 0x53, 0x21, 0xB1, 0x3E, 0xB9, 0xEF, 0xAA, 0xEB,
},
- 159},
+ 159,
+ true},
{{
0x5E, 0xFA, 0x07, 0x3F, 0x49, 0x42, 0x63, 0x44, 0x48, 0x3A, 0xB0,
0xDD, 0xBB, 0xDD, 0xA5, 0xE3, 0x59, 0x72, 0xF9, 0xC4, 0x7C, 0x74,
0xDD, 0xF9, 0x8E, 0xC4, 0x22, 0x90, 0xB2, 0x51, 0xCA, 0x97,
},
- 271},
+ 271,
+ true},
{{
0x5F, 0x66, 0x5B, 0x40, 0x60, 0xBE, 0x9E, 0xFA, 0xF6, 0xAD, 0x73,
0x9F, 0x6B, 0x39, 0xA1, 0xDB, 0x98, 0x47, 0x27, 0x7E, 0xB8, 0xDC,
0x14, 0x40, 0x45, 0x37, 0x6D, 0xE1, 0x00, 0x9E, 0x31, 0x27,
},
- 164},
+ 164,
+ true},
{{
0x60, 0x46, 0x13, 0x68, 0x79, 0xE5, 0x64, 0x50, 0x40, 0x0F, 0x7D,
0xB2, 0xEC, 0xD0, 0xDF, 0x1B, 0x88, 0xF6, 0x67, 0xC1, 0xE3, 0xFF,
0xFC, 0x52, 0x96, 0x4F, 0xF9, 0xE2, 0xE4, 0x8E, 0x85, 0xF5,
},
- 344},
+ 344,
+ true},
{{
0x61, 0x06, 0xC0, 0xE3, 0xA0, 0xA2, 0x99, 0x83, 0x18, 0x75, 0x12,
0x7B, 0xD7, 0xD3, 0xCC, 0x18, 0x59, 0x80, 0x3D, 0x51, 0x1C, 0xAC,
0x11, 0xEB, 0x6E, 0x08, 0x40, 0xDD, 0x16, 0x6F, 0xC1, 0x0E,
},
- 176},
+ 176,
+ false},
{{
0x61, 0x61, 0x67, 0x20, 0x14, 0x33, 0xAE, 0xA6, 0xC8, 0xE5, 0xE3,
0x07, 0x0A, 0xFC, 0xAF, 0x67, 0x49, 0x18, 0x8F, 0x81, 0x4B, 0xD1,
0xAB, 0xB1, 0x79, 0xAE, 0x8D, 0xAD, 0x3A, 0xBF, 0x26, 0xEC,
},
- 141},
+ 141,
+ false},
{{
0x62, 0x55, 0x4C, 0x17, 0x00, 0x55, 0x43, 0xB2, 0x37, 0x21, 0x5F,
0x04, 0x26, 0x8D, 0xCD, 0x2F, 0xD1, 0xC4, 0x70, 0x24, 0x0A, 0xD3,
0xC8, 0x66, 0x0E, 0x25, 0xAE, 0x2C, 0x59, 0x63, 0x0F, 0x55,
},
- 97},
+ 97,
+ false},
{{
0x62, 0x8E, 0x3A, 0x11, 0x56, 0xF6, 0xFA, 0xA9, 0x2F, 0x94, 0xB4,
0x09, 0x25, 0x8D, 0x4C, 0xBA, 0x3F, 0x20, 0x47, 0x48, 0x0D, 0x30,
0x19, 0x4F, 0xAF, 0x3F, 0xBE, 0xD0, 0x5E, 0xAE, 0xB5, 0xB2,
},
- 5},
+ 5,
+ true},
{{
0x62, 0xA3, 0x1A, 0x5C, 0x73, 0x0D, 0xBA, 0x67, 0x4D, 0xDB, 0x25,
0xDE, 0x33, 0xDF, 0x14, 0x36, 0x44, 0x37, 0x5B, 0x49, 0xAF, 0x07,
0x87, 0x8A, 0x66, 0x7B, 0x81, 0x34, 0x91, 0xC7, 0x39, 0x71,
},
- 323},
+ 323,
+ true},
{{
0x63, 0xD9, 0xAF, 0x9B, 0x47, 0xB1, 0x06, 0x4D, 0x49, 0xA1, 0x0E,
0x7B, 0x7F, 0xD5, 0x66, 0xDB, 0xC8, 0xCA, 0xA3, 0x99, 0x45, 0x9B,
0xFC, 0x28, 0x29, 0xC5, 0x71, 0xAD, 0x8C, 0x6E, 0xF3, 0x4A,
},
- 33},
+ 33,
+ false},
{{
0x63, 0xF1, 0xA6, 0xF7, 0x9D, 0x6E, 0x73, 0x0D, 0x10, 0x43, 0x2E,
0x63, 0x08, 0x19, 0x4F, 0xF7, 0xBC, 0x28, 0x85, 0x0A, 0xDF, 0x2B,
0xAD, 0xF7, 0x89, 0xD9, 0x71, 0x38, 0x5D, 0x85, 0x12, 0xEE,
},
- 448},
+ 448,
+ true},
{{
0x65, 0x1B, 0xD6, 0x6F, 0x5C, 0x3D, 0xC6, 0x37, 0x95, 0x7E, 0xF5,
0x18, 0x5E, 0x4F, 0xA6, 0x71, 0xC2, 0x16, 0x54, 0xB1, 0xC0, 0xEA,
0x49, 0x38, 0x4F, 0x44, 0xBC, 0xB2, 0x56, 0xA5, 0x08, 0x4C,
},
- 362},
+ 362,
+ true},
{{
0x65, 0x44, 0xFF, 0x9A, 0xDB, 0x64, 0x2C, 0x4C, 0x36, 0x98, 0xA6,
0x0D, 0x81, 0x43, 0xB6, 0xB9, 0x3B, 0xCE, 0xF0, 0x13, 0x65, 0xB5,
0x40, 0xF6, 0x14, 0xDC, 0xC2, 0xA4, 0x5A, 0xB9, 0x4D, 0x31,
},
- 98},
+ 98,
+ false},
{{
0x65, 0x9C, 0xB3, 0x68, 0xAC, 0x56, 0x99, 0x8B, 0xD0, 0x7A, 0xF2,
0xCA, 0xFC, 0x5F, 0xB9, 0x3F, 0x8E, 0x79, 0x47, 0x4A, 0xCC, 0xC2,
0xA6, 0xCF, 0x1A, 0xC9, 0xF2, 0x19, 0x2D, 0x13, 0x63, 0x60,
},
- 221},
+ 221,
+ true},
{{
0x66, 0xB0, 0x05, 0x39, 0x82, 0x6A, 0x37, 0x48, 0x49, 0x30, 0x19,
0x1E, 0x02, 0x8F, 0x62, 0xDA, 0xB1, 0xCB, 0xC8, 0x9B, 0x3A, 0xCD,
0x47, 0x2D, 0xC4, 0xE5, 0x90, 0x5E, 0x47, 0xBF, 0x73, 0x64,
},
- 428},
+ 428,
+ true},
{{
0x67, 0x40, 0x39, 0xE4, 0x72, 0x56, 0x19, 0x63, 0xC8, 0xCB, 0x00,
0xD2, 0x1A, 0x97, 0xA9, 0x0A, 0x18, 0xBB, 0x8A, 0x1C, 0x4C, 0x31,
0x7A, 0xC6, 0x7E, 0x38, 0x2A, 0x65, 0x2B, 0xB5, 0x73, 0xC0,
},
- 216},
+ 216,
+ true},
{{
0x67, 0x56, 0x05, 0xF1, 0x56, 0x7E, 0x25, 0xFB, 0xD2, 0x52, 0x6B,
0xEF, 0xEA, 0x2A, 0xEF, 0xBD, 0xB2, 0x27, 0x9F, 0x3E, 0x1B, 0xAA,
0x3A, 0x30, 0x3A, 0xE7, 0x55, 0x5D, 0x1B, 0xDA, 0x3E, 0xE4,
},
- 198},
+ 198,
+ false},
{{
0x67, 0x6B, 0x9F, 0xF3, 0x03, 0xED, 0xE1, 0x80, 0xFB, 0x95, 0xA4,
0x73, 0x6F, 0xB4, 0xD3, 0x15, 0x30, 0x32, 0xC0, 0x14, 0x44, 0x4F,
0x63, 0xA2, 0x07, 0x4C, 0x41, 0xB9, 0x8B, 0x51, 0xE0, 0xBD,
},
- 452},
+ 452,
+ true},
{{
0x67, 0xA8, 0x42, 0x64, 0xD4, 0x2E, 0x20, 0x4A, 0x9A, 0x5B, 0x0A,
0x36, 0x67, 0xB9, 0x51, 0xDB, 0x22, 0xC5, 0x05, 0xDF, 0x95, 0xED,
0x98, 0x3B, 0x5E, 0x8C, 0x4D, 0x1F, 0xCE, 0x77, 0xAF, 0x43,
},
- 480},
+ 480,
+ true},
{{
0x67, 0xDC, 0x4F, 0x32, 0xFA, 0x10, 0xE7, 0xD0, 0x1A, 0x79, 0xA0,
0x73, 0xAA, 0x0C, 0x9E, 0x02, 0x12, 0xEC, 0x2F, 0xFC, 0x3D, 0x77,
0x9E, 0x0A, 0xA7, 0xF9, 0xC0, 0xF0, 0xE1, 0xC2, 0xC8, 0x93,
},
- 104},
+ 104,
+ false},
{{
0x67, 0xEA, 0x19, 0x32, 0x43, 0xAE, 0x38, 0x39, 0x39, 0xB5, 0xAD,
0x9E, 0x35, 0x6A, 0x6B, 0x2B, 0xF9, 0x3A, 0x93, 0xBC, 0xDC, 0xF8,
0x28, 0xA4, 0x70, 0x82, 0x49, 0x78, 0x83, 0x08, 0x3F, 0x86,
},
- 126},
+ 126,
+ true},
{{
0x68, 0x27, 0x47, 0xF8, 0xBA, 0x62, 0x1B, 0x87, 0xCD, 0xD3, 0xBC,
0x29, 0x5E, 0xD5, 0xCA, 0xBC, 0xE7, 0x22, 0xA1, 0xC0, 0xC0, 0x36,
0x3D, 0x1D, 0x68, 0xB3, 0x89, 0x28, 0xD2, 0x78, 0x7F, 0x1E,
},
- 487},
+ 487,
+ true},
{{
0x68, 0x9B, 0xF4, 0x5B, 0x30, 0x83, 0xFD, 0xEA, 0xD5, 0x5F, 0x14,
0x7F, 0xD1, 0x05, 0xE3, 0xCF, 0x21, 0x8A, 0xD5, 0x8E, 0xDF, 0x3E,
0x4B, 0x30, 0x1C, 0x0C, 0x5E, 0xEE, 0xA6, 0xCF, 0x21, 0x0D,
},
- 429},
+ 429,
+ true},
{{
0x68, 0xC3, 0x69, 0x22, 0x14, 0x72, 0x4D, 0x4B, 0x55, 0xA7, 0x60,
0xF4, 0x70, 0xB4, 0xFC, 0xA8, 0xB5, 0xE0, 0xFE, 0x1D, 0x72, 0x9C,
0xFF, 0x22, 0xFE, 0xB4, 0xCA, 0x88, 0xAC, 0xD3, 0x98, 0x09,
},
- 231},
+ 231,
+ true},
{{
0x6A, 0x43, 0x6B, 0x58, 0xD9, 0xD8, 0x30, 0xE8, 0xD5, 0xB8, 0xA6,
0x42, 0x50, 0x5A, 0xD6, 0xB4, 0x14, 0x06, 0xAD, 0xCD, 0x68, 0x94,
0xD9, 0x41, 0x4F, 0x7B, 0xE0, 0xA1, 0x46, 0x7B, 0xAD, 0xB7,
},
- 426},
+ 426,
+ true},
{{
0x6A, 0x7B, 0x14, 0x82, 0x12, 0x70, 0x02, 0xF9, 0x00, 0x5A, 0x87,
0x35, 0x6E, 0x1D, 0xC3, 0xE0, 0x0B, 0x70, 0xBB, 0xBF, 0xA7, 0x95,
0x02, 0x4F, 0xF8, 0xBE, 0xFF, 0x74, 0xC4, 0x25, 0x9B, 0x75,
},
- 421},
+ 421,
+ true},
{{
0x6B, 0x1A, 0x50, 0x5E, 0x02, 0x46, 0xF2, 0xF6, 0x0C, 0x49, 0x0F,
0xF0, 0xC0, 0x97, 0xA7, 0xBE, 0x27, 0x21, 0x0C, 0xBB, 0x75, 0x00,
0x23, 0x7F, 0x88, 0xB0, 0xCD, 0x48, 0x29, 0x8B, 0xC9, 0xB8,
},
- 191},
+ 191,
+ false},
{{
0x6B, 0x3B, 0x57, 0xE9, 0xEC, 0x88, 0xD1, 0xBB, 0x3D, 0x01, 0x63,
0x7F, 0xF3, 0x3C, 0x76, 0x98, 0xB3, 0xC9, 0x75, 0x82, 0x55, 0xE9,
0xF0, 0x1E, 0xA9, 0x17, 0x8F, 0x3E, 0x7F, 0x3B, 0x2B, 0x52,
},
- 194},
+ 194,
+ false},
{{
0x6B, 0x86, 0xDE, 0x96, 0xA6, 0x58, 0xA5, 0x68, 0x20, 0xA4, 0xF3,
0x5D, 0x90, 0xDB, 0x6C, 0x3E, 0xFD, 0xD5, 0x74, 0xCE, 0x94, 0xB9,
0x09, 0xCB, 0x0D, 0x7F, 0xF1, 0x7C, 0x3C, 0x18, 0x9D, 0x83,
},
- 261},
+ 261,
+ true},
{{
0x6B, 0xCF, 0xC8, 0x6C, 0x8D, 0xDC, 0x2A, 0xF2, 0xE6, 0xA1, 0x18,
0x0A, 0x2D, 0xDA, 0xBB, 0x37, 0xB7, 0xEA, 0x37, 0x55, 0x31, 0x6B,
0x64, 0xB9, 0xB8, 0x95, 0x1B, 0xF0, 0xCA, 0x35, 0x1F, 0x06,
},
- 20},
+ 20,
+ false},
{{
0x6C, 0x46, 0x4B, 0x9A, 0x5B, 0x23, 0x3A, 0x5E, 0x87, 0x4D, 0xA7,
0x65, 0xC2, 0x6F, 0x04, 0x50, 0x10, 0xD2, 0xDD, 0xCF, 0xF4, 0x57,
0x94, 0xF0, 0xB4, 0xC7, 0xE4, 0xAA, 0xFA, 0x50, 0x14, 0x95,
},
- 137},
+ 137,
+ false},
{{
0x6C, 0x5C, 0xBF, 0x02, 0xC1, 0x84, 0x91, 0x66, 0x27, 0x8F, 0x1C,
0xD1, 0xC8, 0x35, 0x83, 0xA1, 0x47, 0xFB, 0x7B, 0xC9, 0x5E, 0x28,
0x9B, 0x27, 0x63, 0x66, 0x93, 0x5E, 0x31, 0x53, 0xF3, 0x02,
},
- 277},
+ 277,
+ true},
{{
0x6C, 0xAE, 0x87, 0xC5, 0x58, 0xD2, 0x44, 0x15, 0x68, 0xE3, 0x82,
0x70, 0xA8, 0xDD, 0x8F, 0xF4, 0x84, 0xA2, 0x59, 0xDC, 0x4F, 0x3C,
0xE9, 0x4C, 0xCF, 0x43, 0x4C, 0x1F, 0xA9, 0x98, 0x11, 0xF6,
},
- 325},
+ 325,
+ true},
{{
0x6D, 0x28, 0xF9, 0xE4, 0x05, 0x14, 0x8B, 0x69, 0x02, 0x7D, 0xA9,
0x90, 0x81, 0x52, 0x11, 0xC8, 0x58, 0x84, 0x1C, 0x54, 0x3F, 0xEC,
0xED, 0x00, 0x8C, 0x23, 0x80, 0x21, 0x98, 0x3C, 0x09, 0x5A,
},
- 376},
+ 376,
+ true},
{{
0x6D, 0x6F, 0x0C, 0x34, 0x09, 0x71, 0xA2, 0x18, 0xA3, 0x1D, 0x10,
0x33, 0x0E, 0xA9, 0xAE, 0x7C, 0x7A, 0x65, 0x50, 0x53, 0x4C, 0x6E,
0xEF, 0xED, 0xDD, 0x21, 0x18, 0xE1, 0x14, 0xDB, 0x47, 0x3E,
},
- 202},
+ 202,
+ false},
{{
0x6D, 0xBF, 0xAE, 0x00, 0xD3, 0x7B, 0x9C, 0xD7, 0x3F, 0x8F, 0xB4,
0x7D, 0xE6, 0x59, 0x17, 0xAF, 0x00, 0xE0, 0xDD, 0xDF, 0x42, 0xDB,
0xCE, 0xAC, 0x20, 0xC1, 0x7C, 0x02, 0x75, 0xEE, 0x20, 0x95,
},
- 117},
+ 117,
+ false},
{{
0x6E, 0x36, 0x4B, 0x61, 0x33, 0xDE, 0xEF, 0xDC, 0xBB, 0x21, 0x27,
0x3C, 0x5F, 0x44, 0x5A, 0x20, 0xAF, 0xBC, 0x05, 0x03, 0x8D, 0x5B,
0x02, 0x1C, 0x0C, 0x21, 0x53, 0x03, 0x90, 0x16, 0x34, 0x5B,
},
- 193},
+ 193,
+ false},
{{
0x6F, 0x3E, 0x07, 0x7F, 0xE5, 0x50, 0x46, 0x46, 0xC0, 0x19, 0x1A,
0xFC, 0xE4, 0x94, 0xE4, 0xEB, 0x68, 0x18, 0x3E, 0x39, 0x8F, 0x5A,
0x4D, 0xC0, 0x56, 0x69, 0xF8, 0xB6, 0xE6, 0xE6, 0x82, 0xFE,
},
- 151},
+ 151,
+ true},
{{
0x70, 0x06, 0xA3, 0x83, 0x11, 0xE5, 0x8F, 0xB1, 0x93, 0x48, 0x42,
0x33, 0x21, 0x82, 0x10, 0xC6, 0x61, 0x25, 0xA0, 0xE4, 0xA8, 0x26,
0xAE, 0xD5, 0x39, 0xAC, 0x56, 0x1D, 0xFB, 0xFB, 0xD9, 0x03,
},
- 227},
+ 227,
+ true},
{{
0x70, 0x16, 0x27, 0x0B, 0x60, 0xB2, 0x8C, 0x6E, 0x17, 0x7E, 0xDE,
0xBD, 0x71, 0x80, 0x07, 0xDF, 0xD3, 0x31, 0x0C, 0x64, 0xA7, 0x37,
0xB7, 0xDB, 0x01, 0xA0, 0x76, 0x90, 0xC3, 0x43, 0xBC, 0x27,
},
- 389},
+ 389,
+ true},
{{
0x70, 0x21, 0x16, 0xCC, 0xD8, 0xBF, 0x23, 0xE1, 0x64, 0x66, 0xF0,
0xE0, 0xDB, 0xA0, 0xED, 0x6A, 0x23, 0x9A, 0x9C, 0x1C, 0xD6, 0xA8,
0xF5, 0xA6, 0x6B, 0x39, 0xAF, 0x35, 0x95, 0x02, 0x03, 0x85,
},
- 92},
+ 92,
+ false},
{{
0x70, 0x6B, 0xB1, 0x01, 0x7C, 0x85, 0x5C, 0x59, 0x16, 0x9B, 0xAD,
0x5C, 0x17, 0x81, 0xCF, 0x59, 0x7F, 0x12, 0xD2, 0xCA, 0xD2, 0xF6,
0x3D, 0x1A, 0x4A, 0xA3, 0x74, 0x93, 0x80, 0x0F, 0xFB, 0x80,
},
- 18},
+ 18,
+ false},
{{
0x71, 0x9C, 0xF5, 0xB3, 0x61, 0x92, 0xE7, 0xBD, 0xE6, 0x50, 0xCC,
0x91, 0x34, 0x1E, 0x6F, 0x64, 0x9D, 0xBB, 0x8C, 0x3E, 0xE4, 0x8B,
0xAC, 0xAA, 0x97, 0xFA, 0x0E, 0x05, 0xB6, 0x37, 0x4B, 0x41,
},
- 242},
+ 242,
+ true},
{{
0x71, 0xED, 0x91, 0x8A, 0x7A, 0xC6, 0xD1, 0x7B, 0x38, 0x49, 0xC2,
0x01, 0x80, 0xB3, 0xE7, 0x33, 0x46, 0x91, 0xBC, 0x5F, 0xB7, 0x33,
0x77, 0xF0, 0x07, 0x0A, 0xFA, 0x0B, 0xE7, 0x89, 0xB2, 0xD1,
},
- 446},
+ 446,
+ true},
{{
0x76, 0xEE, 0x85, 0x90, 0x37, 0x4C, 0x71, 0x54, 0x37, 0xBB, 0xCA,
0x6B, 0xBA, 0x60, 0x28, 0xEA, 0xDD, 0xE2, 0xDC, 0x6D, 0xBB, 0xB8,
0xC3, 0xF6, 0x10, 0xE8, 0x51, 0xF1, 0x1D, 0x1A, 0xB7, 0xF5,
},
- 42},
+ 42,
+ false},
{{
0x77, 0x29, 0x07, 0x17, 0x61, 0x4B, 0x25, 0xF1, 0x29, 0x64, 0xEB,
0xDB, 0x38, 0xB5, 0xF8, 0x3C, 0xAA, 0xDC, 0x0F, 0x6C, 0x36, 0xB0,
0x77, 0x7F, 0x88, 0x0F, 0xC6, 0xDE, 0xE1, 0xD3, 0x39, 0xCC,
},
- 127},
+ 127,
+ false},
{{
0x77, 0x2F, 0xCC, 0xCA, 0x7D, 0x16, 0x46, 0xD6, 0x06, 0x28, 0x13,
0x4F, 0xF2, 0xE6, 0xE7, 0xF5, 0xBA, 0x09, 0x58, 0x98, 0xBE, 0x59,
0x69, 0x8B, 0xCE, 0x9D, 0x15, 0xF9, 0x6F, 0x69, 0xA9, 0xF3,
},
- 12},
+ 12,
+ false},
{{
0x78, 0x2D, 0x7E, 0x61, 0xE1, 0x32, 0x3D, 0x2A, 0xAF, 0xB8, 0x77,
0xBE, 0x34, 0xEE, 0x1D, 0xE0, 0xC1, 0x34, 0x51, 0x36, 0xD4, 0xFC,
0xB3, 0xC9, 0x45, 0x93, 0x7F, 0x6A, 0x67, 0xB4, 0x12, 0xFE,
},
- 435},
+ 435,
+ true},
{{
0x78, 0xCF, 0x3D, 0x3C, 0x72, 0xDA, 0xF9, 0x1C, 0xC5, 0x1B, 0x87,
0x13, 0x57, 0xA5, 0x51, 0xCF, 0x95, 0xB8, 0x37, 0xD0, 0x74, 0xC2,
0x70, 0xB0, 0x8F, 0xAC, 0xD4, 0x63, 0xA8, 0xD3, 0x9B, 0xB3,
},
- 437},
+ 437,
+ true},
{{
0x7A, 0xED, 0xDD, 0xF3, 0x6B, 0x18, 0xF8, 0xAC, 0xB7, 0x37, 0x9F,
0xE1, 0xCE, 0x18, 0x32, 0x12, 0xB2, 0x35, 0x0D, 0x07, 0x88, 0xAB,
0xE0, 0xE8, 0x24, 0x57, 0xBE, 0x9B, 0xAD, 0xAD, 0x6D, 0x54,
},
- 195},
+ 195,
+ true},
{{
0x7A, 0xFE, 0x4B, 0x07, 0x1A, 0x2F, 0x1F, 0x46, 0xF8, 0xBA, 0x94,
0x4A, 0x26, 0xD5, 0x84, 0xD5, 0x96, 0x0B, 0x92, 0xFB, 0x48, 0xC3,
0xBA, 0x1B, 0x7C, 0xAB, 0x84, 0x90, 0x5F, 0x32, 0xAA, 0xCD,
},
- 291},
+ 291,
+ false},
{{
0x7C, 0x3B, 0x46, 0xD9, 0xBE, 0x8F, 0x27, 0x41, 0xF9, 0x80, 0x03,
0x95, 0x21, 0x85, 0x8E, 0x4C, 0xDD, 0x30, 0x77, 0x4F, 0xB3, 0x2B,
0x3B, 0x21, 0xCE, 0xEA, 0x06, 0xAA, 0x79, 0xC6, 0xAA, 0xC6,
},
- 341},
+ 341,
+ true},
{{
0x7C, 0xAA, 0x03, 0x46, 0x51, 0x24, 0x59, 0x0C, 0x60, 0x1E, 0x56,
0x7E, 0x52, 0x14, 0x8E, 0x95, 0x2C, 0x0C, 0xFF, 0xE8, 0x90, 0x00,
0x53, 0x0F, 0xE0, 0xD9, 0x5B, 0x6D, 0x50, 0xEA, 0xAE, 0x41,
},
- 86},
+ 86,
+ false},
{{
0x7C, 0xD6, 0x7C, 0x24, 0x8F, 0x69, 0xD8, 0x3F, 0xC2, 0xF9, 0xBB,
0x01, 0xDC, 0xB1, 0xF7, 0xAD, 0x67, 0xA3, 0x63, 0xD0, 0x46, 0x04,
0x37, 0x96, 0xD0, 0x98, 0x4C, 0x3A, 0x23, 0x1F, 0x6B, 0xB0,
},
- 294},
+ 294,
+ false},
{{
0x7D, 0x43, 0x4D, 0x1D, 0xAD, 0xA2, 0xA1, 0x54, 0xD4, 0x9F, 0x47,
0x3E, 0x38, 0x13, 0x10, 0xB8, 0x3E, 0xE5, 0x8D, 0x29, 0x0A, 0x13,
0x45, 0x51, 0x82, 0xD7, 0x7F, 0x19, 0x62, 0xDF, 0x55, 0xEE,
},
- 306},
+ 306,
+ true},
{{
0x7D, 0x6C, 0x3E, 0xBF, 0x9E, 0xA7, 0x35, 0xD1, 0x85, 0x4B, 0xEE,
0xA7, 0xCB, 0x94, 0x1A, 0xB1, 0xE3, 0x50, 0x35, 0x15, 0xE0, 0x87,
0xBB, 0xB5, 0xBE, 0x69, 0x5D, 0x05, 0xF2, 0xF5, 0x56, 0xE4,
},
- 473},
+ 473,
+ true},
{{
0x7E, 0x0E, 0xAD, 0x76, 0xBB, 0x68, 0x19, 0xDC, 0x2F, 0x54, 0x51,
0x1A, 0x84, 0x35, 0x4F, 0x6E, 0x8B, 0x30, 0x7B, 0x9D, 0xD8, 0x20,
0x58, 0xEA, 0x6C, 0x00, 0x4F, 0x01, 0xD9, 0xDD, 0xA5, 0xDF,
},
- 181},
+ 181,
+ false},
{{
0x7E, 0x6A, 0xCD, 0x85, 0x3C, 0xAC, 0xC6, 0x93, 0x2E, 0x9B, 0x51,
0x9F, 0xDA, 0xD1, 0xBE, 0xB5, 0x15, 0xED, 0x2A, 0x2D, 0x00, 0x25,
0xCF, 0xD3, 0x98, 0xC3, 0xAC, 0x1F, 0x0D, 0xBB, 0x75, 0x4B,
},
- 395},
+ 395,
+ true},
{{
0x7E, 0x87, 0x82, 0xC1, 0x50, 0xCE, 0x39, 0x52, 0xF8, 0x02, 0xE6,
0x36, 0x02, 0x3A, 0x5D, 0x3E, 0x95, 0xBB, 0x5D, 0x68, 0xE3, 0x3E,
0x85, 0xAD, 0xB2, 0xBA, 0x17, 0x81, 0x25, 0xCE, 0xBF, 0x15,
},
- 30},
+ 30,
+ false},
{{
0x7F, 0x1D, 0xEC, 0x8B, 0x03, 0x19, 0x54, 0x8A, 0x05, 0x6D, 0xE5,
0xBB, 0x52, 0x1B, 0xD9, 0x3E, 0xB7, 0x4E, 0x6A, 0x76, 0xF2, 0x8D,
0xFF, 0xB7, 0x5B, 0x45, 0xA5, 0x3B, 0x77, 0x5A, 0xF7, 0xAB,
},
- 274},
+ 274,
+ true},
{{
0x7F, 0x42, 0x96, 0xFC, 0x5B, 0x6A, 0x4E, 0x3B, 0x35, 0xD3, 0xC3,
0x69, 0x62, 0x3E, 0x36, 0x4A, 0xB1, 0xAF, 0x38, 0x1D, 0x8F, 0xA7,
0x12, 0x15, 0x33, 0xC9, 0xD6, 0xC6, 0x33, 0xEA, 0x24, 0x61,
},
- 209},
+ 209,
+ false},
{{
0x7F, 0x7C, 0x88, 0xA7, 0x7D, 0x4D, 0x3B, 0x44, 0xC3, 0x3B, 0x3C,
0x03, 0x0B, 0xC8, 0x3F, 0x1A, 0x26, 0xC2, 0x0D, 0x49, 0x17, 0x7C,
0xA7, 0x74, 0x5D, 0x91, 0xD9, 0xDE, 0x17, 0xE0, 0x8F, 0x14,
},
- 349},
+ 349,
+ true},
{{
0x80, 0x5C, 0x66, 0x96, 0x26, 0x6B, 0x96, 0xB1, 0x47, 0x46, 0x8A,
0x32, 0x1E, 0xBA, 0x9E, 0xB8, 0xB5, 0x96, 0x8F, 0x2C, 0x47, 0x7C,
0xDD, 0x95, 0xFD, 0xAD, 0xD1, 0xFC, 0x63, 0xDD, 0x61, 0x4B,
},
- 298},
+ 298,
+ true},
{{
0x80, 0x8D, 0x68, 0xB3, 0xFA, 0xB4, 0x88, 0x4A, 0x5F, 0x97, 0x1A,
0xCE, 0x7D, 0x10, 0x55, 0x0D, 0x7A, 0x95, 0xA1, 0x63, 0x77, 0x4F,
0x3E, 0xC3, 0x6A, 0xFF, 0xFB, 0x21, 0x3F, 0xBE, 0x4C, 0x74,
},
- 84},
+ 84,
+ false},
{{
0x80, 0x9F, 0x2B, 0xAA, 0xE3, 0x5A, 0xFB, 0x4F, 0x36, 0xBD, 0x64,
0x76, 0xCE, 0x75, 0xC2, 0x00, 0x10, 0x77, 0x90, 0x1B, 0x6A, 0xF5,
0xC4, 0xDA, 0xB8, 0x2E, 0x18, 0x8C, 0x6B, 0x95, 0xC1, 0xA1,
},
- 258},
+ 258,
+ true},
{{
0x80, 0xDB, 0xFB, 0x97, 0xBD, 0xD3, 0x92, 0x6B, 0xAE, 0xE4, 0x1F,
0x73, 0xC5, 0x58, 0x8F, 0xAA, 0x17, 0xD7, 0x07, 0xB0, 0x3A, 0xDF,
0x49, 0x07, 0xA2, 0xBC, 0x67, 0x7F, 0x3E, 0xF1, 0x71, 0x7C,
},
- 214},
+ 214,
+ true},
{{
0x81, 0x6B, 0xA0, 0xBF, 0xDF, 0x5F, 0xD6, 0x4D, 0x56, 0x8E, 0xC0,
0xD0, 0x52, 0xF7, 0x11, 0x64, 0xD9, 0xE2, 0xCC, 0xAE, 0x12, 0xE0,
0x21, 0x9E, 0xD6, 0xCD, 0x81, 0xE7, 0xE8, 0x45, 0xFB, 0x84,
},
- 423},
+ 423,
+ true},
{{
0x81, 0xA9, 0x8F, 0xC7, 0x88, 0xC3, 0x5F, 0x55, 0x76, 0x45, 0xA9,
0x52, 0x24, 0xE5, 0x0C, 0xD1, 0xDA, 0xC8, 0xFF, 0xB2, 0x09, 0xDC,
0x1E, 0x56, 0x88, 0xAA, 0x29, 0x20, 0x5F, 0x13, 0x22, 0x18,
},
- 166},
+ 166,
+ true},
{{
0x82, 0xB5, 0xF8, 0x4D, 0xAF, 0x47, 0xA5, 0x9C, 0x7A, 0xB5, 0x21,
0xE4, 0x98, 0x2A, 0xEF, 0xA4, 0x0A, 0x53, 0x40, 0x6A, 0x3A, 0xEC,
0x26, 0x03, 0x9E, 0xFA, 0x6B, 0x2E, 0x0E, 0x72, 0x44, 0xC1,
},
- 183},
+ 183,
+ false},
{{
0x84, 0xAA, 0xC0, 0x93, 0xE0, 0x8C, 0x49, 0xDB, 0xFF, 0xF8, 0xE5,
0x60, 0x75, 0x92, 0x48, 0xDB, 0xE6, 0x71, 0x35, 0xB3, 0x72, 0xB2,
0x3D, 0x2A, 0x88, 0x1D, 0x5F, 0x99, 0xCB, 0xB1, 0x91, 0xE8,
},
- 276},
+ 276,
+ true},
{{
0x85, 0xA3, 0xD8, 0x1D, 0x2A, 0xD0, 0xC7, 0x9D, 0xF0, 0xA7, 0x96,
0x84, 0xE0, 0xE2, 0x66, 0x60, 0x09, 0xA0, 0x9D, 0xE1, 0x57, 0x60,
0xEA, 0x1D, 0x76, 0xCF, 0x0E, 0xE7, 0xB2, 0x82, 0x5D, 0xBD,
},
- 410},
+ 410,
+ true},
{{
0x85, 0xD2, 0x6B, 0xE9, 0x0D, 0x93, 0x4F, 0xCC, 0xDB, 0x4F, 0xF7,
0xB3, 0x8D, 0x8C, 0x79, 0xCA, 0x76, 0x52, 0xB8, 0x16, 0xD6, 0xA5,
0x24, 0x46, 0xCA, 0x84, 0x28, 0xA6, 0xB8, 0x5D, 0xC5, 0x7C,
},
- 273},
+ 273,
+ true},
{{
0x86, 0x0A, 0x7F, 0x19, 0x21, 0x0D, 0x5E, 0xAD, 0x05, 0x7A, 0x78,
0x53, 0x2B, 0x80, 0x95, 0x14, 0x53, 0xCB, 0x29, 0x07, 0x31, 0x5F,
0x3B, 0xA7, 0xAA, 0x47, 0xB6, 0x98, 0x97, 0xD7, 0x0F, 0x3F,
},
- 249},
+ 249,
+ true},
{{
0x86, 0xA6, 0x8F, 0x05, 0x00, 0x34, 0x12, 0x6A, 0x54, 0x0D, 0x39,
0xDB, 0x2C, 0x5F, 0x91, 0x7E, 0xF6, 0x6A, 0x94, 0xFB, 0x96, 0x19,
0xFA, 0x1E, 0xCD, 0x82, 0x7C, 0xEA, 0x46, 0xBA, 0x0C, 0xB0,
},
- 170},
+ 170,
+ false},
{{
0x86, 0xC1, 0x3A, 0x34, 0x08, 0xDD, 0x1A, 0xA7, 0x7E, 0xE8, 0xB6,
0x94, 0x7C, 0x03, 0x95, 0x87, 0x72, 0xF5, 0x31, 0x24, 0x8C, 0x16,
0x27, 0xBE, 0xFB, 0x2C, 0x4F, 0x4B, 0x04, 0xD0, 0x44, 0x96,
},
- 53},
+ 53,
+ true},
{{
0x86, 0xC8, 0x4B, 0x1C, 0x3A, 0x66, 0xF4, 0x28, 0x5A, 0xF7, 0x97,
0x05, 0x24, 0x67, 0xE3, 0xED, 0x23, 0x6F, 0xD2, 0x98, 0x6F, 0x03,
0x3C, 0x02, 0xC4, 0x77, 0x1B, 0xE0, 0xB9, 0x70, 0x48, 0x2A,
},
- 366},
+ 366,
+ true},
{{
0x87, 0x15, 0x7A, 0x75, 0x85, 0xF4, 0xD0, 0x3B, 0x00, 0xA3, 0x98,
0x46, 0x1E, 0x16, 0x4E, 0x48, 0x06, 0xE1, 0xB3, 0xF4, 0x6D, 0x03,
0xAF, 0xBD, 0xC9, 0xDE, 0xF4, 0xE4, 0x77, 0x8B, 0xE2, 0xE9,
},
- 378},
+ 378,
+ true},
{{
0x87, 0x1A, 0x91, 0x94, 0xF4, 0xEE, 0xD5, 0xB3, 0x12, 0xFF, 0x40,
0xC8, 0x4C, 0x1D, 0x52, 0x4A, 0xED, 0x2F, 0x77, 0x8B, 0xBF, 0xF2,
0x5F, 0x13, 0x8C, 0xF8, 0x1F, 0x68, 0x0A, 0x7A, 0xDC, 0x67,
},
- 483},
+ 483,
+ true},
{{
0x87, 0xAF, 0x34, 0xD6, 0x6F, 0xB3, 0xF2, 0xFD, 0xF3, 0x6E, 0x09,
0x11, 0x1E, 0x9A, 0xBA, 0x2F, 0x6F, 0x44, 0xB2, 0x07, 0xF3, 0x86,
0x3F, 0x3D, 0x0B, 0x54, 0xB2, 0x50, 0x23, 0x90, 0x9A, 0xA5,
},
- 75},
+ 75,
+ false},
{{
0x88, 0x1A, 0x1B, 0x9E, 0xDF, 0x69, 0xAD, 0xE1, 0x41, 0x83, 0x9A,
0xE8, 0x67, 0x3D, 0x31, 0xB4, 0xF4, 0xD4, 0x7F, 0x12, 0x6C, 0xA0,
0x8A, 0x79, 0xFF, 0x06, 0x5D, 0xC9, 0xA6, 0x90, 0xF4, 0xA3,
},
- 322},
+ 322,
+ true},
{{
0x89, 0x1F, 0xF8, 0x98, 0xE4, 0xA8, 0xD5, 0x55, 0x14, 0x00, 0x56,
0xE3, 0x17, 0x6E, 0xEA, 0x91, 0xF4, 0xD8, 0x08, 0xEE, 0x7F, 0x6D,
0x1B, 0xFB, 0xCC, 0xE6, 0xF8, 0x48, 0x07, 0x63, 0x9F, 0x91,
},
- 199},
+ 199,
+ false},
{{
0x89, 0x91, 0xE2, 0x19, 0xCE, 0x9F, 0x74, 0x47, 0x9E, 0xAF, 0xED,
0xB3, 0x53, 0x58, 0x36, 0x12, 0x1D, 0xD2, 0x33, 0xEA, 0x76, 0x8A,
0xFB, 0x9D, 0x9A, 0xC8, 0xB4, 0xA2, 0x23, 0x81, 0xA8, 0xD5,
},
- 321},
+ 321,
+ true},
{{
0x8A, 0x27, 0xB5, 0x55, 0x7B, 0x4B, 0xEC, 0x7C, 0xC0, 0x30, 0x5F,
0xBF, 0x3D, 0x53, 0xD1, 0xF7, 0x1C, 0xD3, 0xF3, 0x49, 0x10, 0xC5,
0xD6, 0x5E, 0x27, 0xEC, 0xDD, 0xB8, 0x20, 0x77, 0xBA, 0x3D,
},
- 7},
+ 7,
+ false},
{{
0x8A, 0x2A, 0xFF, 0xBD, 0x1A, 0x1C, 0x5D, 0x1B, 0xDC, 0xCB, 0xB7,
0xF5, 0x48, 0xBA, 0x99, 0x5F, 0x96, 0x68, 0x06, 0xB3, 0xFD, 0x0C,
0x3A, 0x00, 0xFA, 0xE2, 0xE5, 0x2F, 0x3C, 0x85, 0x39, 0x89,
},
- 145},
+ 145,
+ false},
{{
0x8A, 0x42, 0xEE, 0xAD, 0xBC, 0x8B, 0x21, 0xA3, 0x5C, 0x4B, 0x3A,
0xAD, 0xD7, 0xDF, 0xBC, 0xBD, 0x2E, 0xD1, 0xB1, 0xDA, 0x12, 0xE8,
0xC4, 0x5A, 0x53, 0x4D, 0xA9, 0x06, 0x07, 0xE5, 0x64, 0xFD,
},
- 392},
+ 392,
+ true},
{{
0x8A, 0x90, 0x3B, 0x60, 0x0A, 0x08, 0x0B, 0x38, 0xDF, 0xE2, 0x0D,
0xFB, 0x6A, 0xCD, 0x23, 0x12, 0x2F, 0x64, 0x62, 0x0E, 0x58, 0x08,
0xB9, 0xFC, 0x86, 0x88, 0x95, 0x2F, 0xC1, 0xA3, 0x55, 0x9C,
},
- 275},
+ 275,
+ true},
{{
0x8A, 0xB4, 0xE8, 0x85, 0x56, 0xCB, 0xF8, 0x64, 0xA5, 0xE9, 0xFD,
0x50, 0x17, 0x1C, 0xD4, 0xED, 0x84, 0x24, 0xE8, 0xF0, 0x80, 0x1B,
0x99, 0xE2, 0x36, 0xC8, 0x10, 0x91, 0x59, 0x50, 0xAE, 0x4B,
},
- 370},
+ 370,
+ true},
{{
0x8A, 0xDB, 0x23, 0x85, 0x54, 0xA0, 0xCB, 0xFC, 0x3A, 0x11, 0xFE,
0xCC, 0x18, 0x3E, 0x3C, 0xD2, 0xC2, 0x3D, 0x25, 0xE7, 0x89, 0x4C,
0xF2, 0xBB, 0xAE, 0x58, 0xEB, 0x70, 0xA4, 0x4E, 0x7C, 0xF3,
},
- 234},
+ 234,
+ true},
{{
0x8B, 0x49, 0x50, 0x6A, 0x34, 0x61, 0x06, 0x3E, 0xA8, 0xCC, 0x13,
0xFF, 0xCE, 0x2B, 0x58, 0x1D, 0xE1, 0x5A, 0x94, 0xB9, 0x57, 0x09,
0x2A, 0x93, 0x12, 0x34, 0x67, 0xB8, 0x9E, 0xD8, 0x02, 0xE2,
},
- 375},
+ 375,
+ true},
{{
0x8B, 0xB5, 0x93, 0xA9, 0x3B, 0xE1, 0xD0, 0xE8, 0xA8, 0x22, 0xBB,
0x88, 0x7C, 0x54, 0x78, 0x90, 0xC3, 0xE7, 0x06, 0xAA, 0xD2, 0xDA,
0xB7, 0x62, 0x54, 0xF9, 0x7F, 0xB3, 0x6B, 0x82, 0xFC, 0x26,
},
- 175},
+ 175,
+ false},
{{
0x8B, 0xEA, 0x76, 0xEB, 0xD6, 0x13, 0x7A, 0xFF, 0x9F, 0x1E, 0xCC,
0x3C, 0x08, 0xCA, 0xF1, 0xDE, 0xC4, 0x7D, 0xB9, 0x16, 0x90, 0xD5,
0x75, 0x4C, 0x4E, 0x9F, 0x15, 0x23, 0x2C, 0x0A, 0x2E, 0x78,
},
- 418},
+ 418,
+ true},
{{
0x8D, 0x76, 0x77, 0x64, 0xB3, 0xCB, 0xDA, 0x08, 0x92, 0x9D, 0x07,
0x2A, 0x22, 0xA5, 0x61, 0xF4, 0xDC, 0xDD, 0x1B, 0xC5, 0x7D, 0x3C,
0xBD, 0xDC, 0x94, 0x8C, 0x47, 0xD2, 0xB4, 0x7F, 0x91, 0x22,
},
- 17},
+ 17,
+ false},
{{
0x8D, 0x77, 0x5A, 0x4F, 0x93, 0xCD, 0x20, 0xC1, 0x83, 0x06, 0x14,
0x4F, 0x42, 0xB5, 0x69, 0xFC, 0x2A, 0x89, 0x7E, 0xAE, 0xAE, 0xC3,
0xD3, 0xEA, 0x3C, 0xB0, 0x25, 0xD1, 0xAD, 0x4D, 0x28, 0xE7,
},
- 384},
+ 384,
+ true},
{{
0x8E, 0x15, 0xD4, 0x26, 0xCD, 0x04, 0x89, 0x8F, 0x21, 0x8B, 0xE2,
0xE5, 0xFE, 0x37, 0x84, 0xF3, 0x75, 0x09, 0x4C, 0xC4, 0x35, 0xDC,
0x61, 0xAD, 0x86, 0xC4, 0xA3, 0xC0, 0x15, 0x11, 0xDB, 0xE1,
},
- 439},
+ 439,
+ true},
{{
0x8E, 0x80, 0x46, 0xEC, 0x4C, 0xAC, 0x01, 0x5A, 0x50, 0x7C, 0xE0,
0xD2, 0xD0, 0x15, 0x4A, 0x4B, 0x40, 0xE8, 0xE4, 0x2B, 0x31, 0x65,
0xCF, 0xA5, 0x46, 0x57, 0x14, 0x35, 0x11, 0x2D, 0x17, 0xE5,
},
- 463},
+ 463,
+ true},
{{
0x8E, 0x8B, 0x56, 0xF5, 0x91, 0x8A, 0x25, 0xBD, 0x85, 0xDC, 0xE7,
0x66, 0x63, 0xFD, 0x94, 0xCC, 0x23, 0x69, 0x0F, 0x10, 0xEA, 0x95,
0x86, 0x61, 0x31, 0x71, 0xC6, 0xF8, 0x37, 0x88, 0x90, 0xD5,
},
- 239},
+ 239,
+ true},
{{
0x8E, 0xD5, 0xB4, 0xC0, 0x41, 0xB6, 0xB2, 0x93, 0xC0, 0xE6, 0x41,
0x30, 0x15, 0x06, 0x6D, 0x31, 0x84, 0x83, 0xC9, 0x01, 0xFF, 0x69,
0xE8, 0x6A, 0x52, 0x1D, 0x0C, 0xB2, 0x55, 0x69, 0xF3, 0xE8,
},
- 228},
+ 228,
+ true},
{{
0x8F, 0xD1, 0x12, 0xC3, 0xC8, 0x37, 0x0F, 0x14, 0x7D, 0x5C, 0xCD,
0x3A, 0x7D, 0x86, 0x5E, 0xB8, 0xDD, 0x54, 0x07, 0x83, 0xBA, 0xC6,
0x9F, 0xC6, 0x00, 0x88, 0xE3, 0x74, 0x3F, 0xF3, 0x33, 0x78,
},
- 77},
+ 77,
+ false},
{{
0x91, 0x19, 0xE2, 0xF4, 0x13, 0x57, 0x97, 0x77, 0x95, 0x49, 0x91,
0x70, 0x3E, 0xEE, 0x23, 0xA0, 0x45, 0x23, 0xA3, 0x12, 0xB5, 0xC6,
0x5F, 0x7F, 0x93, 0x74, 0xAA, 0x31, 0x00, 0xEB, 0xD8, 0xE7,
},
- 336},
+ 336,
+ true},
{{
0x91, 0x31, 0x19, 0xF2, 0xCD, 0x3F, 0x48, 0xAC, 0xA7, 0x4E, 0xA6,
0x44, 0x3E, 0xE5, 0x0E, 0x0D, 0xE1, 0x20, 0x2D, 0x9C, 0x54, 0xF3,
0x36, 0xDC, 0x93, 0x00, 0xAF, 0xFE, 0x97, 0xD4, 0x57, 0x7C,
},
- 394},
+ 394,
+ true},
{{
0x91, 0x50, 0x86, 0xCC, 0xD4, 0xED, 0x1E, 0xA7, 0x49, 0xB4, 0x27,
0xF6, 0xB0, 0xCE, 0xB4, 0xA0, 0xEF, 0x5B, 0x4A, 0x1C, 0xF1, 0x80,
0x70, 0x53, 0x9C, 0x0F, 0x2A, 0x75, 0x81, 0x85, 0xA3, 0x82,
},
- 224},
+ 224,
+ true},
{{
0x92, 0x7A, 0x1B, 0x85, 0x62, 0x28, 0x05, 0x76, 0xD0, 0x48, 0xC5,
0x03, 0x21, 0xAD, 0xA4, 0x3D, 0x87, 0x03, 0xD2, 0xD9, 0x52, 0x1A,
0x18, 0xC2, 0x8B, 0x8C, 0x46, 0xCC, 0x6A, 0xAE, 0x4E, 0xFD,
},
- 99},
+ 99,
+ false},
{{
0x92, 0xC4, 0x68, 0x79, 0x62, 0x6E, 0xF2, 0xCC, 0x1E, 0xCE, 0xA5,
0x0C, 0x72, 0xFB, 0x5E, 0x38, 0x58, 0x44, 0x09, 0x5F, 0x21, 0xCB,
0xF3, 0xB2, 0x83, 0xCB, 0x82, 0xE6, 0xB9, 0xFC, 0x6A, 0x58,
},
- 111},
+ 111,
+ false},
{{
0x93, 0x18, 0x22, 0x6F, 0x8C, 0x83, 0xAF, 0xE4, 0x7F, 0x5F, 0x47,
0xC2, 0x4F, 0x59, 0xCE, 0x12, 0xDB, 0xA8, 0xC7, 0x3B, 0x18, 0x1B,
0xEE, 0x6B, 0x2E, 0xA1, 0xF4, 0x0A, 0x06, 0xBC, 0x18, 0x69,
},
- 49},
+ 49,
+ false},
{{
0x93, 0x1F, 0x1C, 0xF0, 0x3A, 0x6F, 0x84, 0xC3, 0x0F, 0xF3, 0xAD,
0x86, 0x9B, 0xE3, 0xC2, 0x1A, 0x41, 0x01, 0x91, 0xCC, 0x98, 0xAC,
0x0A, 0xFC, 0x9D, 0x4E, 0x8B, 0x89, 0xBD, 0x86, 0x9D, 0xDC,
},
- 319},
+ 319,
+ true},
{{
0x93, 0x65, 0x7F, 0x85, 0x30, 0xC5, 0x96, 0xBF, 0x90, 0x9E, 0x50,
0xDA, 0x7D, 0x8D, 0x9C, 0xBB, 0x36, 0xB8, 0x24, 0xCC, 0x16, 0xAB,
0x58, 0x91, 0x37, 0xE1, 0x43, 0x80, 0x11, 0xBC, 0x99, 0x01,
},
- 282},
+ 282,
+ true},
{{
0x93, 0x92, 0xAE, 0x21, 0x49, 0x92, 0x4A, 0xDE, 0x37, 0xE6, 0x45,
0xDB, 0xA1, 0xFF, 0x4B, 0xDD, 0xDC, 0xDA, 0x2B, 0x29, 0x1B, 0x60,
0x97, 0x66, 0x9D, 0x2A, 0xFA, 0x5C, 0x7A, 0x37, 0x26, 0x19,
},
- 76},
+ 76,
+ true},
{{
0x93, 0xA9, 0xB3, 0xC9, 0x6A, 0xAE, 0x1C, 0xD6, 0x61, 0x21, 0x5D,
0x0C, 0x2A, 0x06, 0x5D, 0xA9, 0x63, 0xD7, 0x16, 0x0D, 0x1C, 0x69,
0x46, 0x21, 0xBC, 0xB2, 0x8C, 0x40, 0x6D, 0xF6, 0x4D, 0xB2,
},
- 246},
+ 246,
+ true},
{{
0x94, 0x07, 0x2A, 0xD3, 0xF5, 0x8F, 0x70, 0xF9, 0x30, 0x98, 0xE5,
0xA5, 0xF6, 0xC0, 0x4C, 0x96, 0xC7, 0x10, 0xBD, 0x84, 0x9D, 0x83,
0x18, 0x49, 0x19, 0xAE, 0x90, 0xEB, 0x89, 0x0A, 0xE4, 0x00,
},
- 85},
+ 85,
+ false},
{{
0x94, 0x15, 0xB2, 0x5D, 0xBA, 0x3B, 0xBD, 0x71, 0x14, 0x39, 0xE2,
0xA9, 0x96, 0x4B, 0x7A, 0x52, 0x56, 0xAF, 0xF3, 0xB0, 0x5C, 0x77,
0x2C, 0x8A, 0x34, 0xE6, 0xC9, 0x35, 0x66, 0xAB, 0xA6, 0x3A,
},
- 478},
+ 478,
+ true},
{{
0x94, 0x2A, 0x69, 0x16, 0xA6, 0xE4, 0xAE, 0x52, 0x77, 0x11, 0xC5,
0x45, 0x02, 0x47, 0xA2, 0xA7, 0x4F, 0xB8, 0xE1, 0x56, 0xA8, 0x25,
0x4C, 0xA6, 0x6E, 0x73, 0x9A, 0x11, 0x49, 0x3B, 0xB4, 0x45,
},
- 34},
+ 34,
+ false},
{{
0x94, 0xB9, 0x4B, 0xBF, 0x9A, 0x07, 0x26, 0xF1, 0x7B, 0x09, 0x73,
0xAF, 0x6D, 0x41, 0xE9, 0xFB, 0x2E, 0x70, 0x99, 0x65, 0x1B, 0xCB,
0xEF, 0xDD, 0xD9, 0x7B, 0x0A, 0x5F, 0x2A, 0xAB, 0xB0, 0xDD,
},
- 391},
+ 391,
+ true},
{{
0x95, 0x1E, 0xE0, 0x46, 0xFA, 0x83, 0x31, 0x6E, 0x67, 0x86, 0xC0,
0x8C, 0x44, 0xF1, 0x3B, 0x4C, 0xA2, 0xEA, 0xD2, 0xD2, 0x64, 0x4D,
0x63, 0x31, 0x43, 0x91, 0xC0, 0xCC, 0x70, 0x88, 0x7D, 0x0D,
},
- 185},
+ 185,
+ false},
{{
0x95, 0x2C, 0x20, 0x39, 0xC0, 0x24, 0x3E, 0xB5, 0x15, 0xDD, 0x73,
0xD8, 0x3F, 0xC3, 0x64, 0x31, 0x84, 0x87, 0x4F, 0xEB, 0x08, 0x62,
0xA9, 0x83, 0x77, 0x31, 0xED, 0x9B, 0x47, 0x42, 0xE1, 0x7A,
},
- 44},
+ 44,
+ false},
{{
0x95, 0x46, 0xCE, 0x00, 0xE0, 0x3D, 0xD6, 0x1A, 0xCA, 0x58, 0xC5,
0xC8, 0xDB, 0xF3, 0x8A, 0x11, 0x1B, 0xAD, 0x64, 0x06, 0xC9, 0x1D,
0x74, 0x22, 0xE7, 0xF4, 0xC4, 0x0A, 0x0C, 0xB5, 0x8F, 0x18,
},
- 347},
+ 347,
+ true},
{{
0x95, 0x73, 0x54, 0x73, 0xBD, 0x67, 0xA3, 0xB9, 0x5A, 0x8D, 0x5F,
0x90, 0xC5, 0xA2, 0x1A, 0xCE, 0x1E, 0x0D, 0x79, 0x47, 0x32, 0x06,
0x74, 0xD4, 0xAB, 0x84, 0x79, 0x72, 0xB9, 0x15, 0x44, 0xD2,
},
- 259},
+ 259,
+ true},
{{
0x96, 0x47, 0x5B, 0x35, 0xAC, 0xB1, 0xC9, 0x30, 0x3A, 0x90, 0xBD,
0x1D, 0xBF, 0x57, 0x41, 0x8F, 0x78, 0xE2, 0x9A, 0xF1, 0x1C, 0x4D,
0xE8, 0xC8, 0xCB, 0xA2, 0xE5, 0xF9, 0x30, 0x9E, 0x38, 0xD4,
},
- 316},
+ 316,
+ true},
{{
0x96, 0x7B, 0x0C, 0xD9, 0x3F, 0xCE, 0xF7, 0xF2, 0x7C, 0xE2, 0xC2,
0x45, 0x76, 0x7A, 0xE9, 0xB0, 0x5A, 0x77, 0x6B, 0x06, 0x49, 0xF9,
0x96, 0x5B, 0x62, 0x90, 0x96, 0x84, 0x69, 0x68, 0x68, 0x72,
},
- 50},
+ 50,
+ false},
{{
0x96, 0x99, 0x22, 0x5C, 0x5D, 0xE5, 0x2E, 0x56, 0xCD, 0xD3, 0x2D,
0xF2, 0xE9, 0x6D, 0x1C, 0xFE, 0xA5, 0xAA, 0x3C, 0xA0, 0xBB, 0x52,
0xCD, 0x89, 0x33, 0xC2, 0x3B, 0x5C, 0x27, 0x44, 0x38, 0x20,
},
- 139},
+ 139,
+ false},
{{
0x97, 0x2F, 0xBC, 0x6D, 0x55, 0xBF, 0xEF, 0xB1, 0xAB, 0xE3, 0x75,
0x8A, 0xD7, 0xD6, 0x7A, 0x34, 0x9B, 0xBE, 0xF8, 0x0C, 0x06, 0xF1,
0xD8, 0x50, 0x01, 0xDF, 0xB9, 0x10, 0x1B, 0x9A, 0xBC, 0x1B,
},
- 425},
+ 425,
+ true},
{{
0x97, 0x36, 0xAC, 0x3B, 0x25, 0xD1, 0x6C, 0x45, 0xA4, 0x54, 0x18,
0xA9, 0x64, 0x57, 0x81, 0x56, 0x48, 0x0A, 0x8C, 0xC4, 0x34, 0x54,
0x1D, 0xDC, 0x5D, 0xD5, 0x92, 0x33, 0x22, 0x98, 0x68, 0xDE,
},
- 66},
+ 66,
+ false},
{{
0x97, 0x9F, 0x6F, 0x6A, 0x8A, 0x41, 0xC4, 0x21, 0xCC, 0x67, 0x34,
0x73, 0xD5, 0x8A, 0x63, 0x79, 0x81, 0x7B, 0xE7, 0x3D, 0x2E, 0x52,
0x46, 0x98, 0xC8, 0x0F, 0xFB, 0x66, 0xA1, 0x49, 0xD0, 0x89,
},
- 396},
+ 396,
+ true},
{{
0x98, 0x00, 0x8E, 0x2E, 0xDB, 0xB7, 0x2B, 0xAD, 0x42, 0xDA, 0x2F,
0xCB, 0x06, 0xAC, 0x1A, 0xAA, 0x0B, 0x2E, 0x6E, 0x0C, 0x72, 0xE8,
0xCA, 0x20, 0x4F, 0xBA, 0xFD, 0x1B, 0xB4, 0x87, 0x94, 0x41,
},
- 238},
+ 238,
+ true},
{{
0x98, 0x09, 0x22, 0xEE, 0xE0, 0x7F, 0x86, 0xBC, 0x7F, 0x5E, 0x5E,
0x95, 0xD5, 0x7D, 0xB8, 0xBD, 0xAE, 0x68, 0xE1, 0x7A, 0x42, 0x1C,
0x4E, 0x72, 0xA9, 0x6A, 0x70, 0x8A, 0x87, 0x92, 0x01, 0x24,
},
- 149},
+ 149,
+ true},
{{
0x98, 0x47, 0xE5, 0x65, 0x3E, 0x5E, 0x9E, 0x84, 0x75, 0x16, 0xE5,
0xCB, 0x81, 0x86, 0x06, 0xAA, 0x75, 0x44, 0xA1, 0x9B, 0xE6, 0x7F,
0xD7, 0x36, 0x6D, 0x50, 0x69, 0x88, 0xE8, 0xD8, 0x43, 0x47,
},
- 486},
+ 486,
+ true},
{{
0x98, 0xB3, 0xF1, 0x0A, 0x02, 0x50, 0x41, 0x91, 0x0F, 0x19, 0x7C,
0xF1, 0x7C, 0xA0, 0xFC, 0xDF, 0xED, 0x75, 0xFB, 0x2C, 0x8C, 0x14,
0xA8, 0x43, 0xE0, 0x4D, 0x56, 0x56, 0xC9, 0xEB, 0xAC, 0x1A,
},
- 235},
+ 235,
+ true},
{{
0x98, 0xCA, 0x29, 0xF3, 0x13, 0x38, 0x67, 0x21, 0xAF, 0xBF, 0x5D,
0x14, 0xF1, 0xAB, 0xCA, 0xA1, 0xDC, 0x63, 0xCC, 0x8D, 0x1F, 0xD7,
0xDC, 0x36, 0x1F, 0x6B, 0x01, 0x36, 0x89, 0x38, 0xF2, 0x4B,
},
- 223},
+ 223,
+ true},
{{
0x99, 0x1B, 0x5E, 0xD1, 0xB2, 0xFD, 0x36, 0x4B, 0x9F, 0x63, 0x4B,
0x62, 0x4B, 0x30, 0x52, 0x03, 0xF2, 0x99, 0x08, 0xBE, 0x31, 0x8E,
0xF6, 0x39, 0x92, 0x22, 0xD8, 0xA3, 0xEF, 0x79, 0x90, 0xE5,
},
- 299},
+ 299,
+ true},
{{
0x99, 0x33, 0x3C, 0x3A, 0x66, 0x5C, 0xF0, 0xEF, 0xBB, 0x74, 0x88,
0xB3, 0x80, 0x7B, 0x8B, 0x65, 0xF8, 0x7B, 0x5B, 0x29, 0xD6, 0x88,
0x0F, 0x02, 0x8E, 0xDC, 0x28, 0x44, 0x2E, 0xEA, 0xE6, 0x69,
},
- 434},
+ 434,
+ true},
{{
0x99, 0x62, 0xAB, 0x16, 0x99, 0xB0, 0xEB, 0x7C, 0x7E, 0x8A, 0x57,
0x8B, 0xC7, 0x98, 0x93, 0x04, 0x20, 0x31, 0xC1, 0x15, 0x8C, 0x63,
0x36, 0x13, 0x19, 0x9A, 0x90, 0xB9, 0x65, 0x2A, 0x2A, 0x75,
},
- 462},
+ 462,
+ true},
{{
0x9A, 0xDB, 0x99, 0xC9, 0x3A, 0xB2, 0x56, 0xEC, 0xCA, 0x2B, 0x53,
0x50, 0xC7, 0x50, 0x48, 0xA8, 0x58, 0x4C, 0x12, 0xDF, 0xC2, 0x48,
0xE3, 0xF6, 0x0E, 0xA9, 0x35, 0x4C, 0x34, 0xEB, 0xFC, 0xCE,
},
- 65},
+ 65,
+ true},
{{
0x9B, 0x21, 0x9D, 0x0F, 0xBF, 0xF3, 0x6A, 0x5F, 0xB3, 0x20, 0x90,
0x57, 0x19, 0x06, 0xBC, 0xEE, 0xA6, 0x86, 0x17, 0xC8, 0x33, 0xA3,
0xF6, 0x1B, 0x81, 0xE9, 0x62, 0xA8, 0xE6, 0x4D, 0xB8, 0xAF,
},
- 217},
+ 217,
+ true},
{{
0x9C, 0x6F, 0x6A, 0x12, 0x3C, 0xBA, 0xA4, 0xEE, 0x34, 0xDB, 0xEC,
0xEE, 0xE2, 0x4C, 0x97, 0xD7, 0x38, 0x87, 0x8C, 0xB4, 0x23, 0xF3,
0xC2, 0x27, 0x39, 0x03, 0x42, 0x4F, 0x5D, 0x1F, 0x6D, 0xD5,
},
- 135},
+ 135,
+ true},
{{
0x9D, 0x98, 0xA1, 0xFB, 0x60, 0x53, 0x8C, 0x4C, 0xC4, 0x85, 0x7F,
0xF1, 0xA8, 0xC8, 0x03, 0x4F, 0xAF, 0x6F, 0xC5, 0x92, 0x09, 0x3F,
0x61, 0x99, 0x94, 0xB2, 0xC8, 0x13, 0xD2, 0x50, 0xB8, 0x64,
},
- 333},
+ 333,
+ true},
{{
0x9D, 0xC3, 0x8A, 0x9E, 0xDC, 0xF8, 0x28, 0x42, 0xB6, 0x74, 0xDA,
0x18, 0x6B, 0x6D, 0x62, 0x15, 0xAB, 0x9E, 0x2E, 0xC6, 0xD7, 0x2F,
0x57, 0xB0, 0x8A, 0x89, 0x27, 0x28, 0xC3, 0x14, 0x31, 0xF3,
},
- 342},
+ 342,
+ true},
{{
0x9D, 0xD5, 0x5F, 0xC5, 0x73, 0xF5, 0x46, 0xCB, 0x6A, 0x38, 0x31,
0xD1, 0x11, 0x2D, 0x87, 0x10, 0xA6, 0xF4, 0xF8, 0x2D, 0xC8, 0x7F,
0x5F, 0xAE, 0x9D, 0x3A, 0x1A, 0x02, 0x8D, 0xD3, 0x6E, 0x4B,
},
- 11},
+ 11,
+ true},
{{
0x9E, 0x5A, 0x34, 0xB0, 0x89, 0x29, 0xBC, 0x0A, 0x58, 0x1C, 0x89,
0x36, 0xAA, 0xFD, 0x6A, 0xB7, 0x51, 0x7B, 0xB1, 0x51, 0x88, 0xB4,
0xF6, 0xFC, 0x02, 0xC4, 0x59, 0x06, 0xF7, 0x15, 0x95, 0xB0,
},
- 354},
+ 354,
+ true},
{{
0x9E, 0xA9, 0xFE, 0x27, 0x45, 0x37, 0xF4, 0xF9, 0x35, 0x64, 0x2C,
0xDE, 0x82, 0x4F, 0xD7, 0x7E, 0xB0, 0xE1, 0x25, 0xCF, 0x11, 0x8A,
0xB9, 0xB4, 0xC2, 0x19, 0xF6, 0xCB, 0xF9, 0x59, 0xB1, 0x8D,
},
- 431},
+ 431,
+ true},
{{
0x9E, 0xCC, 0x51, 0x36, 0x8E, 0x86, 0xE3, 0x46, 0x0F, 0x66, 0xC2,
0x95, 0xE4, 0x94, 0x2D, 0xD5, 0x30, 0x80, 0xF2, 0x7B, 0x1E, 0x41,
0x0A, 0xFF, 0x2D, 0x1A, 0xA9, 0xD4, 0xE6, 0xBC, 0x7E, 0x7C,
},
- 144},
+ 144,
+ true},
{{
0x9E, 0xFD, 0x91, 0x1D, 0x6F, 0xF4, 0x6F, 0x18, 0x31, 0x11, 0x1D,
0xF3, 0xC5, 0x4C, 0xD2, 0x61, 0x1C, 0xAE, 0x23, 0x98, 0xFF, 0x73,
0x86, 0xD1, 0xCB, 0x6B, 0x4F, 0x32, 0xE3, 0x33, 0x7E, 0xD6,
},
- 407},
+ 407,
+ true},
{{
0xA1, 0x25, 0x74, 0xF4, 0xEB, 0x73, 0x95, 0xCC, 0x63, 0x0A, 0x15,
0xFE, 0xC8, 0xDB, 0x1C, 0x7C, 0x82, 0x8F, 0x66, 0x69, 0x9D, 0x98,
0x4C, 0x8C, 0x89, 0x7E, 0xCA, 0x44, 0xC8, 0x08, 0xF5, 0x5D,
},
- 310},
+ 310,
+ true},
{{
0xA1, 0xD4, 0x5D, 0x06, 0x29, 0x73, 0x41, 0xB1, 0xF3, 0xA7, 0x35,
0xCF, 0xA3, 0x8F, 0x28, 0x3E, 0x68, 0x79, 0xFE, 0xC0, 0x62, 0x81,
0xA3, 0x61, 0xE5, 0xF4, 0x17, 0xCC, 0x70, 0xD2, 0x9D, 0xC9,
},
- 424},
+ 424,
+ true},
{{
0xA2, 0x5A, 0x72, 0x14, 0xC2, 0xB6, 0xC8, 0x61, 0x42, 0xAD, 0xA3,
0x9D, 0xFF, 0x2D, 0x73, 0xD8, 0x65, 0xAA, 0x57, 0x84, 0x3F, 0xDD,
0x2D, 0xB7, 0x7B, 0x3F, 0xEB, 0xF8, 0x26, 0x83, 0xDE, 0x2D,
},
- 240},
+ 240,
+ true},
{{
0xA2, 0xDC, 0x98, 0xCA, 0x7C, 0xBB, 0xEE, 0x18, 0x22, 0xB2, 0x5B,
0x26, 0x7B, 0xD5, 0xCA, 0x50, 0x2F, 0xA7, 0xB0, 0xCF, 0x4F, 0xFF,
0x07, 0x03, 0xEE, 0x6A, 0x41, 0x67, 0x03, 0xF3, 0xC7, 0xEA,
},
- 334},
+ 334,
+ true},
{{
0xA3, 0x20, 0xF4, 0xD5, 0x34, 0xD7, 0xBE, 0x97, 0xC1, 0xAE, 0x8D,
0xD0, 0x49, 0x97, 0x35, 0xBC, 0x89, 0x5C, 0x32, 0x3A, 0xDD, 0x2D,
0x38, 0x8B, 0xFC, 0xCF, 0x66, 0x2C, 0x23, 0xD7, 0xF9, 0x9A,
},
- 293},
+ 293,
+ false},
{{
0xA3, 0x78, 0x41, 0x9D, 0x1A, 0xE9, 0xEB, 0xD2, 0x7B, 0x22, 0x94,
0x80, 0x44, 0xC6, 0x84, 0xBA, 0x29, 0xBC, 0x08, 0x4B, 0x98, 0xF9,
0x65, 0xBE, 0x73, 0x26, 0x2F, 0x0F, 0x6A, 0xAA, 0x1C, 0x6F,
},
- 307},
+ 307,
+ true},
{{
0xA4, 0x00, 0x3B, 0xD5, 0xBD, 0xD8, 0x94, 0xE0, 0x1A, 0x8E, 0x01,
0xE0, 0x6B, 0x62, 0xC7, 0xAA, 0x82, 0xF0, 0x3D, 0xE5, 0x25, 0x31,
0x33, 0x57, 0x0A, 0xAD, 0x4F, 0xD0, 0xE7, 0xD8, 0x1D, 0x3C,
},
- 106},
+ 106,
+ true},
{{
0xA4, 0xB8, 0x9B, 0xB7, 0x06, 0x56, 0xEA, 0x49, 0x8F, 0x2D, 0x9E,
0x00, 0xA4, 0x97, 0xFD, 0xB9, 0xDC, 0xD2, 0x0B, 0x81, 0xB8, 0x93,
0x8E, 0x95, 0x2B, 0xBA, 0x2D, 0xF9, 0xF6, 0x57, 0x29, 0xC3,
},
- 371},
+ 371,
+ true},
{{
0xA4, 0xCB, 0xF4, 0x85, 0x16, 0xAF, 0x31, 0x60, 0xEB, 0xC6, 0x2A,
0xCA, 0xC6, 0xE7, 0xF2, 0x58, 0x60, 0x9E, 0xD0, 0x89, 0x15, 0x35,
0x01, 0x0C, 0x16, 0x69, 0x24, 0x93, 0xA9, 0xFE, 0x1F, 0xBF,
},
- 449},
+ 449,
+ true},
{{
0xA5, 0x1A, 0x2F, 0x3A, 0x05, 0x0E, 0x83, 0x8A, 0x50, 0x50, 0x69,
0x65, 0x78, 0xDB, 0xBE, 0xDA, 0xAC, 0x1A, 0x10, 0x7E, 0xE2, 0xD9,
0xD4, 0x8F, 0xAE, 0x50, 0x5D, 0x18, 0xD0, 0xDA, 0x5C, 0xF8,
},
- 260},
+ 260,
+ true},
{{
0xA5, 0x20, 0x4D, 0xBB, 0x27, 0x54, 0xB9, 0x7E, 0x3C, 0x8A, 0x10,
0x4E, 0xAC, 0xB3, 0x74, 0xA6, 0x49, 0x8A, 0x43, 0x87, 0x73, 0xC7,
0x50, 0x77, 0xF0, 0x06, 0x3C, 0x2C, 0xEB, 0x25, 0xD2, 0xA2,
},
- 305},
+ 305,
+ true},
{{
0xA5, 0x9D, 0x2F, 0x09, 0xC8, 0xB1, 0x68, 0xCD, 0x9A, 0xFA, 0x3B,
0xC3, 0xEB, 0x4D, 0xB0, 0xD7, 0xA4, 0x35, 0x88, 0xD5, 0x23, 0x28,
0x7F, 0x2B, 0x83, 0xA8, 0x22, 0xEB, 0x33, 0x70, 0x91, 0x70,
},
- 453},
+ 453,
+ true},
{{
0xA6, 0xE1, 0x1F, 0xF1, 0x5E, 0xC3, 0x26, 0xA5, 0xE3, 0xF1, 0x8A,
0xD3, 0x3A, 0x05, 0x66, 0x94, 0xDC, 0x84, 0xC6, 0x99, 0x76, 0x6D,
0x02, 0x8A, 0x5A, 0xD0, 0xEF, 0xE1, 0xA8, 0xE5, 0x3A, 0xC7,
},
- 67},
+ 67,
+ false},
{{
0xA6, 0xF1, 0xF9, 0xBF, 0x8A, 0x0A, 0x9D, 0xDC, 0x08, 0x0F, 0xB4,
0x9B, 0x1E, 0xFC, 0x3D, 0x1A, 0x1C, 0x2C, 0x32, 0xDC, 0x0E, 0x13,
0x6A, 0x5B, 0x00, 0xC9, 0x73, 0x16, 0xF2, 0xA3, 0xDC, 0x11,
},
- 70},
+ 70,
+ true},
{{
0xA7, 0x4B, 0x4B, 0x6A, 0x2E, 0xB5, 0x5B, 0x98, 0x64, 0xC0, 0x4E,
0xCB, 0x16, 0x00, 0x3F, 0xF5, 0xDB, 0x5B, 0x51, 0xE4, 0x2C, 0xF8,
0x59, 0xF9, 0x5E, 0x9D, 0x0A, 0x1D, 0xD4, 0x64, 0x40, 0x96,
},
- 364},
+ 364,
+ true},
{{
0xA7, 0x6E, 0x29, 0x49, 0xCB, 0x87, 0xF6, 0x23, 0x6B, 0x5F, 0x68,
0xC6, 0x90, 0x74, 0x75, 0x87, 0xD6, 0x44, 0x8E, 0xA2, 0x1C, 0xFE,
0xAD, 0x79, 0x50, 0x08, 0x4A, 0xC0, 0x15, 0x19, 0x0B, 0x25,
},
- 455},
+ 455,
+ true},
{{
0xA7, 0x98, 0xD9, 0x2F, 0x76, 0xC9, 0xC6, 0x75, 0x5E, 0x5F, 0x55,
0xF8, 0x6C, 0xD1, 0x4A, 0xED, 0xCC, 0x06, 0x55, 0x37, 0x1E, 0x27,
0xCC, 0xDE, 0x03, 0x77, 0x74, 0x5C, 0xE3, 0xC5, 0x00, 0x13,
},
- 356},
+ 356,
+ true},
{{
0xA7, 0xA8, 0xF0, 0x39, 0x89, 0x4F, 0x5F, 0x67, 0x5E, 0x92, 0xA7,
0x78, 0xE0, 0x08, 0xE4, 0x24, 0xC9, 0x41, 0x7D, 0xBA, 0x06, 0xA1,
0x73, 0x8B, 0x45, 0xB4, 0xE0, 0x8D, 0x36, 0xFC, 0x2D, 0x7C,
},
- 220},
+ 220,
+ true},
{{
0xA7, 0xE3, 0x9B, 0xD7, 0xDF, 0x60, 0x9B, 0xEF, 0x32, 0x62, 0xBF,
0x3D, 0xB4, 0xDC, 0x8F, 0x38, 0x14, 0xE0, 0xDB, 0x5A, 0x7A, 0x52,
0x15, 0x6A, 0x6D, 0x0C, 0x35, 0xB4, 0xDA, 0xE8, 0xA6, 0xAD,
},
- 301},
+ 301,
+ true},
{{
0xA8, 0x12, 0x93, 0x44, 0x5D, 0xB1, 0x96, 0xA2, 0x03, 0x0F, 0x9E,
0x45, 0x5F, 0xE3, 0xC7, 0x4A, 0x9A, 0x4F, 0x83, 0x17, 0xB0, 0x2B,
0x01, 0x40, 0x60, 0x27, 0xA8, 0x70, 0x81, 0x74, 0x43, 0x4C,
},
- 15},
+ 15,
+ false},
{{
0xA8, 0x6B, 0xDA, 0xB8, 0xF4, 0x80, 0xB6, 0xEB, 0x89, 0x42, 0xAB,
0x91, 0x70, 0xBD, 0xD0, 0x99, 0x19, 0x71, 0xA7, 0xAD, 0x13, 0x5D,
0xFB, 0xBC, 0xB7, 0x28, 0x5F, 0x07, 0xA7, 0xD1, 0xE3, 0x8A,
},
- 268},
+ 268,
+ true},
{{
0xA8, 0x74, 0x43, 0xB3, 0xD8, 0x96, 0xEB, 0x25, 0x7C, 0xCC, 0xE9,
0x9B, 0x95, 0xAD, 0xA9, 0xBC, 0x81, 0xB9, 0xDB, 0x4E, 0x31, 0x42,
0xAA, 0x9A, 0x99, 0xAF, 0x09, 0x42, 0xCB, 0x0A, 0x4A, 0x3A,
},
- 120},
+ 120,
+ false},
{{
0xA9, 0x99, 0x72, 0xCE, 0x1F, 0x6C, 0x58, 0x1D, 0x00, 0x97, 0xF6,
0x26, 0x18, 0x06, 0x2E, 0x53, 0x15, 0x7B, 0x52, 0x76, 0xE1, 0xEC,
0x66, 0x51, 0xA3, 0x15, 0x70, 0x57, 0xF0, 0x57, 0xB3, 0x39,
},
- 4},
+ 4,
+ true},
{{
0xAA, 0x1C, 0x2B, 0xED, 0xB1, 0xA5, 0x08, 0xBA, 0xAD, 0x7F, 0xB3,
0xF5, 0xE0, 0x28, 0x97, 0xB9, 0x07, 0xC7, 0x48, 0xDE, 0xA9, 0xB7,
0x90, 0x89, 0x04, 0xAA, 0xDB, 0xD0, 0x49, 0x7A, 0xAB, 0x6A,
},
- 252},
+ 252,
+ true},
{{
0xAA, 0x26, 0x30, 0xA7, 0xB6, 0x17, 0xB0, 0x4D, 0x0A, 0x29, 0x4B,
0xAB, 0x7A, 0x8C, 0xAA, 0xA5, 0x01, 0x6E, 0x6D, 0xBE, 0x60, 0x48,
0x37, 0xA8, 0x3A, 0x85, 0x71, 0x9F, 0xAB, 0x66, 0x7E, 0xB5,
},
- 93},
+ 93,
+ false},
{{
0xAB, 0x38, 0x76, 0xC3, 0xDA, 0x5D, 0xE0, 0xC9, 0xCF, 0x67, 0x36,
0x86, 0x8E, 0xE5, 0xB8, 0x8B, 0xF9, 0xBA, 0x1D, 0xFF, 0x9C, 0x9D,
0x72, 0xD2, 0xFE, 0x5A, 0x8D, 0x2F, 0x78, 0x30, 0x21, 0x66,
},
- 265},
+ 265,
+ true},
{{
0xAB, 0x39, 0xA4, 0xB0, 0x25, 0x95, 0x56, 0x91, 0xA4, 0x02, 0x69,
0xF3, 0x53, 0xFA, 0x1D, 0x5C, 0xB9, 0x4E, 0xAF, 0x6C, 0x7E, 0xA9,
0x80, 0x84, 0x84, 0xBB, 0xBB, 0x62, 0xFD, 0x9F, 0x68, 0xF3,
},
- 262},
+ 262,
+ true},
{{
0xAB, 0x5C, 0xDB, 0x33, 0x56, 0x39, 0x73, 0x56, 0xD6, 0xE6, 0x91,
0x97, 0x3C, 0x25, 0xB8, 0x61, 0x8B, 0x65, 0xD7, 0x6A, 0x90, 0x48,
0x6E, 0xA7, 0xA8, 0xA5, 0xC1, 0x77, 0x67, 0xF4, 0x67, 0x3A,
},
- 160},
+ 160,
+ true},
{{
0xAB, 0x98, 0x49, 0x52, 0x76, 0xAD, 0xF1, 0xEC, 0xAF, 0xF2, 0x8F,
0x35, 0xC5, 0x30, 0x48, 0x78, 0x1E, 0x5C, 0x17, 0x18, 0xDA, 0xB9,
0xC8, 0xE6, 0x7A, 0x50, 0x4F, 0x4F, 0x6A, 0x51, 0x32, 0x8F,
},
- 122},
+ 122,
+ false},
{{
0xAB, 0xCA, 0xDF, 0xA3, 0x5F, 0xF8, 0x35, 0xCB, 0x3A, 0x0A, 0x0B,
0x86, 0x40, 0x06, 0x22, 0xB8, 0x0D, 0x5E, 0x80, 0xC7, 0x65, 0xBC,
0x02, 0x7F, 0x1B, 0x1C, 0x4E, 0x0A, 0x62, 0x0F, 0x5E, 0x1C,
},
- 451},
+ 451,
+ true},
{{
0xAC, 0x44, 0x7D, 0xED, 0xD0, 0x43, 0x2A, 0xAB, 0x9C, 0x07, 0x0F,
0x2C, 0xCA, 0x01, 0xB6, 0xDA, 0xB0, 0x9B, 0xEF, 0x07, 0xCF, 0x4C,
0xA6, 0xAA, 0xA7, 0x55, 0x63, 0x4F, 0x85, 0x7B, 0x31, 0x5A,
},
- 479},
+ 479,
+ true},
{{
0xAC, 0xF6, 0x5E, 0x1D, 0x62, 0xCB, 0x58, 0xA2, 0xBA, 0xFD, 0x6F,
0xFA, 0xB4, 0x0F, 0xB8, 0x86, 0x99, 0xC4, 0x73, 0x97, 0xCF, 0x5C,
0xB4, 0x83, 0xD4, 0x2D, 0x69, 0xCA, 0xD3, 0x4C, 0xD4, 0x8B,
},
- 24},
+ 24,
+ true},
{{
0xAC, 0xF7, 0xAD, 0x98, 0xE6, 0xF0, 0x65, 0x86, 0x6E, 0x6F, 0x8C,
0xDF, 0x0C, 0xEB, 0x6F, 0x74, 0x81, 0xF6, 0x95, 0x7B, 0x6D, 0xFF,
0x82, 0x3F, 0x6B, 0x94, 0xD7, 0x9F, 0x01, 0xA6, 0x1C, 0x39,
},
- 382},
+ 382,
+ true},
{{
0xAD, 0x30, 0x4C, 0x88, 0x4A, 0x5D, 0x37, 0x6B, 0xD1, 0x95, 0x20,
0x9A, 0x14, 0xC3, 0x9E, 0x07, 0xF0, 0xD3, 0xF5, 0xCF, 0x89, 0x3D,
0x80, 0x2B, 0x05, 0x3E, 0x1B, 0x92, 0x6E, 0x55, 0xD7, 0x74,
},
- 390},
+ 390,
+ true},
{{
0xAE, 0x20, 0x33, 0xB3, 0x08, 0x28, 0x25, 0xA7, 0x03, 0xE5, 0xA6,
0xAD, 0xC3, 0x22, 0x1A, 0x86, 0x85, 0x4A, 0xA4, 0x11, 0xDB, 0x04,
0x7D, 0xD5, 0xF5, 0x3E, 0xB8, 0x4A, 0xA1, 0x4B, 0xDC, 0x01,
},
- 383},
+ 383,
+ true},
{{
0xAE, 0x56, 0xD8, 0x47, 0x97, 0x3D, 0x19, 0x93, 0x90, 0xE6, 0x6E,
0x40, 0x24, 0xC9, 0xF8, 0x7D, 0x87, 0x37, 0x1E, 0x8B, 0xA8, 0x87,
0x6A, 0xF8, 0x3D, 0x1E, 0x64, 0x4F, 0x54, 0x66, 0x47, 0x38,
},
- 281},
+ 281,
+ true},
{{
0xAF, 0x11, 0x0F, 0x6B, 0x5A, 0xE8, 0xB7, 0x67, 0xEA, 0xC6, 0xE0,
0xAA, 0x27, 0x3F, 0x38, 0x16, 0xE7, 0xA4, 0x0A, 0x64, 0x4E, 0xDA,
0xCB, 0x43, 0x98, 0x14, 0x63, 0x56, 0xE7, 0x75, 0x09, 0xD6,
},
- 386},
+ 386,
+ true},
{{
0xAF, 0x20, 0x7C, 0x61, 0xFD, 0x9C, 0x7C, 0xF9, 0x2C, 0x2A, 0xFE,
0x81, 0x54, 0x28, 0x2D, 0xC3, 0xF2, 0xCB, 0xF3, 0x2F, 0x75, 0xCD,
0x17, 0x28, 0x14, 0xC5, 0x2B, 0x03, 0xB7, 0xEB, 0xC2, 0x58,
},
- 257},
+ 257,
+ true},
{{
0xAF, 0x6A, 0xB5, 0x1B, 0x7B, 0xAD, 0x1D, 0xED, 0xD5, 0x33, 0xEB,
0x59, 0x33, 0x2B, 0x62, 0x27, 0xD6, 0x55, 0x7F, 0x20, 0xB4, 0x44,
0x32, 0x16, 0xDB, 0x73, 0x5B, 0x92, 0x28, 0x0C, 0x7A, 0x44,
},
- 337},
+ 337,
+ true},
{{
0xAF, 0xF9, 0x88, 0x90, 0x6D, 0xDE, 0x12, 0x95, 0x5D, 0x9B, 0xEB,
0xBF, 0x92, 0x8F, 0xDC, 0xC3, 0x1C, 0xCE, 0x32, 0x8D, 0x5B, 0x93,
0x84, 0xF2, 0x1C, 0x89, 0x41, 0xCA, 0x26, 0xE2, 0x03, 0x91,
},
- 31},
+ 31,
+ false},
{{
0xB0, 0x3D, 0x87, 0xB0, 0x56, 0xD0, 0x8C, 0xC9, 0xD4, 0xE6, 0x75,
0xEF, 0x19, 0xCA, 0x83, 0xAB, 0x53, 0x53, 0x21, 0x68, 0xA8, 0x25,
0x85, 0x98, 0xBE, 0x72, 0xE6, 0xD8, 0x5C, 0x7D, 0xD7, 0xC1,
},
- 25},
+ 25,
+ false},
{{
0xB0, 0x83, 0xFF, 0x53, 0x6F, 0x7F, 0x48, 0xA9, 0x08, 0x1E, 0x29,
0x4A, 0x01, 0x87, 0xB5, 0x3E, 0x81, 0x97, 0x71, 0x40, 0x2D, 0x9D,
0x48, 0x10, 0x30, 0x6D, 0xE0, 0x31, 0x02, 0x4E, 0x5F, 0x46,
},
- 412},
+ 412,
+ true},
{{
0xB0, 0xF6, 0xF1, 0x5B, 0x48, 0x17, 0xEB, 0xE6, 0xFE, 0x0B, 0x4B,
0xFC, 0xD7, 0xD3, 0xAC, 0xE4, 0xC7, 0x58, 0xB0, 0xAB, 0x6F, 0x8A,
0x9D, 0xA2, 0xED, 0x92, 0xE6, 0x18, 0x23, 0x9D, 0x9C, 0x98,
},
- 142},
+ 142,
+ false},
{{
0xB1, 0x12, 0x41, 0x42, 0xA5, 0xA1, 0xA5, 0xA2, 0x88, 0x19, 0xC7,
0x35, 0x34, 0x0E, 0xFF, 0x8C, 0x9E, 0x2F, 0x81, 0x68, 0xFE, 0xE3,
0xBA, 0x18, 0x7F, 0x25, 0x3B, 0xC1, 0xA3, 0x92, 0xD7, 0xE2,
},
- 72},
+ 72,
+ true},
{{
0xB1, 0x6C, 0xB1, 0xBA, 0x52, 0x9A, 0x39, 0xE2, 0xDF, 0xD5, 0x3B,
0x3F, 0xF5, 0xA7, 0x9F, 0x19, 0x04, 0x61, 0x4D, 0x83, 0xE3, 0x13,
0x04, 0xF0, 0x27, 0x8B, 0xB4, 0x0B, 0x38, 0xCF, 0x78, 0x24,
},
- 432},
+ 432,
+ true},
{{
0xB1, 0xBE, 0x0F, 0x7A, 0x5E, 0x63, 0x8B, 0x55, 0x9D, 0x8B, 0x52,
0x1F, 0xEF, 0x60, 0x17, 0xAD, 0x8F, 0xA1, 0x6E, 0xB0, 0x54, 0x8E,
0x84, 0x6B, 0x2A, 0xC4, 0xB4, 0x1D, 0x89, 0xB4, 0x1F, 0x14,
},
- 211},
+ 211,
+ true},
{{
0xB2, 0x13, 0xA9, 0xCB, 0xAA, 0x9A, 0x88, 0x31, 0xAC, 0x0B, 0x3A,
0xA8, 0x0E, 0x9D, 0x15, 0x85, 0x6C, 0xD4, 0x3A, 0x7C, 0xC2, 0xE0,
0xBA, 0xC5, 0xFC, 0xB8, 0x4A, 0x24, 0x75, 0x1A, 0x8A, 0x78,
},
- 450},
+ 450,
+ true},
{{
0xB2, 0x1D, 0x2A, 0x74, 0x33, 0x18, 0x71, 0x2B, 0xA1, 0x6F, 0x39,
0x91, 0x9D, 0x96, 0x1A, 0x4B, 0xAF, 0xBA, 0x3B, 0xCA, 0x9A, 0x43,
0xA7, 0x5B, 0x1F, 0xCF, 0xE2, 0x2C, 0x5D, 0x70, 0xCA, 0xBA,
},
- 107},
+ 107,
+ false},
{{
0xB2, 0xDE, 0xF5, 0x36, 0x2A, 0xD3, 0xFA, 0xCD, 0x04, 0xBD, 0x29,
0x04, 0x7A, 0x43, 0x84, 0x4F, 0x76, 0x70, 0x34, 0xEA, 0x48, 0x92,
0xF8, 0x0E, 0x56, 0xBE, 0xE6, 0x90, 0x24, 0x3E, 0x25, 0x02,
},
- 48},
+ 48,
+ true},
{{
0xB3, 0x18, 0x2E, 0x28, 0x9A, 0xE3, 0x4D, 0xDF, 0x2B, 0xE6, 0x43,
0xAB, 0x79, 0xC2, 0x44, 0x30, 0x16, 0x05, 0xFA, 0x0F, 0x1E, 0xAA,
0xE6, 0xD1, 0x0F, 0xB9, 0x29, 0x60, 0x0A, 0xF8, 0x4D, 0xF0,
},
- 355},
+ 355,
+ true},
{{
0xB4, 0x29, 0x6D, 0x5F, 0xE6, 0x0E, 0x52, 0xF3, 0xF0, 0xFF, 0x99,
0xDA, 0x75, 0xAF, 0x5E, 0x7E, 0x62, 0x59, 0x9F, 0x99, 0xEB, 0xE0,
0xFA, 0x41, 0x3F, 0x66, 0xE6, 0xB4, 0x25, 0xC3, 0xD0, 0x9F,
},
- 348},
+ 348,
+ true},
{{
0xB4, 0x89, 0xCC, 0xB2, 0x24, 0xB9, 0xA6, 0xB8, 0x1D, 0xD2, 0x74,
0xCE, 0xAF, 0x52, 0x09, 0xC2, 0x52, 0x99, 0x8C, 0x9A, 0x76, 0xAF,
0x48, 0xE4, 0xF4, 0xC5, 0x0A, 0x07, 0x28, 0x46, 0x18, 0x25,
},
- 465},
+ 465,
+ true},
{{
0xB4, 0xA0, 0x39, 0xEA, 0xFC, 0x43, 0x10, 0xBA, 0x9B, 0xDE, 0x09,
0x3E, 0xDB, 0x8F, 0x9D, 0x9D, 0x0B, 0x3D, 0x4C, 0x7C, 0x00, 0x4D,
0x48, 0x28, 0x8C, 0x35, 0xDB, 0xCC, 0x19, 0x46, 0x7D, 0x18,
},
- 82},
+ 82,
+ true},
{{
0xB5, 0xEC, 0x35, 0xBA, 0xAB, 0x53, 0x88, 0x84, 0xCF, 0xA8, 0xDD,
0x97, 0x37, 0x6B, 0x10, 0x2F, 0x03, 0xE5, 0x3B, 0x48, 0x2C, 0x64,
0x10, 0x0C, 0x25, 0x07, 0x22, 0xAE, 0x9B, 0x04, 0x2C, 0xBC,
},
- 430},
+ 430,
+ true},
{{
0xB6, 0x38, 0xCF, 0xF0, 0x5C, 0x8A, 0x83, 0x27, 0x58, 0xED, 0xC3,
0x02, 0x8A, 0xF9, 0xE2, 0xD5, 0x55, 0x14, 0x56, 0x8B, 0xC6, 0xBB,
0x34, 0xAB, 0x36, 0xD1, 0x40, 0xB9, 0x7A, 0xC6, 0xB1, 0x2D,
},
- 68},
+ 68,
+ true},
{{
0xB6, 0x56, 0xA4, 0x34, 0x38, 0x31, 0xA2, 0xAC, 0xF1, 0x1E, 0xEA,
0xBC, 0x3A, 0x44, 0xB9, 0x70, 0x25, 0xFF, 0xFB, 0xA2, 0xB9, 0x10,
0xDA, 0x87, 0x14, 0xCF, 0x82, 0x7D, 0x81, 0xBE, 0x10, 0xC9,
},
- 408},
+ 408,
+ true},
{{
0xB7, 0x38, 0x29, 0x0C, 0xC0, 0x85, 0x47, 0xE7, 0x9A, 0xC6, 0x7F,
0x83, 0x1E, 0xBB, 0x33, 0x54, 0x7C, 0x4E, 0x7D, 0xB4, 0x51, 0x4E,
0x2D, 0x29, 0x88, 0xC2, 0x3C, 0x44, 0x13, 0x40, 0xEB, 0x41,
},
- 207},
+ 207,
+ false},
{{
0xB8, 0x9B, 0xCB, 0xB8, 0xAC, 0xD4, 0x74, 0xC1, 0xBE, 0xA7, 0xDA,
0xD6, 0x50, 0x37, 0xF4, 0x8D, 0xCE, 0xCC, 0x9D, 0xFA, 0xA0, 0x61,
0x2C, 0x3C, 0x24, 0x45, 0x95, 0x64, 0x19, 0xDF, 0x32, 0xFE,
},
- 475},
+ 475,
+ true},
{{
0xB9, 0x18, 0x2F, 0x52, 0xAF, 0x0D, 0xD1, 0x8E, 0x3A, 0x99, 0xEB,
0xBA, 0xE7, 0x88, 0x3D, 0x4E, 0x4C, 0xC7, 0xFE, 0x2F, 0x81, 0xFA,
0xD0, 0xD3, 0x6C, 0xA6, 0x61, 0xEF, 0xC3, 0x2D, 0x0A, 0x92,
},
- 312},
+ 312,
+ true},
{{
0xB9, 0x4C, 0x19, 0x83, 0x00, 0xCE, 0xC5, 0xC0, 0x57, 0xAD, 0x07,
0x27, 0xB7, 0x0B, 0xBE, 0x91, 0x81, 0x69, 0x92, 0x25, 0x64, 0x39,
0xA7, 0xB3, 0x2F, 0x45, 0x98, 0x11, 0x9D, 0xDA, 0x9C, 0x97,
},
- 178},
+ 178,
+ false},
{{
0xBB, 0x41, 0x28, 0xEC, 0x96, 0x20, 0xF2, 0xD2, 0xA4, 0x9C, 0xE8,
0xE2, 0xC4, 0xE2, 0x57, 0xAE, 0xBA, 0xD9, 0x3A, 0x0F, 0x11, 0xC5,
0x6B, 0x5F, 0xA4, 0xB0, 0x0E, 0x23, 0x75, 0x9F, 0xA3, 0x9D,
},
- 105},
+ 105,
+ false},
{{
0xBB, 0x52, 0x08, 0x6D, 0x06, 0x39, 0xE8, 0xDB, 0x33, 0x27, 0x75,
0xAC, 0x8F, 0x4E, 0x84, 0x35, 0xD9, 0x2C, 0xEB, 0x00, 0xF4, 0xE2,
0x4F, 0x28, 0xFC, 0x0E, 0xAB, 0xE2, 0x40, 0x77, 0x2E, 0x80,
},
- 201},
+ 201,
+ false},
{{
0xBC, 0xCE, 0x8E, 0x2B, 0xBA, 0xEE, 0x71, 0xB6, 0x35, 0x8D, 0xDD,
0x64, 0x1C, 0xBB, 0xFC, 0x25, 0xDE, 0x45, 0x40, 0x03, 0x00, 0x62,
0x71, 0xF7, 0x5B, 0x50, 0xB7, 0x26, 0xD6, 0x7C, 0x3B, 0xC9,
},
- 243},
+ 243,
+ true},
{{
0xBC, 0xFB, 0x44, 0xAA, 0xB9, 0xAD, 0x02, 0x10, 0x15, 0x70, 0x6B,
0x41, 0x21, 0xEA, 0x76, 0x1C, 0x81, 0xC9, 0xE8, 0x89, 0x67, 0x59,
0x0F, 0x6F, 0x94, 0xAE, 0x74, 0x4D, 0xC8, 0x8B, 0x78, 0xFB,
},
- 23},
+ 23,
+ false},
{{
0xBD, 0x15, 0x3E, 0xD7, 0xB0, 0x43, 0x4F, 0x68, 0x86, 0xB1, 0x7B,
0xCE, 0x8B, 0xBE, 0x84, 0xED, 0x34, 0x0C, 0x71, 0x32, 0xD7, 0x02,
0xA8, 0xF4, 0xFA, 0x31, 0x8F, 0x75, 0x6E, 0xCB, 0xD6, 0xF3,
},
- 71},
+ 71,
+ false},
{{
0xBE, 0x3D, 0xB7, 0xB7, 0x9B, 0xFE, 0x57, 0x9D, 0xCF, 0x9B, 0x07,
0xCA, 0x4C, 0xAD, 0x75, 0xAF, 0xF1, 0x69, 0x75, 0x56, 0x8E, 0x5B,
0x45, 0xCF, 0xCA, 0xE4, 0xD6, 0x1F, 0xB6, 0x31, 0x75, 0xA8,
},
- 57},
+ 57,
+ false},
{{
0xBE, 0xDD, 0x8B, 0xC9, 0x7E, 0xA8, 0x64, 0x97, 0x19, 0x5A, 0x07,
0x8A, 0x99, 0x9A, 0x23, 0x7A, 0x06, 0x0A, 0xEB, 0xAE, 0x07, 0xBC,
0x0A, 0x0B, 0x9B, 0x77, 0x89, 0x82, 0xBA, 0x5F, 0x62, 0xF4,
},
- 372},
+ 372,
+ true},
{{
0xBF, 0x01, 0xC3, 0x5F, 0x33, 0x71, 0x13, 0xF1, 0x67, 0xB4, 0xA5,
0x01, 0x86, 0x76, 0x5E, 0x7B, 0x1E, 0x38, 0x90, 0xAF, 0x58, 0x63,
0x28, 0xF1, 0x85, 0xCD, 0x0D, 0x6B, 0xAE, 0x81, 0x35, 0x21,
},
- 415},
+ 415,
+ true},
{{
0xBF, 0xE8, 0x29, 0x09, 0x87, 0x2E, 0x44, 0x34, 0xF1, 0x15, 0xC5,
0x1A, 0x56, 0x16, 0x80, 0x19, 0x59, 0x4D, 0x0E, 0x03, 0xDC, 0xA3,
0x63, 0xD9, 0xF3, 0xB4, 0x83, 0x9D, 0x0B, 0xAB, 0xCD, 0xE5,
},
- 404},
+ 404,
+ true},
{{
0xC0, 0x6C, 0x87, 0x2F, 0xC2, 0xD0, 0xAC, 0x08, 0xD7, 0x8D, 0x42,
0x19, 0x81, 0xFB, 0xDA, 0x4E, 0x35, 0x50, 0x0D, 0x09, 0x46, 0xF7,
0x98, 0x94, 0xED, 0xD2, 0x1A, 0xC2, 0x9D, 0xEC, 0x07, 0x19,
},
- 232},
+ 232,
+ true},
{{
0xC0, 0x71, 0x35, 0xF6, 0xB4, 0x52, 0x39, 0x82, 0x64, 0xA4, 0x77,
0x6D, 0xBD, 0x0A, 0x6A, 0x30, 0x7C, 0x60, 0xA3, 0x6F, 0x96, 0x7B,
0xD2, 0x63, 0x21, 0xDC, 0xB8, 0x17, 0xB5, 0xC0, 0xC4, 0x81,
},
- 167},
+ 167,
+ true},
{{
0xC1, 0xAD, 0x1B, 0x18, 0x98, 0xEC, 0x39, 0x50, 0x48, 0xDF, 0x07,
0x0B, 0xFA, 0x21, 0x7E, 0x25, 0xC9, 0x13, 0xBE, 0xD8, 0xCA, 0x6B,
0x73, 0xDE, 0x08, 0x55, 0x28, 0x84, 0x6A, 0x01, 0x03, 0xC1,
},
- 124},
+ 124,
+ false},
{{
0xC3, 0xBC, 0x61, 0x00, 0xF5, 0x7E, 0x32, 0x0D, 0x86, 0x59, 0xF2,
0x25, 0x84, 0x67, 0x7E, 0x56, 0x86, 0x0A, 0xAB, 0x10, 0x14, 0xE0,
0x08, 0x4A, 0x49, 0x6F, 0xFF, 0x8C, 0x88, 0x0B, 0x6B, 0xA3,
},
- 26},
+ 26,
+ true},
{{
0xC4, 0x25, 0x33, 0xD3, 0xAF, 0x49, 0x98, 0xF5, 0xAD, 0x9F, 0x07,
0x25, 0x21, 0xD8, 0x5D, 0x47, 0x2F, 0xA7, 0xFF, 0xDC, 0xFC, 0x58,
0x8C, 0x82, 0x47, 0xB3, 0x37, 0xDC, 0x77, 0x10, 0x93, 0x89,
},
- 373},
+ 373,
+ true},
{{
0xC4, 0x44, 0xB5, 0xB6, 0x6C, 0xE5, 0xD7, 0x1E, 0x1B, 0x5E, 0x40,
0xF2, 0x73, 0x85, 0xC9, 0x5C, 0xBF, 0xD2, 0x4A, 0x05, 0xB5, 0x6F,
0x70, 0xCA, 0xC0, 0x99, 0x2F, 0x0F, 0x50, 0xC3, 0x37, 0x9C,
},
- 108},
+ 108,
+ false},
{{
0xC5, 0x3D, 0xAD, 0x9E, 0x53, 0xAE, 0x27, 0xED, 0x95, 0xF0, 0xEA,
0x7A, 0x92, 0x03, 0xF7, 0xBF, 0x56, 0xEF, 0xF0, 0xF8, 0xE1, 0xCE,
0x96, 0x0C, 0xB4, 0x76, 0x1B, 0x96, 0x83, 0x42, 0xE3, 0x4E,
},
- 443},
+ 443,
+ true},
{{
0xC5, 0x69, 0x7B, 0xE9, 0x1C, 0xD6, 0x55, 0x53, 0x9B, 0x56, 0x07,
0x58, 0xE9, 0x1B, 0x6E, 0x08, 0x54, 0x61, 0x62, 0x37, 0x41, 0x03,
0x4C, 0x48, 0x5E, 0x47, 0xD7, 0xE9, 0xD2, 0x5A, 0x03, 0xC0,
},
- 213},
+ 213,
+ true},
{{
0xC5, 0xEA, 0x25, 0x9C, 0x62, 0x98, 0x03, 0x50, 0x86, 0x49, 0xF0,
0x21, 0x77, 0xF6, 0x3C, 0x32, 0xFA, 0x85, 0xCC, 0x4A, 0xD5, 0xC3,
0x5F, 0x0D, 0x54, 0x1C, 0x45, 0xDF, 0x10, 0xA4, 0x9F, 0xD7,
},
- 286},
+ 286,
+ true},
{{
0xC6, 0x3D, 0x68, 0xC6, 0x48, 0xA1, 0x8B, 0x77, 0x64, 0x1C, 0x42,
0x7A, 0x66, 0x9D, 0x61, 0xC9, 0x76, 0x8A, 0x55, 0xF4, 0xFC, 0xD0,
0x32, 0x2E, 0xAC, 0x96, 0xC5, 0x77, 0x00, 0x29, 0x9C, 0xF1,
},
- 290},
+ 290,
+ false},
{{
0xC7, 0x3A, 0xFC, 0x2E, 0xBA, 0x77, 0x0D, 0x0C, 0xBC, 0x1E, 0xE4,
0x1F, 0x25, 0x2B, 0x52, 0xE8, 0xA9, 0x3D, 0x12, 0xB7, 0x2D, 0xCC,
0xEC, 0x03, 0x1D, 0x8D, 0x83, 0x9C, 0xBF, 0x81, 0x8A, 0x79,
},
- 3},
+ 3,
+ true},
{{
0xC7, 0x46, 0x12, 0x7C, 0x5F, 0x6B, 0x52, 0x9C, 0xE9, 0xE2, 0x94,
0x8E, 0xFD, 0x94, 0x65, 0x44, 0x40, 0x89, 0x31, 0x9A, 0xCF, 0x03,
0xF3, 0x4D, 0x0B, 0xF3, 0x7E, 0xAD, 0xC7, 0x7D, 0xB2, 0x2F,
},
- 43},
+ 43,
+ true},
{{
0xC7, 0x84, 0x33, 0x3D, 0x20, 0xBC, 0xD7, 0x42, 0xB9, 0xFD, 0xC3,
0x23, 0x6F, 0x4E, 0x50, 0x9B, 0x89, 0x37, 0x07, 0x0E, 0x73, 0x06,
0x7E, 0x25, 0x4D, 0xD3, 0xBF, 0x9C, 0x45, 0xBF, 0x4D, 0xDE,
},
- 182},
+ 182,
+ false},
{{
0xC7, 0xF4, 0x3B, 0x4C, 0xF5, 0xB7, 0x15, 0x68, 0x29, 0x4F, 0x82,
0x2B, 0x53, 0x76, 0x26, 0x05, 0xF6, 0xDD, 0xD1, 0x5C, 0xAD, 0xEC,
0xE7, 0x39, 0xE9, 0xE2, 0xC3, 0xCB, 0xA6, 0x1E, 0x9D, 0x67,
},
- 134},
+ 134,
+ false},
{{
0xC7, 0xF5, 0x84, 0x23, 0x6D, 0x86, 0x39, 0x5E, 0x8F, 0x6F, 0x82,
0xC0, 0x10, 0x88, 0x6A, 0x2C, 0x56, 0xE0, 0x71, 0xA6, 0xA1, 0xC3,
0xED, 0x28, 0x76, 0xB8, 0xA3, 0xA7, 0x2C, 0x5E, 0xFB, 0xB5,
},
- 397},
+ 397,
+ true},
{{
0xC9, 0x0D, 0x00, 0x9C, 0x47, 0xEE, 0xB9, 0xF2, 0xA2, 0x9A, 0xE8,
0x48, 0xF5, 0xD9, 0x30, 0xF2, 0xB4, 0x1E, 0xF5, 0xED, 0xBC, 0x5C,
0x56, 0x95, 0xC1, 0x41, 0x43, 0x45, 0xC1, 0xDD, 0x67, 0xB4,
},
- 358},
+ 358,
+ true},
{{
0xC9, 0x54, 0xC2, 0xC0, 0xB1, 0x89, 0x82, 0x5B, 0xB6, 0x5D, 0xDB,
0x3D, 0xDC, 0xA0, 0x80, 0xB7, 0xDB, 0xCF, 0xE6, 0xB1, 0x7C, 0xAD,
0xE1, 0x02, 0x2B, 0xAD, 0xA8, 0x18, 0x33, 0x66, 0x77, 0xD0,
},
- 308},
+ 308,
+ true},
{{
0xC9, 0x90, 0x5B, 0x0E, 0xE0, 0x12, 0x02, 0x29, 0x3C, 0xA0, 0x26,
0xE6, 0x4F, 0x08, 0x41, 0x24, 0x42, 0xC5, 0x50, 0x4C, 0x06, 0xE4,
0x4C, 0xA7, 0xE9, 0x72, 0x6D, 0x61, 0xF2, 0x0E, 0x40, 0x89,
},
- 402},
+ 402,
+ true},
{{
0xCB, 0x6E, 0x91, 0x71, 0x1A, 0xD6, 0xD5, 0x5C, 0x89, 0x06, 0xF3,
0x79, 0xCB, 0x07, 0x1F, 0xB5, 0xC4, 0x79, 0x33, 0x65, 0x4A, 0x74,
0x15, 0x61, 0x2E, 0xEE, 0x66, 0x29, 0xF2, 0x6F, 0xBC, 0xD7,
},
- 41},
+ 41,
+ true},
+ {{
+ 0xCB, 0xAD, 0x7B, 0x1D, 0x38, 0x48, 0x49, 0xDF, 0x09, 0x46, 0xB7,
+ 0xEE, 0x8E, 0x7F, 0x5F, 0x7C, 0xE3, 0xAE, 0xD8, 0x76, 0xFD, 0xA7,
+ 0xBC, 0x9D, 0x30, 0xD8, 0xB1, 0x6F, 0x29, 0xFF, 0x2C, 0x53,
+ },
+ 492,
+ true},
{{
0xCB, 0xE5, 0xAC, 0x15, 0xD8, 0x8B, 0x5C, 0xAC, 0x3F, 0x81, 0xE6,
0xDF, 0x3B, 0xFB, 0x57, 0xBE, 0xA6, 0x09, 0x58, 0x81, 0x3A, 0x47,
0xB7, 0x7F, 0x3C, 0x5C, 0xB6, 0xB9, 0x81, 0x91, 0xBD, 0xB5,
},
- 8},
+ 8,
+ true},
{{
0xCC, 0x49, 0x97, 0x86, 0x3C, 0x8C, 0x48, 0xA4, 0xCB, 0x5C, 0x3E,
0x65, 0x37, 0xDC, 0x06, 0x02, 0x8D, 0x86, 0x38, 0xBE, 0x49, 0xF5,
0xF8, 0xA2, 0xBA, 0x56, 0xF2, 0xF2, 0xC8, 0xA8, 0xC7, 0x79,
},
- 267},
+ 267,
+ true},
{{
0xCE, 0x24, 0xEB, 0x06, 0x26, 0xDE, 0xFD, 0x81, 0x68, 0xC9, 0x6A,
0x77, 0x01, 0xF0, 0x93, 0x01, 0x60, 0x0F, 0xE5, 0xDD, 0x0D, 0xBC,
0xE5, 0x8E, 0x9C, 0x97, 0xB8, 0x30, 0xAF, 0x02, 0xEF, 0x28,
},
- 32},
+ 32,
+ false},
{{
0xCE, 0xB1, 0x94, 0x11, 0xC6, 0x50, 0x52, 0xC7, 0x57, 0xF9, 0x41,
0xEB, 0x82, 0x6C, 0x96, 0x94, 0x1E, 0x4D, 0x08, 0xD0, 0x96, 0xC7,
0xDB, 0x7E, 0x7E, 0xA3, 0xC4, 0xF8, 0xC1, 0x3F, 0x1A, 0x13,
},
- 288},
+ 288,
+ false},
{{
0xCE, 0xD4, 0x39, 0x02, 0xAB, 0x5F, 0xB5, 0x7B, 0x44, 0x23, 0x22,
0xDC, 0x0E, 0x17, 0x2A, 0x4F, 0xB5, 0x5F, 0x71, 0x78, 0xB8, 0x08,
0xF9, 0x4E, 0x78, 0x0A, 0x6F, 0xD6, 0xCC, 0x6B, 0xD8, 0x18,
},
- 19},
+ 19,
+ false},
{{
0xCF, 0x0B, 0x47, 0x4A, 0xCE, 0x84, 0x69, 0xFA, 0xBA, 0x40, 0x2F,
0x02, 0xEE, 0xBD, 0xF9, 0xE1, 0x70, 0x0D, 0x9C, 0xBE, 0x8B, 0xE4,
0xE4, 0x34, 0x84, 0x07, 0xB6, 0x9D, 0xD3, 0x19, 0x6E, 0x94,
},
- 148},
+ 148,
+ true},
{{
0xD0, 0x77, 0x3A, 0xDB, 0x60, 0x04, 0x3E, 0x95, 0x43, 0x09, 0xD9,
0x71, 0x4F, 0xE0, 0x53, 0xEA, 0xAD, 0x8A, 0xA5, 0xB9, 0x58, 0x6E,
0xDB, 0xA4, 0x68, 0xE2, 0x76, 0xDF, 0x82, 0x06, 0x5A, 0xDF,
},
- 132},
+ 132,
+ false},
{{
0xD1, 0xC4, 0x53, 0x77, 0xEB, 0xDC, 0xD6, 0x18, 0xCD, 0x16, 0x51,
0xDC, 0x2E, 0x02, 0xC2, 0x1D, 0x75, 0x1E, 0x5A, 0xA9, 0xFC, 0xD1,
0xB3, 0x43, 0x1F, 0xF6, 0xEC, 0xF6, 0xA3, 0x13, 0x48, 0xFA,
},
- 292},
+ 292,
+ false},
{{
0xD1, 0xDE, 0x2A, 0xE6, 0x1C, 0x8D, 0xF2, 0xFA, 0x62, 0x39, 0x66,
0x16, 0x3D, 0x4C, 0x73, 0xD4, 0x60, 0xBF, 0xC4, 0x28, 0xE5, 0x75,
0x85, 0xBE, 0x6B, 0xFE, 0xB9, 0xA5, 0x63, 0x23, 0xD1, 0xB6,
},
- 46},
+ 46,
+ false},
{{
0xD1, 0xEC, 0xAC, 0xCA, 0x44, 0x01, 0x2C, 0x3E, 0x1E, 0x6D, 0x1B,
0x39, 0xDD, 0x29, 0x68, 0xFC, 0x7F, 0xD3, 0x12, 0x7A, 0xAA, 0x57,
0xAB, 0x51, 0x82, 0xA3, 0xBE, 0xAB, 0xCC, 0xD7, 0xA3, 0xA9,
},
- 367},
+ 367,
+ true},
{{
0xD2, 0xA5, 0xF3, 0x2F, 0x0E, 0x01, 0xB9, 0x10, 0xEF, 0x4E, 0x3B,
0x46, 0xBF, 0x84, 0xE5, 0xAF, 0x5F, 0xB5, 0x68, 0x9E, 0x7D, 0x15,
0x07, 0xE9, 0x29, 0xE3, 0x68, 0xAC, 0x88, 0xC6, 0xCC, 0x76,
},
- 103},
+ 103,
+ false},
{{
0xD2, 0xF9, 0x1A, 0x04, 0xE3, 0xA6, 0x1D, 0x4E, 0xAD, 0x78, 0x48,
0xC8, 0xD4, 0x3B, 0x5E, 0x11, 0x52, 0xD8, 0x85, 0x72, 0x74, 0x89,
0xBC, 0x65, 0x73, 0x8B, 0x67, 0xC0, 0xA2, 0x27, 0x85, 0xA7,
},
- 255},
+ 255,
+ true},
{{
0xD3, 0x98, 0x0A, 0xAD, 0xD2, 0x16, 0x38, 0xC7, 0x0D, 0x74, 0xA4,
0xBB, 0x1F, 0x8A, 0xB5, 0xE1, 0x17, 0x24, 0xE6, 0x2E, 0xD4, 0x08,
0xF9, 0xFA, 0x8D, 0x3D, 0x4D, 0x91, 0x69, 0x00, 0x28, 0x6B,
},
- 472},
+ 472,
+ true},
+ {{
+ 0xD4, 0x9C, 0x6F, 0x28, 0x9C, 0xD0, 0x56, 0x51, 0x94, 0x92, 0x48,
+ 0x0F, 0x19, 0x2F, 0x00, 0xA6, 0xFC, 0x7C, 0x18, 0x62, 0xDA, 0xB2,
+ 0xE7, 0xB5, 0xD8, 0xE0, 0x5F, 0x66, 0x78, 0xFA, 0xE1, 0x41,
+ },
+ 491,
+ true},
{{
0xD4, 0xAF, 0x6C, 0x0A, 0x48, 0x23, 0x10, 0xBD, 0x7C, 0x54, 0xBB,
0x7A, 0xB1, 0x21, 0x91, 0x6F, 0x86, 0xC0, 0xC0, 0x7C, 0xD5, 0x2F,
0xCA, 0xC3, 0x2D, 0x38, 0x44, 0xC2, 0x60, 0x05, 0x11, 0x5F,
},
- 326},
+ 326,
+ true},
{{
0xD5, 0x59, 0x7E, 0xA3, 0x45, 0x3A, 0x62, 0x61, 0xF5, 0xD4, 0x2E,
0xB9, 0xCA, 0xF5, 0xBD, 0xB4, 0xE3, 0x8A, 0x1E, 0xDE, 0xBD, 0xB5,
0xBE, 0xA6, 0xD7, 0xC0, 0xBC, 0x1A, 0x8A, 0xBE, 0xCA, 0xB2,
},
- 405},
+ 405,
+ true},
{{
0xD6, 0x46, 0xF3, 0xEA, 0x2D, 0x70, 0x03, 0xFC, 0xAA, 0x77, 0xAD,
0x21, 0x91, 0x36, 0xC7, 0x8E, 0x02, 0x4A, 0x6F, 0x2E, 0x23, 0x07,
0xDF, 0xB8, 0xCF, 0xA9, 0x7A, 0x17, 0x13, 0x73, 0xEC, 0xDF,
},
- 374},
+ 374,
+ true},
{{
0xD6, 0xA1, 0x84, 0x43, 0xD3, 0x48, 0xDB, 0x99, 0x4F, 0x93, 0x4C,
0xCD, 0x8E, 0x63, 0x5D, 0x83, 0x3A, 0x27, 0xAC, 0x1E, 0x56, 0xF8,
0xAF, 0xAF, 0x7C, 0x97, 0xCB, 0x4F, 0x43, 0xEA, 0xB6, 0x8B,
},
- 172},
+ 172,
+ true},
{{
0xD8, 0xFB, 0x33, 0xE3, 0x85, 0xC9, 0xC2, 0xDA, 0x72, 0x9A, 0x84,
0x70, 0x6B, 0xA9, 0x27, 0xDC, 0xBB, 0x79, 0x27, 0x3E, 0x12, 0x2F,
0xFD, 0x96, 0x73, 0x36, 0x3B, 0x70, 0xB7, 0xF3, 0x6C, 0xBB,
},
- 153},
+ 153,
+ true},
{{
0xD9, 0x24, 0x05, 0xC4, 0x6D, 0x91, 0x2A, 0x56, 0x3E, 0x43, 0x28,
0x7F, 0x56, 0xCD, 0x41, 0x0A, 0x1C, 0xDF, 0x63, 0x67, 0xC5, 0x7C,
0x9E, 0xA7, 0xC5, 0xCA, 0xE0, 0x39, 0xDC, 0xBC, 0xCE, 0x50,
},
- 365},
+ 365,
+ true},
{{
0xD9, 0xC4, 0x73, 0xCE, 0xE2, 0x5F, 0x94, 0xD1, 0xBC, 0x60, 0x62,
0xBD, 0x62, 0x91, 0x14, 0x77, 0x27, 0x6F, 0x06, 0x4B, 0x82, 0x7A,
0x94, 0x4E, 0x06, 0x4F, 0x85, 0xD0, 0x91, 0x2D, 0x2C, 0x5E,
},
- 253},
+ 253,
+ true},
{{
0xDA, 0x80, 0x0B, 0x80, 0xB2, 0xA8, 0x7D, 0x39, 0x9E, 0x66, 0xFA,
0x19, 0xD7, 0x2F, 0xDF, 0x49, 0x98, 0x3B, 0x47, 0xD8, 0xCF, 0x32,
0x2C, 0x7C, 0x79, 0x50, 0x3A, 0x0C, 0x7E, 0x28, 0xFE, 0xAF,
},
- 230},
+ 230,
+ true},
{{
0xDA, 0x87, 0x96, 0xBE, 0x34, 0xCC, 0x81, 0xAB, 0xEE, 0x73, 0x04,
0xC4, 0xD2, 0xBC, 0xA0, 0xAC, 0x98, 0x4C, 0x5B, 0x24, 0xB6, 0x1B,
0x13, 0xE2, 0x28, 0x5E, 0x1D, 0x27, 0xAD, 0x8C, 0xEB, 0xF0,
},
- 218},
+ 218,
+ true},
{{
0xDB, 0x15, 0xC0, 0x06, 0x2B, 0x52, 0x0F, 0x31, 0x8A, 0x19, 0xDA,
0xCF, 0xEC, 0xD6, 0x4F, 0x9E, 0x7A, 0x3F, 0xBE, 0x60, 0x9F, 0xD5,
0x86, 0x79, 0x6F, 0x20, 0xAE, 0x02, 0x8E, 0x8E, 0x30, 0x58,
},
- 168},
+ 168,
+ true},
{{
0xDB, 0xC1, 0xE3, 0xA1, 0x52, 0x38, 0xA0, 0x48, 0x3B, 0xCD, 0xB8,
0xFD, 0xEC, 0x61, 0x6E, 0x03, 0xE7, 0x05, 0xA4, 0x8E, 0x2A, 0x50,
0x11, 0x57, 0xCA, 0xDF, 0x3B, 0x9C, 0x73, 0x11, 0xC5, 0xE5,
},
- 87},
+ 87,
+ false},
{{
0xDC, 0x05, 0x3D, 0x02, 0x7F, 0xC1, 0x86, 0xE7, 0xC4, 0x1C, 0xD1,
0x93, 0xAF, 0x30, 0xFC, 0x09, 0x79, 0x4E, 0xB9, 0xF3, 0xD9, 0xE6,
0x73, 0x6D, 0xCE, 0x04, 0x14, 0x40, 0xD8, 0x76, 0xA8, 0x01,
},
- 399},
+ 399,
+ true},
{{
0xDD, 0x5E, 0xD1, 0xC0, 0x90, 0xF9, 0xF4, 0x48, 0x06, 0x1B, 0xAA,
0x94, 0xA6, 0xBB, 0x11, 0x01, 0x75, 0x44, 0xE9, 0xEE, 0xFA, 0xA2,
0x0C, 0xC7, 0x14, 0xCE, 0x6C, 0x63, 0x3F, 0x5D, 0xC6, 0x29,
},
- 189},
+ 189,
+ false},
{{
0xDD, 0x9A, 0x6B, 0xFB, 0xF4, 0x4E, 0x17, 0xA2, 0x7F, 0x36, 0x8A,
0xC8, 0xE0, 0x67, 0xB3, 0x07, 0x39, 0x62, 0x69, 0xA7, 0x47, 0xF9,
0x2E, 0x8F, 0x2A, 0xCF, 0x2B, 0x45, 0x1E, 0x3F, 0xFC, 0x72,
},
- 236},
+ 236,
+ true},
{{
0xDF, 0x53, 0x0B, 0xAC, 0x9F, 0xCD, 0x91, 0x4C, 0x25, 0x2C, 0x2F,
0xBD, 0xCE, 0xDD, 0xC6, 0x18, 0x3D, 0x4A, 0xE8, 0xC6, 0x80, 0xAD,
0x65, 0xF0, 0x3E, 0x20, 0x48, 0x61, 0xDD, 0x7B, 0x1C, 0x73,
},
- 313},
+ 313,
+ true},
{{
0xE0, 0xEF, 0x88, 0x2D, 0xA4, 0x8A, 0xB0, 0xB7, 0xEF, 0xB0, 0xD9,
0xBA, 0x15, 0xB2, 0x71, 0x7D, 0xD0, 0x8F, 0x04, 0x3C, 0x25, 0xAC,
0x09, 0xB5, 0x6B, 0x8B, 0x57, 0xFC, 0xEE, 0xB5, 0xA3, 0x5D,
},
- 369},
+ 369,
+ true},
{{
0xE1, 0x56, 0x44, 0x5F, 0xA2, 0x0C, 0x32, 0xAD, 0x00, 0x93, 0x7B,
0x27, 0xD0, 0x96, 0xB8, 0x96, 0x3B, 0xCC, 0x86, 0x39, 0x50, 0x33,
0x3A, 0x87, 0x7E, 0x68, 0xFA, 0x69, 0x70, 0x7A, 0x03, 0xAF,
},
- 445},
+ 445,
+ true},
{{
0xE2, 0x66, 0x13, 0xA5, 0x78, 0xE1, 0x58, 0xC2, 0xA4, 0x4E, 0x4F,
0xEC, 0x41, 0xE6, 0xF3, 0x7A, 0x0A, 0x99, 0x1F, 0xE1, 0xA5, 0xFE,
0x73, 0x6C, 0x30, 0x3F, 0x44, 0x20, 0xA9, 0x0F, 0xB5, 0x0A,
},
- 331},
+ 331,
+ true},
{{
0xE2, 0xD8, 0x91, 0xEF, 0xB7, 0x38, 0x66, 0x91, 0x05, 0xD5, 0x30,
0xDE, 0x5E, 0xD7, 0x2E, 0x2B, 0x2A, 0xC3, 0xF4, 0xA6, 0x70, 0x78,
0xB5, 0x34, 0x9B, 0x3F, 0xDA, 0xCA, 0x49, 0x6F, 0x5E, 0xB8,
},
- 9},
+ 9,
+ true},
{{
0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4,
0xC8, 0x99, 0x6F, 0xB9, 0x24, 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B,
0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55,
},
- 488},
+ 488,
+ true},
{{
0xE4, 0x2F, 0x24, 0xBD, 0x4D, 0x37, 0xF4, 0xAA, 0x2E, 0x56, 0xB9,
0x79, 0xD8, 0x3D, 0x1E, 0x65, 0x21, 0x9F, 0xE0, 0xE9, 0xE3, 0xA3,
0x82, 0xA1, 0xB3, 0xCB, 0x66, 0xC9, 0x39, 0x55, 0xDE, 0x75,
},
- 29},
+ 29,
+ true},
{{
0xE4, 0x3D, 0xEA, 0x89, 0x4F, 0x42, 0xCE, 0xCF, 0x4A, 0x1D, 0xD6,
0x0E, 0xD1, 0xDA, 0xB8, 0x2F, 0x7C, 0x0A, 0x30, 0x8A, 0xE3, 0x2A,
0x3D, 0x49, 0xA7, 0xAA, 0x1A, 0x3E, 0x95, 0x70, 0x15, 0xF7,
},
- 212},
+ 212,
+ true},
{{
0xE5, 0xCA, 0x37, 0xBC, 0x7B, 0x6C, 0x36, 0x19, 0x79, 0xBC, 0x6B,
0x12, 0x3C, 0xA9, 0xA1, 0xDB, 0x01, 0x90, 0x46, 0xD7, 0xFF, 0x5F,
0x57, 0xDF, 0xB8, 0x54, 0xB1, 0x9D, 0x10, 0xB0, 0x68, 0x2F,
},
- 112},
+ 112,
+ false},
{{
0xE7, 0xCA, 0x91, 0xBB, 0xFB, 0xB1, 0x87, 0x88, 0x05, 0x7B, 0x3A,
0x80, 0x70, 0x44, 0x6E, 0xA5, 0x29, 0x11, 0x60, 0x19, 0x41, 0x02,
0xF7, 0xDC, 0xC3, 0xB9, 0x84, 0x8C, 0x63, 0xCB, 0x9C, 0xD5,
},
- 89},
+ 89,
+ false},
{{
0xE8, 0x5F, 0xBF, 0x8B, 0x9A, 0x2E, 0xA4, 0x90, 0x9D, 0xCE, 0x0F,
0xB5, 0xB2, 0xFE, 0x5F, 0x58, 0x77, 0x34, 0x3D, 0x27, 0xD5, 0x8A,
0x41, 0x0A, 0x8B, 0x23, 0x7A, 0xB6, 0x75, 0xA2, 0xDD, 0xAF,
},
- 345},
+ 345,
+ true},
{{
0xEA, 0x2F, 0x9E, 0x08, 0x7E, 0xAE, 0xBB, 0xDF, 0xC0, 0x56, 0x9E,
0xCA, 0x18, 0x36, 0x4E, 0x52, 0x36, 0x25, 0x46, 0x24, 0x85, 0x4F,
0x92, 0xE3, 0x78, 0x71, 0xB5, 0xEE, 0x36, 0x74, 0x48, 0x83,
},
- 297},
+ 297,
+ true},
{{
0xEA, 0x87, 0xF4, 0x62, 0xDE, 0xEF, 0xFF, 0xBD, 0x77, 0x75, 0xAA,
0x2A, 0x4B, 0x7E, 0x0F, 0xCB, 0x91, 0xC2, 0x2E, 0xEE, 0x6D, 0xF6,
0x9E, 0xD9, 0x01, 0x00, 0xCC, 0xC7, 0x3B, 0x31, 0x14, 0x76,
},
- 289},
+ 289,
+ false},
{{
0xEB, 0x49, 0x93, 0xEF, 0xA9, 0xB0, 0x89, 0xE5, 0x93, 0x41, 0x8A,
0xA8, 0x93, 0xF8, 0xE9, 0x3A, 0x73, 0x74, 0xD8, 0x10, 0xE5, 0x2F,
0xCB, 0xE0, 0x1E, 0x7F, 0x1D, 0x7E, 0x92, 0xA6, 0xD0, 0x24,
},
- 215},
+ 215,
+ true},
{{
0xEC, 0x90, 0x56, 0xFE, 0x95, 0x09, 0x41, 0x16, 0x09, 0x76, 0x3A,
0xEE, 0x83, 0x1E, 0xF3, 0x7C, 0x83, 0x2B, 0x75, 0xB3, 0xD7, 0x27,
0x52, 0x8F, 0xC7, 0xC7, 0x52, 0x01, 0xC1, 0xFF, 0x28, 0xE6,
},
- 197},
+ 197,
+ false},
{{
0xEC, 0xA0, 0xF1, 0x81, 0x40, 0x2C, 0xE7, 0xA8, 0x65, 0x2B, 0x31,
0xB4, 0xD0, 0x36, 0xDF, 0x24, 0x7E, 0x3A, 0x30, 0xB7, 0xF4, 0x1A,
0x50, 0xD9, 0x1E, 0xC4, 0xF9, 0x0B, 0x00, 0x6B, 0x43, 0xA1,
},
- 16},
+ 16,
+ false},
{{
0xED, 0x1B, 0x22, 0x9E, 0x0E, 0x08, 0x75, 0x02, 0x1C, 0x1F, 0x17,
0x60, 0xC3, 0x40, 0x7F, 0xB1, 0xD6, 0x60, 0x8E, 0xDA, 0x7A, 0xDD,
0x71, 0xA3, 0xE3, 0x27, 0x5C, 0xED, 0x09, 0x69, 0x0F, 0x7C,
},
- 377},
+ 377,
+ true},
{{
0xED, 0xE4, 0xB1, 0x53, 0x5A, 0x52, 0x9B, 0xF1, 0x60, 0x6B, 0xC6,
0xFF, 0x75, 0x7B, 0x91, 0x47, 0x0A, 0xA3, 0x0A, 0xEA, 0xFF, 0xD2,
0xD6, 0xDF, 0x2E, 0xBA, 0x34, 0x0D, 0xAE, 0x30, 0x2F, 0xCA,
},
- 219},
+ 219,
+ true},
{{
0xEF, 0x4F, 0xA1, 0xC6, 0x30, 0xF0, 0x49, 0x50, 0xE0, 0xE2, 0xD1,
0x0D, 0xC1, 0x9F, 0x14, 0x9D, 0x08, 0xAB, 0x46, 0xDE, 0xC9, 0x5D,
0xA3, 0x13, 0x1C, 0xBA, 0xEA, 0x8A, 0xF8, 0xEA, 0x30, 0x27,
},
- 393},
+ 393,
+ true},
{{
0xEF, 0x53, 0xFF, 0xAF, 0x0C, 0xEB, 0x04, 0x0D, 0x07, 0x7F, 0x5B,
0xD8, 0x0A, 0x9D, 0xEE, 0xF6, 0xD4, 0x50, 0x7F, 0xDB, 0x6F, 0x9B,
0xCF, 0x8C, 0x35, 0x94, 0xBE, 0xCE, 0x7E, 0xBD, 0xB0, 0x25,
},
- 361},
+ 361,
+ true},
{{
0xEF, 0xFE, 0xE1, 0xF1, 0xE5, 0xF3, 0x9F, 0x42, 0xFF, 0x80, 0xD4,
0x71, 0xC9, 0xC5, 0xA7, 0x99, 0xA8, 0xC8, 0x43, 0xF9, 0xB6, 0x76,
0x31, 0x5F, 0x9E, 0xAB, 0x3F, 0x4C, 0x7A, 0x2F, 0x7F, 0xC8,
},
- 129},
+ 129,
+ true},
{{
0xF1, 0xC6, 0xBA, 0x67, 0x0C, 0xFC, 0x88, 0xE4, 0xDF, 0x52, 0x97,
0x3C, 0xAE, 0x42, 0x0F, 0x0A, 0x08, 0x9D, 0xD4, 0x74, 0x14, 0x4F,
0xE5, 0x80, 0x6C, 0x42, 0x00, 0x64, 0xE1, 0x59, 0x12, 0x29,
},
- 171},
+ 171,
+ false},
{{
0xF2, 0xA4, 0xE6, 0xB2, 0x63, 0xD0, 0xA5, 0x52, 0xAD, 0xFF, 0x5D,
0x85, 0xDC, 0x96, 0xB5, 0x82, 0x0F, 0xD6, 0x6A, 0xA0, 0xB1, 0x82,
0x28, 0xF4, 0x8F, 0xDB, 0x08, 0x7C, 0x8D, 0xB3, 0x41, 0x33,
},
- 474},
+ 474,
+ true},
{{
0xF3, 0x43, 0x8E, 0x23, 0xB3, 0xCE, 0x53, 0x25, 0x22, 0xFA, 0xCF,
0x30, 0x79, 0x23, 0xF5, 0x8F, 0xD1, 0x86, 0x08, 0xE9, 0xBA, 0x7A,
0xDD, 0xC3, 0x0E, 0x95, 0x2B, 0x43, 0xC4, 0x96, 0x16, 0xC3,
},
- 177},
+ 177,
+ false},
{{
0xF4, 0x23, 0x52, 0xC3, 0xCC, 0x3D, 0x84, 0xB8, 0x51, 0x89, 0x89,
0xD6, 0x47, 0xC8, 0x8C, 0xA3, 0x01, 0xC8, 0x8F, 0xB9, 0x91, 0x93,
0x8B, 0xBC, 0xEC, 0xC9, 0xEE, 0x60, 0xE5, 0x65, 0xD3, 0x77,
},
- 467},
+ 467,
+ true},
{{
0xF4, 0x63, 0xC5, 0x4D, 0x9F, 0x1A, 0x04, 0x7A, 0xED, 0x52, 0x65,
0x6A, 0xC7, 0x85, 0xE0, 0x7E, 0xBE, 0xC5, 0x28, 0xE0, 0x20, 0x7B,
0xFD, 0x3F, 0x55, 0xD8, 0x93, 0x23, 0x76, 0x68, 0xF6, 0xAE,
},
- 96},
+ 96,
+ true},
{{
0xF4, 0x8B, 0xAD, 0xD7, 0xDF, 0x6A, 0x06, 0x69, 0x0D, 0x0A, 0xE3,
0x13, 0x73, 0xB1, 0x28, 0x55, 0xF8, 0xDE, 0xDB, 0x14, 0x51, 0x7F,
0x36, 0x2A, 0x31, 0x31, 0x01, 0xCC, 0x98, 0xCC, 0x6B, 0x35,
},
- 60},
+ 60,
+ false},
{{
0xF5, 0x3C, 0x22, 0x05, 0x98, 0x17, 0xDD, 0x96, 0xF4, 0x00, 0x65,
0x16, 0x39, 0xD2, 0xF8, 0x57, 0xE2, 0x10, 0x70, 0xA5, 0x9A, 0xBE,
0xD9, 0x07, 0x94, 0x00, 0xD9, 0xF6, 0x95, 0x50, 0x69, 0x00,
},
- 118},
+ 118,
+ true},
{{
0xF5, 0x85, 0x7D, 0x88, 0x62, 0xBC, 0x2B, 0xA3, 0xC9, 0xDD, 0xCA,
0x3F, 0x84, 0x14, 0x6D, 0xC8, 0xD8, 0x1F, 0x4D, 0x57, 0x9D, 0x2B,
0x38, 0x7B, 0xF6, 0x00, 0x65, 0x38, 0x1E, 0xE6, 0x41, 0xDD,
},
- 335},
+ 335,
+ true},
{{
0xF5, 0xE1, 0x9C, 0x8E, 0x14, 0xFE, 0x75, 0x5F, 0x55, 0x1C, 0xEC,
0x2B, 0x71, 0x13, 0xE7, 0xC9, 0x80, 0x23, 0xB1, 0x76, 0xEB, 0xE6,
0xC1, 0xAB, 0xCF, 0x87, 0x2B, 0x2A, 0x7B, 0x93, 0x23, 0x04,
},
- 363},
+ 363,
+ true},
{{
0xF6, 0x14, 0x6B, 0xC2, 0x38, 0xE8, 0xFC, 0xE0, 0xD4, 0x7B, 0x70,
0x74, 0xC9, 0xA2, 0x6B, 0x1A, 0xA0, 0xF8, 0x83, 0x52, 0x85, 0x10,
0xF0, 0x6D, 0x9C, 0xFE, 0xC4, 0x1F, 0xF6, 0xCA, 0x19, 0x68,
},
- 247},
+ 247,
+ true},
{{
0xF6, 0xB5, 0x9C, 0x8E, 0x27, 0x89, 0xA1, 0xFD, 0x5D, 0x5B, 0x25,
0x37, 0x42, 0xFE, 0xAD, 0xC6, 0x92, 0x5C, 0xB9, 0x3E, 0xDC, 0x34,
0x5E, 0x53, 0x16, 0x6E, 0x12, 0xC5, 0x2B, 0xA2, 0xA6, 0x01,
},
- 327},
+ 327,
+ true},
{{
0xF7, 0x3B, 0xE5, 0xEB, 0xA5, 0x36, 0x91, 0x2C, 0x55, 0x7F, 0xB8,
0x55, 0x51, 0x7A, 0xD1, 0xEE, 0x04, 0x87, 0xBD, 0x8F, 0x63, 0x49,
0x8C, 0x39, 0x49, 0x16, 0x41, 0x77, 0xBA, 0x06, 0xC5, 0xDE,
},
- 380},
+ 380,
+ true},
{{
0xF7, 0xAF, 0xF4, 0x1B, 0x27, 0x09, 0xF1, 0x75, 0xF8, 0xAB, 0xA1,
0x7E, 0x56, 0x7B, 0x27, 0x04, 0x6B, 0x2D, 0xD5, 0x4B, 0xF6, 0xE7,
0xE2, 0x63, 0xD3, 0x29, 0x58, 0x73, 0x43, 0x7B, 0x9C, 0xFF,
},
- 387},
+ 387,
+ true},
{{
0xF7, 0xEC, 0xDE, 0xD5, 0xC6, 0x60, 0x47, 0xD2, 0x8E, 0xD6, 0x46,
0x6B, 0x54, 0x3C, 0x40, 0xE0, 0x74, 0x3A, 0xBE, 0x81, 0xD1, 0x09,
0x25, 0x4D, 0xCF, 0x84, 0x5D, 0x4C, 0x2C, 0x78, 0x53, 0xC5,
},
- 208},
+ 208,
+ false},
{{
0xF8, 0xE5, 0xF9, 0x05, 0xBC, 0x93, 0x99, 0x11, 0x26, 0x7B, 0x83,
0xD5, 0x08, 0x14, 0xA9, 0x03, 0x23, 0xB5, 0x1E, 0x18, 0x36, 0x29,
0xDB, 0x52, 0xD4, 0xFC, 0x2D, 0x54, 0x68, 0xA5, 0xA5, 0x78,
},
- 222},
+ 222,
+ true},
{{
0xFA, 0xC9, 0x5D, 0xE3, 0xC2, 0x4A, 0x17, 0x41, 0x94, 0x80, 0x0C,
0xFF, 0xAA, 0x3C, 0xA5, 0x1D, 0x71, 0x16, 0x63, 0x06, 0x64, 0xA9,
0xB6, 0x0C, 0x87, 0x58, 0xB4, 0xEF, 0x0D, 0xC5, 0x8F, 0x88,
},
- 119},
+ 119,
+ true},
{{
0xFA, 0xDD, 0xDE, 0x04, 0xBC, 0xF0, 0x8C, 0xA8, 0xF4, 0xE2, 0x2E,
0xFD, 0x2A, 0xFE, 0xAD, 0xE6, 0xBF, 0x3D, 0x85, 0x0A, 0xE4, 0x7B,
0xE9, 0x6A, 0x82, 0xD5, 0x39, 0x49, 0x4F, 0x12, 0x0C, 0xBD,
},
- 350},
+ 350,
+ true},
{{
0xFB, 0xE3, 0x01, 0x80, 0x31, 0xF9, 0x58, 0x6B, 0xCB, 0xF4, 0x17,
0x27, 0xE4, 0x17, 0xB7, 0xD1, 0xC4, 0x5C, 0x2F, 0x47, 0xF9, 0x3B,
0xE3, 0x72, 0xA1, 0x7B, 0x96, 0xB5, 0x07, 0x57, 0xD5, 0xA2,
},
- 210},
+ 210,
+ false},
{{
0xFC, 0x3B, 0x82, 0x79, 0x6B, 0x57, 0x2C, 0xA9, 0x73, 0x19, 0x93,
0x63, 0x5D, 0xB8, 0xCF, 0x07, 0xC2, 0xBF, 0x01, 0xE1, 0x99, 0xB2,
0xF2, 0x73, 0xA3, 0xF9, 0x53, 0xBD, 0x18, 0x5D, 0xE3, 0xC0,
},
- 158},
+ 158,
+ true},
{{
0xFC, 0xF7, 0xDA, 0x98, 0x36, 0x03, 0xE8, 0x88, 0x62, 0x03, 0x0D,
0x96, 0x13, 0x7D, 0x8E, 0x13, 0x03, 0x1B, 0xAD, 0xFB, 0x4D, 0x56,
0xC1, 0xFD, 0x4C, 0xAC, 0xC3, 0x39, 0xF6, 0xBD, 0xBB, 0x2A,
},
- 28},
+ 28,
+ true},
{{
0xFD, 0x37, 0x1B, 0xEA, 0x97, 0x55, 0xFF, 0x60, 0xC8, 0x82, 0x8C,
0x84, 0x9B, 0x8E, 0x52, 0x15, 0xDE, 0x53, 0x2D, 0x61, 0xB0, 0x09,
0x85, 0x5F, 0xA0, 0xAD, 0x63, 0x0D, 0x90, 0xEE, 0xF8, 0x2E,
},
- 490},
+ 490,
+ true},
{{
0xFD, 0x87, 0x2D, 0x17, 0x66, 0x17, 0xE5, 0x0C, 0x26, 0x61, 0x19,
0xD0, 0xFD, 0xB0, 0x47, 0xB0, 0x73, 0x2D, 0xA2, 0x04, 0x8B, 0x12,
0x1A, 0xF7, 0xB9, 0x86, 0x0C, 0xA3, 0xE2, 0xF2, 0xF2, 0xBE,
},
- 123},
+ 123,
+ true},
{{
0xFE, 0xA2, 0xB7, 0xD6, 0x45, 0xFB, 0xA7, 0x3D, 0x75, 0x3C, 0x1E,
0xC9, 0xA7, 0x87, 0x0C, 0x40, 0xE1, 0xF7, 0xB0, 0xC5, 0x61, 0xE9,
0x27, 0xB9, 0x85, 0xBF, 0x71, 0x18, 0x66, 0xE3, 0x6F, 0x22,
},
- 110},
+ 110,
+ false},
{{
0xFF, 0x34, 0x2F, 0xB6, 0xC4, 0xC8, 0xBD, 0x30, 0xA4, 0x70, 0x6F,
0x73, 0x48, 0x95, 0x39, 0xF1, 0x9E, 0x6E, 0x48, 0xCC, 0x05, 0xF4,
0x62, 0x54, 0x65, 0x4F, 0x66, 0x10, 0xDB, 0xC5, 0x40, 0xE9,
},
- 133},
+ 133,
+ false},
{{
0xFF, 0x56, 0x80, 0xCD, 0x73, 0xA5, 0x70, 0x3D, 0xA0, 0x48, 0x17,
0xA0, 0x75, 0xFD, 0x46, 0x25, 0x06, 0xA7, 0x35, 0x06, 0xC4, 0xB8,
0x1A, 0x15, 0x83, 0xEF, 0x54, 0x94, 0x78, 0xD2, 0x64, 0x76,
},
- 54},
+ 54,
+ true},
};
} // namespace
diff --git a/chromium/net/cert/sth_distributor.cc b/chromium/net/cert/sth_distributor.cc
deleted file mode 100644
index 3de77d903a5..00000000000
--- a/chromium/net/cert/sth_distributor.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/cert/sth_distributor.h"
-
-#include "base/metrics/histogram_macros.h"
-#include "base/time/time.h"
-#include "net/cert/signed_tree_head.h"
-
-namespace {
-const uint8_t kPilotLogID[] = {0xa4, 0xb9, 0x09, 0x90, 0xb4, 0x18, 0x58, 0x14,
- 0x87, 0xbb, 0x13, 0xa2, 0xcc, 0x67, 0x70, 0x0a,
- 0x3c, 0x35, 0x98, 0x04, 0xf9, 0x1b, 0xdf, 0xb8,
- 0xe3, 0x77, 0xcd, 0x0e, 0xc8, 0x0d, 0xdc, 0x10};
-}
-
-namespace net {
-
-namespace ct {
-
-STHDistributor::STHDistributor()
- : observer_list_(base::ObserverListPolicy::EXISTING_ONLY) {}
-
-STHDistributor::~STHDistributor() = default;
-
-void STHDistributor::NewSTHObserved(const SignedTreeHead& sth) {
- auto it = std::find_if(observed_sths_.begin(), observed_sths_.end(),
- [&sth](const SignedTreeHead& other) {
- return sth.log_id == other.log_id;
- });
-
- if (it == observed_sths_.end())
- observed_sths_.push_back(sth);
- else
- *it = sth;
-
- for (auto& observer : observer_list_)
- observer.NewSTHObserved(sth);
-
- if (sth.log_id.compare(0, sth.log_id.size(),
- reinterpret_cast<const char*>(kPilotLogID),
- sizeof(kPilotLogID)) != 0)
- return;
-
- const base::TimeDelta sth_age = base::Time::Now() - sth.timestamp;
- UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertificateTransparency.PilotSTHAge", sth_age,
- base::TimeDelta::FromHours(1),
- base::TimeDelta::FromDays(4), 100);
-}
-
-void STHDistributor::RegisterObserver(STHObserver* observer) {
- observer_list_.AddObserver(observer);
- // Make a local copy, because notifying the |observer| of a
- // new STH may result in this class being notified of a
- // (different) new STH, thus invalidating the iterator.
- std::vector<SignedTreeHead> local_sths(observed_sths_);
-
- for (const auto& sth : local_sths)
- observer->NewSTHObserved(sth);
-}
-
-void STHDistributor::UnregisterObserver(STHObserver* observer) {
- observer_list_.RemoveObserver(observer);
-}
-
-} // namespace ct
-
-} // namespace net
diff --git a/chromium/net/cert/sth_distributor.h b/chromium/net/cert/sth_distributor.h
deleted file mode 100644
index 0462cd29bb3..00000000000
--- a/chromium/net/cert/sth_distributor.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_CERT_STH_DISTRIBUTOR_H_
-#define NET_CERT_STH_DISTRIBUTOR_H_
-
-#include <vector>
-
-#include "base/observer_list.h"
-#include "net/base/net_export.h"
-#include "net/cert/sth_observer.h"
-#include "net/cert/sth_reporter.h"
-
-namespace net {
-
-namespace ct {
-
-struct SignedTreeHead;
-
-// A proxy for delegating new STH notifications to all registered
-// observers.
-// For each |observer| registered with RegisterObserver, the
-// NewSTHObserved method will be called whenever the STHDistributor's
-// NewSTHObserved method is invoked.
-class NET_EXPORT STHDistributor : public STHObserver, public STHReporter {
- public:
- STHDistributor();
- ~STHDistributor() override;
-
- // STHObserver implementation.
- void NewSTHObserved(const SignedTreeHead& sth) override;
-
- // STHReporter implementation
- // Registers |observer| for new STH notifications. On registration,
- // the |observer| will be notified of the latest STH for each log tha the
- // STHDistributor has observed.
- void RegisterObserver(STHObserver* observer) override;
-
- // Unregisters |observer|, which must have been previously
- // registered via RegisterObserver()
- void UnregisterObserver(STHObserver* observer) override;
-
- private:
- // STHs from logs, one for each log.
- std::vector<SignedTreeHead> observed_sths_;
-
- // The observers for new STH notifications.
- base::ObserverList<STHObserver, true> observer_list_;
-};
-
-} // namespace ct
-
-} // namespace net
-
-#endif // NET_CERT_STH_DISTRIBUTOR_H_
diff --git a/chromium/net/cert/sth_distributor_unittest.cc b/chromium/net/cert/sth_distributor_unittest.cc
deleted file mode 100644
index c57b61d7787..00000000000
--- a/chromium/net/cert/sth_distributor_unittest.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/cert/sth_distributor.h"
-
-#include <map>
-#include <string>
-
-#include "base/test/histogram_tester.h"
-#include "crypto/sha2.h"
-#include "net/cert/signed_tree_head.h"
-#include "net/cert/sth_observer.h"
-#include "net/test/ct_test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-
-namespace ct {
-
-namespace {
-
-// An STHObserver implementation that simply stores all
-// observed STHs, keyed by log ID.
-class StoringSTHObserver : public STHObserver {
- public:
- void NewSTHObserved(const SignedTreeHead& sth) override {
- sths[sth.log_id] = sth;
- }
-
- std::map<std::string, SignedTreeHead> sths;
-};
-
-class STHDistributorTest : public ::testing::Test {
- public:
- STHDistributorTest() = default;
-
- void SetUp() override {
- ASSERT_TRUE(GetSampleSignedTreeHead(&sample_sth_));
- sample_sth_.log_id = GetTestPublicKeyId();
- }
-
- protected:
- STHDistributor distributor_;
- SignedTreeHead sample_sth_;
-};
-
-// Test that when a new observer is registered, the STHDistributor notifies it
-// of all the observed STHs it received so far.
-// This test makes sure that all observed STHs are reported to the observer.
-TEST_F(STHDistributorTest, NotifiesOfExistingSTHs) {
- // Create an STH that differs from the |sample_sth_| by belonging to a
- // different log.
- const std::string other_log = "another log";
- SignedTreeHead second_sth(sample_sth_);
- second_sth.log_id = other_log;
-
- // Notify |distributor_| of both STHs.
- distributor_.NewSTHObserved(sample_sth_);
- distributor_.NewSTHObserved(second_sth);
-
- StoringSTHObserver observer;
- distributor_.RegisterObserver(&observer);
-
- // Check that two STHs from different logs received prior to observer
- // registration were reported to the observer once registered.
- EXPECT_EQ(2u, observer.sths.size());
- EXPECT_EQ(1u, observer.sths.count(other_log));
- distributor_.UnregisterObserver(&observer);
-}
-
-// Test that histograms are properly recorded for the STH age when an STH
-// from Google's Pilot log is observed.
-TEST_F(STHDistributorTest, LogsUMAForPilotSTH) {
- const char kPilotSTHAgeHistogram[] =
- "Net.CertificateTransparency.PilotSTHAge";
- base::HistogramTester histograms;
- histograms.ExpectTotalCount(kPilotSTHAgeHistogram, 0);
-
- const uint8_t kPilotLogID[] = {
- 0xa4, 0xb9, 0x09, 0x90, 0xb4, 0x18, 0x58, 0x14, 0x87, 0xbb, 0x13,
- 0xa2, 0xcc, 0x67, 0x70, 0x0a, 0x3c, 0x35, 0x98, 0x04, 0xf9, 0x1b,
- 0xdf, 0xb8, 0xe3, 0x77, 0xcd, 0x0e, 0xc8, 0x0d, 0xdc, 0x10};
- sample_sth_.log_id = std::string(reinterpret_cast<const char*>(kPilotLogID),
- crypto::kSHA256Length);
-
- distributor_.NewSTHObserved(sample_sth_);
- histograms.ExpectTotalCount(kPilotSTHAgeHistogram, 1);
-}
-
-// Test that the STHDistributor updates, rather than accumulates, STHs
-// coming from the same log.
-// This is tested by notifying the STHDistributor of an STH, modifying that
-// STH, notifying the STHDistributor of the modified STH, then registering
-// an observer which should get notified only once, with the modified STH.
-TEST_F(STHDistributorTest, UpdatesObservedSTHData) {
- // Observe an initial STH
- StoringSTHObserver observer;
- distributor_.RegisterObserver(&observer);
-
- distributor_.NewSTHObserved(sample_sth_);
-
- EXPECT_EQ(1u, observer.sths.size());
- EXPECT_EQ(sample_sth_, observer.sths[GetTestPublicKeyId()]);
-
- // Observe a new STH. "new" simply means that it is a more recently observed
- // SignedTreeHead for the given log ID, not necessarily that it's newer
- // chronologically (the timestamp) or the log state (the tree size).
- // To make sure the more recently observed SignedTreeHead is returned, just
- // modify some fields.
- SignedTreeHead new_sth = sample_sth_;
- new_sth.tree_size++;
- new_sth.timestamp -= base::TimeDelta::FromSeconds(3);
-
- distributor_.NewSTHObserved(new_sth);
- // The STH should have been broadcast to existing observers.
- EXPECT_EQ(1u, observer.sths.size());
- EXPECT_NE(sample_sth_, observer.sths[GetTestPublicKeyId()]);
- EXPECT_EQ(new_sth, observer.sths[GetTestPublicKeyId()]);
-
- // Registering a new observer should only receive the most recently observed
- // STH.
- StoringSTHObserver new_observer;
- distributor_.RegisterObserver(&new_observer);
- EXPECT_EQ(1u, new_observer.sths.size());
- EXPECT_NE(sample_sth_, new_observer.sths[GetTestPublicKeyId()]);
- EXPECT_EQ(new_sth, new_observer.sths[GetTestPublicKeyId()]);
-
- distributor_.UnregisterObserver(&new_observer);
- distributor_.UnregisterObserver(&observer);
-}
-
-} // namespace
-
-} // namespace ct
-
-} // namespace net
diff --git a/chromium/net/cert/sth_observer.h b/chromium/net/cert/sth_observer.h
deleted file mode 100644
index ad65a6bd162..00000000000
--- a/chromium/net/cert/sth_observer.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_CERT_STH_OBSERVER_H_
-#define NET_CERT_STH_OBSERVER_H_
-
-#include <set>
-
-#include "net/base/net_export.h"
-
-namespace net {
-
-namespace ct {
-
-struct SignedTreeHead;
-
-// Interface for receiving notifications of new STHs observed.
-class NET_EXPORT STHObserver {
- public:
- virtual ~STHObserver() {}
-
- // Called with a new |sth| when one is observed.
- virtual void NewSTHObserved(const SignedTreeHead& sth) = 0;
-};
-
-} // namespace ct
-
-} // namespace net
-
-#endif // NET_CERT_STH_OBSERVER_H_
diff --git a/chromium/net/cert/sth_reporter.h b/chromium/net/cert/sth_reporter.h
deleted file mode 100644
index a62ad659bf9..00000000000
--- a/chromium/net/cert/sth_reporter.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_CERT_STH_REPORTER_H_
-#define NET_CERT_STH_REPORTER_H_
-
-#include <set>
-
-#include "net/base/net_export.h"
-
-namespace net {
-
-namespace ct {
-
-class STHObserver;
-
-// Interface for registering/unregistering observers.
-class NET_EXPORT STHReporter {
- public:
- virtual ~STHReporter() {}
-
- virtual void RegisterObserver(STHObserver* observer) = 0;
- virtual void UnregisterObserver(STHObserver* observer) = 0;
-};
-
-} // namespace ct
-
-} // namespace net
-
-#endif // NET_CERT_STH_REPORTER_H_
diff --git a/chromium/net/cert/test_root_certs_win.cc b/chromium/net/cert/test_root_certs_win.cc
index 8bf74cdabd8..72240c73013 100644
--- a/chromium/net/cert/test_root_certs_win.cc
+++ b/chromium/net/cert/test_root_certs_win.cc
@@ -65,8 +65,9 @@ struct CryptoAPIInjector {
// sz_CERT_STORE_PROV_SYSTEM_[A/W] and CERT_STORE_PROV_SYSTEM_A, based
// on whether or not any third-party CryptoAPI modules have been
// installed.
- const CRYPT_OID_FUNC_ENTRY kFunctionToIntercept =
- { CERT_STORE_PROV_SYSTEM_W, &InterceptedOpenStoreW };
+ const CRYPT_OID_FUNC_ENTRY kFunctionToIntercept = {
+ CERT_STORE_PROV_SYSTEM_W,
+ reinterpret_cast<void*>(&InterceptedOpenStoreW)};
// Inject kFunctionToIntercept at the front of the linked list that
// crypt32 uses when CertOpenStore is called, replacing the existing
diff --git a/chromium/net/cert/x509_certificate.cc b/chromium/net/cert/x509_certificate.cc
index 615c03ae2fb..cfef4bb7da1 100644
--- a/chromium/net/cert/x509_certificate.cc
+++ b/chromium/net/cert/x509_certificate.cc
@@ -440,6 +440,20 @@ bool X509Certificate::Equals(const X509Certificate* other) const {
other->cert_buffer_.get());
}
+bool X509Certificate::EqualsIncludingChain(const X509Certificate* other) const {
+ if (intermediate_ca_certs_.size() != other->intermediate_ca_certs_.size() ||
+ !Equals(other)) {
+ return false;
+ }
+ for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) {
+ if (!x509_util::CryptoBufferEqual(intermediate_ca_certs_[i].get(),
+ other->intermediate_ca_certs_[i].get())) {
+ return false;
+ }
+ }
+ return true;
+}
+
bool X509Certificate::IsIssuedByEncoded(
const std::vector<std::string>& valid_issuers) {
std::vector<std::string> normalized_issuers;
diff --git a/chromium/net/cert/x509_certificate.h b/chromium/net/cert/x509_certificate.h
index 5497e2e8afb..156ad0bd351 100644
--- a/chromium/net/cert/x509_certificate.h
+++ b/chromium/net/cert/x509_certificate.h
@@ -183,6 +183,10 @@ class NET_EXPORT X509Certificate
// Does not consider any associated intermediates.
bool Equals(const X509Certificate* other) const;
+ // Returns true if this object and |other| represent the same certificate
+ // and intermediates.
+ bool EqualsIncludingChain(const X509Certificate* other) const;
+
// Do any of the given issuer names appear in this cert's chain of trust?
// |valid_issuers| is a list of DER-encoded X.509 DistinguishedNames.
bool IsIssuedByEncoded(const std::vector<std::string>& valid_issuers);
diff --git a/chromium/net/cert/x509_certificate_unittest.cc b/chromium/net/cert/x509_certificate_unittest.cc
index fcc94520314..5f617bf1440 100644
--- a/chromium/net/cert/x509_certificate_unittest.cc
+++ b/chromium/net/cert/x509_certificate_unittest.cc
@@ -732,6 +732,108 @@ TEST(X509CertificateTest, IntermediateCertificates) {
thawte_cert->cert_buffer()));
}
+TEST(X509CertificateTest, Equals) {
+ CertificateList certs = CreateCertificateListFromFile(
+ GetTestCertsDirectory(), "multi-root-chain1.pem",
+ X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
+ ASSERT_EQ(4u, certs.size());
+
+ // Comparing X509Certificates with no intermediates.
+ EXPECT_TRUE(certs[0]->Equals(certs[0].get()));
+ EXPECT_FALSE(certs[1]->Equals(certs[0].get()));
+ EXPECT_FALSE(certs[0]->Equals(certs[1].get()));
+ EXPECT_TRUE(certs[0]->EqualsIncludingChain(certs[0].get()));
+ EXPECT_FALSE(certs[1]->EqualsIncludingChain(certs[0].get()));
+ EXPECT_FALSE(certs[0]->EqualsIncludingChain(certs[1].get()));
+
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates1;
+ intermediates1.push_back(x509_util::DupCryptoBuffer(certs[1]->cert_buffer()));
+ scoped_refptr<X509Certificate> cert0_with_intermediate =
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(certs[0]->cert_buffer()),
+ std::move(intermediates1));
+ ASSERT_TRUE(cert0_with_intermediate);
+
+ // Comparing X509Certificate with one intermediate to X509Certificate with no
+ // intermediates.
+ EXPECT_TRUE(certs[0]->Equals(cert0_with_intermediate.get()));
+ EXPECT_TRUE(cert0_with_intermediate->Equals(certs[0].get()));
+ EXPECT_FALSE(certs[0]->EqualsIncludingChain(cert0_with_intermediate.get()));
+ EXPECT_FALSE(cert0_with_intermediate->EqualsIncludingChain(certs[0].get()));
+
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates2;
+ intermediates2.push_back(x509_util::DupCryptoBuffer(certs[2]->cert_buffer()));
+ scoped_refptr<X509Certificate> cert0_with_intermediate2 =
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(certs[0]->cert_buffer()),
+ std::move(intermediates1));
+ ASSERT_TRUE(cert0_with_intermediate2);
+
+ // Comparing X509Certificate with one intermediate to X509Certificate with
+ // one different intermediate.
+ EXPECT_TRUE(cert0_with_intermediate2->Equals(cert0_with_intermediate.get()));
+ EXPECT_TRUE(cert0_with_intermediate->Equals(cert0_with_intermediate2.get()));
+ EXPECT_FALSE(cert0_with_intermediate2->EqualsIncludingChain(
+ cert0_with_intermediate.get()));
+ EXPECT_FALSE(cert0_with_intermediate->EqualsIncludingChain(
+ cert0_with_intermediate2.get()));
+
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates12;
+ intermediates12.push_back(
+ x509_util::DupCryptoBuffer(certs[1]->cert_buffer()));
+ intermediates12.push_back(
+ x509_util::DupCryptoBuffer(certs[2]->cert_buffer()));
+ scoped_refptr<X509Certificate> cert0_with_intermediates12 =
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(certs[0]->cert_buffer()),
+ std::move(intermediates12));
+ ASSERT_TRUE(cert0_with_intermediates12);
+
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates21;
+ intermediates21.push_back(
+ x509_util::DupCryptoBuffer(certs[2]->cert_buffer()));
+ intermediates21.push_back(
+ x509_util::DupCryptoBuffer(certs[1]->cert_buffer()));
+ scoped_refptr<X509Certificate> cert0_with_intermediates21 =
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(certs[0]->cert_buffer()),
+ std::move(intermediates21));
+ ASSERT_TRUE(cert0_with_intermediates21);
+
+ // Comparing X509Certificate with two intermediates to X509Certificate with
+ // same two intermediates but in reverse order
+ EXPECT_TRUE(
+ cert0_with_intermediates21->Equals(cert0_with_intermediates12.get()));
+ EXPECT_TRUE(
+ cert0_with_intermediates12->Equals(cert0_with_intermediates21.get()));
+ EXPECT_FALSE(cert0_with_intermediates21->EqualsIncludingChain(
+ cert0_with_intermediates12.get()));
+ EXPECT_FALSE(cert0_with_intermediates12->EqualsIncludingChain(
+ cert0_with_intermediates21.get()));
+
+ std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates12b;
+ intermediates12b.push_back(
+ x509_util::DupCryptoBuffer(certs[1]->cert_buffer()));
+ intermediates12b.push_back(
+ x509_util::DupCryptoBuffer(certs[2]->cert_buffer()));
+ scoped_refptr<X509Certificate> cert0_with_intermediates12b =
+ X509Certificate::CreateFromBuffer(
+ x509_util::DupCryptoBuffer(certs[0]->cert_buffer()),
+ std::move(intermediates12b));
+ ASSERT_TRUE(cert0_with_intermediates12b);
+
+ // Comparing X509Certificate with two intermediates to X509Certificate with
+ // same two intermediates in same order.
+ EXPECT_TRUE(
+ cert0_with_intermediates12->Equals(cert0_with_intermediates12b.get()));
+ EXPECT_TRUE(
+ cert0_with_intermediates12b->Equals(cert0_with_intermediates12.get()));
+ EXPECT_TRUE(cert0_with_intermediates12->EqualsIncludingChain(
+ cert0_with_intermediates12b.get()));
+ EXPECT_TRUE(cert0_with_intermediates12b->EqualsIncludingChain(
+ cert0_with_intermediates12.get()));
+}
+
TEST(X509CertificateTest, IsIssuedByEncoded) {
base::FilePath certs_dir = GetTestCertsDirectory();
diff --git a/chromium/net/cert/x509_util.cc b/chromium/net/cert/x509_util.cc
index b0558744c57..9e6e2144f30 100644
--- a/chromium/net/cert/x509_util.cc
+++ b/chromium/net/cert/x509_util.cc
@@ -13,7 +13,9 @@
#include "build/build_config.h"
#include "crypto/openssl_util.h"
#include "crypto/rsa_private_key.h"
+#include "crypto/sha2.h"
#include "net/base/hash_value.h"
+#include "net/cert/asn1_util.h"
#include "net/cert/internal/cert_errors.h"
#include "net/cert/internal/name_constraints.h"
#include "net/cert/internal/parse_certificate.h"
@@ -202,23 +204,19 @@ bool CreateKeyAndSelfSignedCert(const std::string& subject,
std::string* der_cert) {
std::unique_ptr<crypto::RSAPrivateKey> new_key(
crypto::RSAPrivateKey::Create(kRSAKeyLength));
- if (!new_key.get())
+ if (!new_key)
return false;
- bool success = CreateSelfSignedCert(new_key.get(),
- kSignatureDigestAlgorithm,
- subject,
- serial_number,
- not_valid_before,
- not_valid_after,
- der_cert);
+ bool success = CreateSelfSignedCert(new_key->key(), kSignatureDigestAlgorithm,
+ subject, serial_number, not_valid_before,
+ not_valid_after, der_cert);
if (success)
*key = std::move(new_key);
return success;
}
-bool CreateSelfSignedCert(crypto::RSAPrivateKey* key,
+bool CreateSelfSignedCert(EVP_PKEY* key,
DigestAlgorithm alg,
const std::string& subject,
uint32_t serial_number,
@@ -256,7 +254,7 @@ bool CreateSelfSignedCert(crypto::RSAPrivateKey* key,
!AddTime(&validity, not_valid_before) ||
!AddTime(&validity, not_valid_after) ||
!AddNameWithCommonName(&tbs_cert, common_name) || // subject
- !EVP_marshal_public_key(&tbs_cert, key->key()) || // subjectPublicKeyInfo
+ !EVP_marshal_public_key(&tbs_cert, key) || // subjectPublicKeyInfo
!CBB_finish(cbb.get(), &tbs_cert_bytes, &tbs_cert_len)) {
return false;
}
@@ -275,8 +273,7 @@ bool CreateSelfSignedCert(crypto::RSAPrivateKey* key,
!AddRSASignatureAlgorithm(&cert, alg) ||
!CBB_add_asn1(&cert, &signature, CBS_ASN1_BITSTRING) ||
!CBB_add_u8(&signature, 0 /* no unused bits */) ||
- !EVP_DigestSignInit(ctx.get(), nullptr, ToEVP(alg), nullptr,
- key->key()) ||
+ !EVP_DigestSignInit(ctx.get(), nullptr, ToEVP(alg), nullptr, key) ||
// Compute the maximum signature length.
!EVP_DigestSign(ctx.get(), nullptr, &sig_len, tbs_cert_bytes,
tbs_cert_len) ||
@@ -353,6 +350,16 @@ ParseCertificateOptions DefaultParseCertificateOptions() {
return options;
}
+bool CalculateSha256SpkiHash(const CRYPTO_BUFFER* buffer, HashValue* hash) {
+ base::StringPiece spki;
+ if (!asn1::ExtractSPKIFromDERCert(CryptoBufferAsStringPiece(buffer), &spki)) {
+ return false;
+ }
+ *hash = HashValue(HASH_VALUE_SHA256);
+ crypto::SHA256HashString(spki, hash->data(), hash->size());
+ return true;
+}
+
} // namespace x509_util
} // namespace net
diff --git a/chromium/net/cert/x509_util.h b/chromium/net/cert/x509_util.h
index 6f0b8b215b0..6e4d97acdb5 100644
--- a/chromium/net/cert/x509_util.h
+++ b/chromium/net/cert/x509_util.h
@@ -11,10 +11,13 @@
#include <string>
#include <vector>
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string_piece.h"
#include "base/time/time.h"
+#include "net/base/hash_value.h"
#include "net/base/net_export.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
#include "third_party/boringssl/src/include/openssl/pool.h"
namespace crypto {
@@ -66,7 +69,7 @@ NET_EXPORT bool CreateKeyAndSelfSignedCert(
// Creates a self-signed certificate from a provided key, using the specified
// hash algorithm.
-NET_EXPORT bool CreateSelfSignedCert(crypto::RSAPrivateKey* key,
+NET_EXPORT bool CreateSelfSignedCert(EVP_PKEY* key,
DigestAlgorithm alg,
const std::string& subject,
uint32_t serial_number,
@@ -112,6 +115,12 @@ scoped_refptr<X509Certificate> CreateX509CertificateFromBuffers(
// Returns the default ParseCertificateOptions for the net stack.
ParseCertificateOptions DefaultParseCertificateOptions();
+// On success, returns true and updates |hash| to be the SHA-256 hash of the
+// subjectPublicKeyInfo of the certificate in |buffer|. If |buffer| is not a
+// valid certificate, returns false and |hash| is in an undefined state.
+NET_EXPORT bool CalculateSha256SpkiHash(const CRYPTO_BUFFER* buffer,
+ HashValue* hash) WARN_UNUSED_RESULT;
+
} // namespace x509_util
} // namespace net
diff --git a/chromium/net/cert/x509_util_unittest.cc b/chromium/net/cert/x509_util_unittest.cc
index c5d6b36b937..cbaadc8f4c6 100644
--- a/chromium/net/cert/x509_util_unittest.cc
+++ b/chromium/net/cert/x509_util_unittest.cc
@@ -137,7 +137,7 @@ TEST(X509UtilTest, CreateSelfSigned) {
std::string der_cert;
ASSERT_TRUE(x509_util::CreateSelfSignedCert(
- private_key.get(), x509_util::DIGEST_SHA256, "CN=subject", 1,
+ private_key->key(), x509_util::DIGEST_SHA256, "CN=subject", 1,
base::Time::Now(), base::Time::Now() + base::TimeDelta::FromDays(1),
&der_cert));
diff --git a/chromium/net/cert/x509_util_win.cc b/chromium/net/cert/x509_util_win.cc
index 9def51f963a..827ab4d8edc 100644
--- a/chromium/net/cert/x509_util_win.cc
+++ b/chromium/net/cert/x509_util_win.cc
@@ -7,7 +7,7 @@
#include "crypto/scoped_capi_types.h"
#include "crypto/sha2.h"
#include "net/cert/x509_certificate.h"
-#include "net/net_features.h"
+#include "net/net_buildflags.h"
#include "third_party/boringssl/src/include/openssl/pool.h"
namespace net {
diff --git a/chromium/net/cert_net/cert_net_fetcher_impl_unittest.cc b/chromium/net/cert_net/cert_net_fetcher_impl_unittest.cc
index 8eec0772d92..e2b4a4c236e 100644
--- a/chromium/net/cert_net/cert_net_fetcher_impl_unittest.cc
+++ b/chromium/net/cert_net/cert_net_fetcher_impl_unittest.cc
@@ -21,6 +21,7 @@
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/gtest_util.h"
#include "net/test/url_request/url_request_hanging_read_job.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_test_util.h"
@@ -52,7 +53,8 @@ class RequestContext : public URLRequestContext {
storage_.set_cert_transparency_verifier(
std::make_unique<MultiLogCTVerifier>());
storage_.set_ct_policy_enforcer(std::make_unique<CTPolicyEnforcer>());
- storage_.set_proxy_resolution_service(ProxyResolutionService::CreateFixed(no_proxy));
+ storage_.set_proxy_resolution_service(ProxyResolutionService::CreateFixed(
+ ProxyConfigWithAnnotation(no_proxy, TRAFFIC_ANNOTATION_FOR_TESTS)));
storage_.set_ssl_config_service(new SSLConfigServiceDefaults);
storage_.set_http_server_properties(
std::unique_ptr<HttpServerProperties>(new HttpServerPropertiesImpl()));
diff --git a/chromium/net/cert_net/nss_ocsp.cc b/chromium/net/cert_net/nss_ocsp.cc
index 1926cf6af2b..8325fbdee09 100644
--- a/chromium/net/cert_net/nss_ocsp.cc
+++ b/chromium/net/cert_net/nss_ocsp.cc
@@ -33,6 +33,7 @@
#include "base/synchronization/lock.h"
#include "base/threading/thread_checker.h"
#include "base/threading/thread_restrictions.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/host_port_pair.h"
@@ -71,8 +72,8 @@ class OCSPIOLoop {
void StartUsing() {
base::AutoLock autolock(lock_);
used_ = true;
- io_loop_ = base::MessageLoopForIO::current();
- DCHECK(io_loop_);
+ DCHECK(base::MessageLoopForIO::IsCurrent());
+ io_task_runner_ = base::ThreadTaskRunnerHandle::Get();
}
// Called on IO loop.
@@ -90,23 +91,6 @@ class OCSPIOLoop {
void AddRequest(OCSPRequestSession* request);
void RemoveRequest(OCSPRequestSession* request);
- // Clears internal state and calls |StartUsing()|. Should be called only in
- // the context of testing.
- void ReuseForTesting() {
- {
- base::AutoLock autolock(lock_);
- DCHECK(base::MessageLoopForIO::current());
- thread_checker_.DetachFromThread();
-
- // CalledOnValidThread is the only available API to reassociate
- // thread_checker_ with the current thread. Result ignored intentionally.
- ignore_result(thread_checker_.CalledOnValidThread());
- shutdown_ = false;
- used_ = false;
- }
- StartUsing();
- }
-
private:
friend struct base::LazyInstanceTraitsBase<OCSPIOLoop>;
@@ -114,12 +98,14 @@ class OCSPIOLoop {
void CancelAllRequests();
+ // Protects all members below.
mutable base::Lock lock_;
- bool shutdown_; // Protected by |lock_|.
- std::set<OCSPRequestSession*> requests_; // Protected by |lock_|.
- bool used_; // Protected by |lock_|.
+ bool shutdown_;
+ std::set<OCSPRequestSession*> requests_;
+ bool used_;
// This should not be modified after |used_|.
- base::MessageLoopForIO* io_loop_; // Protected by |lock_|.
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
+
base::ThreadChecker thread_checker_;
DISALLOW_COPY_AND_ASSIGN(OCSPIOLoop);
@@ -199,7 +185,6 @@ class OCSPRequestSession
buffer_(new IOBuffer(kRecvBufferSize)),
response_code_(-1),
cv_(&lock_),
- io_loop_(NULL),
finished_(false) {}
void SetPostData(const char* http_data, PRUint32 http_data_len,
@@ -217,9 +202,9 @@ class OCSPRequestSession
void Start() {
// At this point, it runs on worker thread.
- // |io_loop_| was initialized to be NULL in constructor, and
- // set only in StartURLRequest, so no need to lock |lock_| here.
- DCHECK(!io_loop_);
+ // |io_task_runner_| is only initialized in StartURLRequest, so no need to
+ // lock |lock_| here.
+ DCHECK(!io_task_runner_);
g_ocsp_io_loop.Get().PostTaskToIOLoop(
FROM_HERE,
base::Bind(&OCSPRequestSession::StartURLRequest, this));
@@ -230,7 +215,7 @@ class OCSPRequestSession
}
void Cancel() {
- // IO thread may set |io_loop_| to NULL, so protect by |lock_|.
+ // IO thread may reset |io_task_runner_|, so protect by |lock_|.
base::AutoLock autolock(lock_);
CancelLocked();
}
@@ -295,7 +280,7 @@ class OCSPRequestSession
const RedirectInfo& redirect_info,
bool* defer_redirect) override {
DCHECK_EQ(request_.get(), request);
- DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_);
+ DCHECK(io_task_runner_->BelongsToCurrentThread());
if (!redirect_info.new_url.SchemeIs("http")) {
// Prevent redirects to non-HTTP schemes, including HTTPS. This matches
@@ -306,7 +291,7 @@ class OCSPRequestSession
void OnResponseStarted(URLRequest* request, int net_error) override {
DCHECK_EQ(request_.get(), request);
- DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_);
+ DCHECK(io_task_runner_->BelongsToCurrentThread());
DCHECK_NE(ERR_IO_PENDING, net_error);
int bytes_read = 0;
@@ -321,7 +306,7 @@ class OCSPRequestSession
void OnReadCompleted(URLRequest* request, int bytes_read) override {
DCHECK_EQ(request_.get(), request);
- DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_);
+ DCHECK(io_task_runner_->BelongsToCurrentThread());
while (bytes_read > 0) {
data_.append(buffer_->data(), bytes_read);
@@ -334,7 +319,7 @@ class OCSPRequestSession
{
base::AutoLock autolock(lock_);
finished_ = true;
- io_loop_ = NULL;
+ io_task_runner_ = nullptr;
}
cv_.Signal();
Release(); // Balanced with StartURLRequest().
@@ -346,8 +331,8 @@ class OCSPRequestSession
#ifndef NDEBUG
{
base::AutoLock autolock(lock_);
- if (io_loop_)
- DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_);
+ if (io_task_runner_)
+ DCHECK(io_task_runner_->BelongsToCurrentThread());
}
#endif
if (request_) {
@@ -356,7 +341,7 @@ class OCSPRequestSession
{
base::AutoLock autolock(lock_);
finished_ = true;
- io_loop_ = NULL;
+ io_task_runner_ = nullptr;
}
cv_.Signal();
Release(); // Balanced with StartURLRequest().
@@ -371,14 +356,14 @@ class OCSPRequestSession
// a reference to this object, and so that thread doesn't need to lock
// |lock_| here.
DCHECK(!request_);
- DCHECK(!io_loop_);
+ DCHECK(!io_task_runner_);
}
// Must call this method while holding |lock_|.
void CancelLocked() {
lock_.AssertAcquired();
- if (io_loop_) {
- io_loop_->task_runner()->PostTask(
+ if (io_task_runner_) {
+ io_task_runner_->PostTask(
FROM_HERE, base::Bind(&OCSPRequestSession::CancelURLRequest, this));
}
}
@@ -396,8 +381,9 @@ class OCSPRequestSession
{
base::AutoLock autolock(lock_);
- DCHECK(!io_loop_);
- io_loop_ = base::MessageLoopForIO::current();
+ DCHECK(!io_task_runner_);
+ DCHECK(base::MessageLoopForIO::IsCurrent());
+ io_task_runner_ = base::ThreadTaskRunnerHandle::Get();
g_ocsp_io_loop.Get().AddRequest(this);
}
@@ -463,11 +449,13 @@ class OCSPRequestSession
scoped_refptr<HttpResponseHeaders> response_headers_;
std::string data_; // Results of the request
- // |lock_| protects |finished_| and |io_loop_|.
+ // |lock_| protects |finished_| and |io_task_runner_|.
mutable base::Lock lock_;
base::ConditionVariable cv_;
- base::MessageLoop* io_loop_; // Message loop of the IO thread
+ // TaskRunner for the IO thread. Set when StartURLRequest() is invoked (on the
+ // IO thread).
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
bool finished_;
DISALLOW_COPY_AND_ASSIGN(OCSPRequestSession);
@@ -518,18 +506,17 @@ class OCSPServerSession {
OCSPIOLoop::OCSPIOLoop()
: shutdown_(false),
- used_(false),
- io_loop_(NULL) {
+ used_(false) {
}
void OCSPIOLoop::Shutdown() {
// Safe to read outside lock since we only write on IO thread anyway.
DCHECK(thread_checker_.CalledOnValidThread());
- // Prevent the worker thread from trying to access |io_loop_|.
+ // Prevent the worker thread from trying to access |io_task_runner_|.
{
base::AutoLock autolock(lock_);
- io_loop_ = NULL;
+ io_task_runner_ = nullptr;
used_ = false;
shutdown_ = true;
}
@@ -544,8 +531,8 @@ void OCSPIOLoop::Shutdown() {
void OCSPIOLoop::PostTaskToIOLoop(const base::Location& from_here,
const base::Closure& task) {
base::AutoLock autolock(lock_);
- if (io_loop_)
- io_loop_->task_runner()->PostTask(from_here, task);
+ if (io_task_runner_)
+ io_task_runner_->PostTask(from_here, task);
}
void OCSPIOLoop::AddRequest(OCSPRequestSession* request) {
@@ -862,30 +849,10 @@ char* GetAlternateOCSPAIAInfo(CERTCertificate *cert) {
} // anonymous namespace
-void SetMessageLoopForNSSHttpIO() {
- // Must have a MessageLoopForIO.
- DCHECK(base::MessageLoopForIO::current());
-
- bool used = g_ocsp_io_loop.Get().used();
-
- // Should not be called when g_ocsp_io_loop has already been used.
- DCHECK(!used);
-}
-
void EnsureNSSHttpIOInit() {
- g_ocsp_io_loop.Get().StartUsing();
g_ocsp_nss_initialization.Get();
}
-void ShutdownNSSHttpIO() {
- g_ocsp_io_loop.Get().Shutdown();
-}
-
-void ResetNSSHttpIOForTesting() {
- g_ocsp_io_loop.Get().ReuseForTesting();
-}
-
-// This function would be called before NSS initialization.
void SetURLRequestContextForNSSHttpIO(URLRequestContext* request_context) {
pthread_mutex_lock(&g_request_context_lock);
if (request_context) {
@@ -893,6 +860,12 @@ void SetURLRequestContextForNSSHttpIO(URLRequestContext* request_context) {
}
g_request_context = request_context;
pthread_mutex_unlock(&g_request_context_lock);
+
+ if (request_context) {
+ g_ocsp_io_loop.Get().StartUsing();
+ } else {
+ g_ocsp_io_loop.Get().Shutdown();
+ }
}
} // namespace net
diff --git a/chromium/net/cert_net/nss_ocsp.h b/chromium/net/cert_net/nss_ocsp.h
index a422cb22e5a..2429f41a00a 100644
--- a/chromium/net/cert_net/nss_ocsp.h
+++ b/chromium/net/cert_net/nss_ocsp.h
@@ -11,26 +11,13 @@ namespace net {
class URLRequestContext;
-// Sets the MessageLoop for NSS's HTTP client functions (i.e. OCSP, CA
-// certificate and CRL fetches) to the current message loop. This should be
-// called before EnsureNSSHttpIOInit() if you want to control the message loop.
-NET_EXPORT void SetMessageLoopForNSSHttpIO();
-
-// Initializes HTTP client functions for NSS. This must be called before any
-// certificate verification functions. This function is thread-safe, and HTTP
-// handlers will only ever be initialized once. ShutdownNSSHttpIO() must be
-// called on shutdown.
+// Initializes HTTP client functions for NSS. This function is thread-safe,
+// and HTTP handlers will only ever be initialized once.
NET_EXPORT void EnsureNSSHttpIOInit();
-// This should be called once on shutdown to stop issuing URLRequests for NSS
-// related HTTP fetches.
-NET_EXPORT void ShutdownNSSHttpIO();
-
-// Can be called after a call to |ShutdownNSSHttpIO()| to reset internal state
-// and associate it with the current thread.
-NET_EXPORT void ResetNSSHttpIOForTesting();
-
-// Sets the URLRequestContext for HTTP requests issued by NSS.
+// Sets the URLRequestContext and MessageLoop for HTTP requests issued by NSS
+// (i.e. OCSP, CA certificate and CRL fetches). Must be called again with
+// |request_context|=nullptr before the URLRequestContext is destroyed.
NET_EXPORT void SetURLRequestContextForNSSHttpIO(
URLRequestContext* request_context);
diff --git a/chromium/net/cert_net/nss_ocsp_unittest.cc b/chromium/net/cert_net/nss_ocsp_unittest.cc
index 45004f55dca..b4c5947a24b 100644
--- a/chromium/net/cert_net/nss_ocsp_unittest.cc
+++ b/chromium/net/cert_net/nss_ocsp_unittest.cc
@@ -102,11 +102,10 @@ class NssHttpTest : public ::testing::Test {
std::move(handler));
SetURLRequestContextForNSSHttpIO(&context_);
- EnsureNSSHttpIOInit();
}
void TearDown() override {
- ShutdownNSSHttpIO();
+ SetURLRequestContextForNSSHttpIO(nullptr);
if (handler_)
URLRequestFilter::GetInstance()->RemoveHostnameHandler("http", kAiaHost);
@@ -130,9 +129,8 @@ class NssHttpTest : public ::testing::Test {
std::unique_ptr<CertVerifier> verifier_;
};
-// Tests that when using NSS to verify certificates, and IO is enabled,
-// that a request to fetch missing intermediate certificates is
-// made successfully.
+// Tests that when using NSS to verify certificates that a request to fetch
+// missing intermediate certificates is made successfully.
TEST_F(NssHttpTest, TestAia) {
scoped_refptr<X509Certificate> test_cert(
ImportCertFromFile(GetTestCertsDirectory(), "aia-cert.pem"));
@@ -148,7 +146,7 @@ TEST_F(NssHttpTest, TestAia) {
TestCompletionCallback test_callback;
std::unique_ptr<CertVerifier::Request> request;
- int flags = CertVerifier::VERIFY_CERT_IO_ENABLED;
+ int flags = 0;
int error = verifier()->Verify(
CertVerifier::RequestParams(test_cert, "aia-host.invalid", flags,
std::string(), CertificateList()),
diff --git a/chromium/net/cookies/OWNERS b/chromium/net/cookies/OWNERS
index db28c8e2140..fb0dd2d56c8 100644
--- a/chromium/net/cookies/OWNERS
+++ b/chromium/net/cookies/OWNERS
@@ -1,6 +1,6 @@
estark@chromium.org
mkwst@chromium.org
mmenke@chromium.org
-rdsmith@chromium.org
+morlovich@chromium.org
# COMPONENT: Internals>Network>Cookies
diff --git a/chromium/net/cookies/canonical_cookie.cc b/chromium/net/cookies/canonical_cookie.cc
index 0939cdd319f..ffd247ea73c 100644
--- a/chromium/net/cookies/canonical_cookie.cc
+++ b/chromium/net/cookies/canonical_cookie.cc
@@ -346,36 +346,7 @@ bool CanonicalCookie::IsOnPath(const std::string& url_path) const {
}
bool CanonicalCookie::IsDomainMatch(const std::string& host) const {
- // Can domain match in two ways; as a domain cookie (where the cookie
- // domain begins with ".") or as a host cookie (where it doesn't).
-
- // Some consumers of the CookieMonster expect to set cookies on
- // URLs like http://.strange.url. To retrieve cookies in this instance,
- // we allow matching as a host cookie even when the domain_ starts with
- // a period.
- if (host == domain_)
- return true;
-
- // Domain cookie must have an initial ".". To match, it must be
- // equal to url's host with initial period removed, or a suffix of
- // it.
-
- // Arguably this should only apply to "http" or "https" cookies, but
- // extension cookie tests currently use the funtionality, and if we
- // ever decide to implement that it should be done by preventing
- // such cookies from being set.
- if (domain_.empty() || domain_[0] != '.')
- return false;
-
- // The host with a "." prefixed.
- if (domain_.compare(1, std::string::npos, host) == 0)
- return true;
-
- // A pure suffix of the host (ok since we know the domain already
- // starts with a ".")
- return (host.length() > domain_.length() &&
- host.compare(host.length() - domain_.length(),
- domain_.length(), domain_) == 0);
+ return cookie_util::IsDomainMatch(domain_, host);
}
bool CanonicalCookie::IncludeForRequestURL(const GURL& url,
diff --git a/chromium/net/cookies/canonical_cookie_unittest.cc b/chromium/net/cookies/canonical_cookie_unittest.cc
index 04c050bf215..97d25ef455b 100644
--- a/chromium/net/cookies/canonical_cookie_unittest.cc
+++ b/chromium/net/cookies/canonical_cookie_unittest.cc
@@ -148,21 +148,25 @@ TEST(CanonicalCookieTest, Create) {
EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie->SameSite());
}
-TEST(CanonicalCookieTest, CreateInvalidSameSite) {
+TEST(CanonicalCookieTest, CreateNonStandardSameSite) {
GURL url("http://www.example.com/test/foo.html");
base::Time now = base::Time::Now();
std::unique_ptr<CanonicalCookie> cookie;
CookieOptions options;
- // Invalid 'SameSite' attribute values.
options.set_same_site_cookie_mode(
CookieOptions::SameSiteCookieMode::INCLUDE_STRICT_AND_LAX);
- cookie = CanonicalCookie::Create(url, "A=2; SameSite=Invalid", now, options);
- EXPECT_EQ(nullptr, cookie.get());
+ // Non-standard value for the SameSite attribute.
+ cookie =
+ CanonicalCookie::Create(url, "A=2; SameSite=NonStandard", now, options);
+ EXPECT_TRUE(cookie.get());
+ EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie->SameSite());
+ // Omit value for the SameSite attribute.
cookie = CanonicalCookie::Create(url, "A=2; SameSite", now, options);
- EXPECT_EQ(nullptr, cookie.get());
+ EXPECT_TRUE(cookie.get());
+ EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie->SameSite());
}
TEST(CanonicalCookieTest, CreateInvalidHttpOnly) {
diff --git a/chromium/net/cookies/cookie_change_dispatcher.h b/chromium/net/cookies/cookie_change_dispatcher.h
index 8bea41b29ed..8b48c046f6a 100644
--- a/chromium/net/cookies/cookie_change_dispatcher.h
+++ b/chromium/net/cookies/cookie_change_dispatcher.h
@@ -110,6 +110,11 @@ class CookieChangeDispatcher {
const std::string& name,
CookieChangeCallback callback) WARN_UNUSED_RESULT = 0;
+ // Observe changes to the cookies that would be sent for a request to |url|.
+ virtual std::unique_ptr<CookieChangeSubscription> AddCallbackForUrl(
+ const GURL& url,
+ CookieChangeCallback callback) WARN_UNUSED_RESULT = 0;
+
// Observe all the CookieStore's changes.
//
// The callback will not observe a few bookkeeping changes.
diff --git a/chromium/net/cookies/cookie_change_dispatcher_test_helpers.cc b/chromium/net/cookies/cookie_change_dispatcher_test_helpers.cc
new file mode 100644
index 00000000000..0db6daaa5e8
--- /dev/null
+++ b/chromium/net/cookies/cookie_change_dispatcher_test_helpers.cc
@@ -0,0 +1,33 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cookies/cookie_change_dispatcher_test_helpers.h"
+
+#include "base/logging.h"
+
+namespace net {
+
+// Google Test helper.
+std::ostream& operator<<(std::ostream& os, const CookieChangeCause& cause) {
+ switch (cause) {
+ case CookieChangeCause::INSERTED:
+ return os << "INSERTED";
+ case CookieChangeCause::EXPLICIT:
+ return os << "EXPLICIT";
+ case CookieChangeCause::UNKNOWN_DELETION:
+ return os << "UNKNOWN_DELETION";
+ case CookieChangeCause::OVERWRITE:
+ return os << "OVERWRITE";
+ case CookieChangeCause::EXPIRED:
+ return os << "EXPIRED";
+ case CookieChangeCause::EVICTED:
+ return os << "EVICTED";
+ case CookieChangeCause::EXPIRED_OVERWRITE:
+ return os << "EXPIRED_OVERWRITE";
+ }
+ NOTREACHED();
+ return os;
+}
+
+} // namespace net
diff --git a/chromium/net/cookies/cookie_change_dispatcher_test_helpers.h b/chromium/net/cookies/cookie_change_dispatcher_test_helpers.h
new file mode 100644
index 00000000000..5ef6d9cd4d8
--- /dev/null
+++ b/chromium/net/cookies/cookie_change_dispatcher_test_helpers.h
@@ -0,0 +1,19 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_COOKIES_COOKIE_CHANGE_DISPATCHER_TEST_HELPERS_H_
+#define NET_COOKIES_COOKIE_CHANGE_DISPATCHER_TEST_HELPERS_H_
+
+#include <ostream>
+
+#include "net/cookies/cookie_change_dispatcher.h"
+
+namespace net {
+
+// Google Test helper for printing CookieChangeCause values.
+std::ostream& operator<<(std::ostream& os, const CookieChangeCause& cause);
+
+} // namespace net
+
+#endif // NET_COOKIES_COOKIE_CHANGE_DISPATCHER_TEST_HELPERS_H_
diff --git a/chromium/net/cookies/cookie_constants.h b/chromium/net/cookies/cookie_constants.h
index 61e1c0a0c0c..3f5b3cf7dda 100644
--- a/chromium/net/cookies/cookie_constants.h
+++ b/chromium/net/cookies/cookie_constants.h
@@ -37,7 +37,7 @@ NET_EXPORT std::string CookiePriorityToString(CookiePriority priority);
// Defaults to COOKIE_PRIORITY_DEFAULT for empty or unrecognized strings.
NET_EXPORT CookiePriority StringToCookiePriority(const std::string& priority);
-// Converst the Set-Cookie header SameSite token |same_site| to a
+// Converts the Set-Cookie header SameSite token |same_site| to a
// CookieSameSite. Defaults to CookieSameSite::DEFAULT_MODE for empty or
// unrecognized strings.
NET_EXPORT CookieSameSite StringToCookieSameSite(const std::string& same_site);
diff --git a/chromium/net/cookies/cookie_monster.cc b/chromium/net/cookies/cookie_monster.cc
index ce09270fc62..46df1b24378 100644
--- a/chromium/net/cookies/cookie_monster.cc
+++ b/chromium/net/cookies/cookie_monster.cc
@@ -49,17 +49,21 @@
#include "base/bind.h"
#include "base/callback.h"
+#include "base/debug/dump_without_crashing.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "base/timer/elapsed_timer.h"
+#include "base/trace_event/process_memory_dump.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_monster_change_dispatcher.h"
@@ -97,8 +101,8 @@ static const int kMinutesInTenYears = 10 * 365 * 24 * 60;
namespace {
-void MayeRunDeleteCallback(base::WeakPtr<net::CookieMonster> cookie_monster,
- base::OnceClosure callback) {
+void MaybeRunDeleteCallback(base::WeakPtr<net::CookieMonster> cookie_monster,
+ base::OnceClosure callback) {
if (cookie_monster && callback)
std::move(callback).Run();
}
@@ -122,6 +126,22 @@ void MaybeRunCookieCallback(base::OnceCallback<void(T)> callback,
std::move(callback).Run(result);
}
+// Wraps a OnceClosure -- specifically one used by
+// |GetCookieListWithOptionsAsync()| -- with additional bound state to track the
+// duration between when its creation and destruction time.
+// See https://crbug.com/824024 for context.
+base::OnceClosure InstrumentGetCookieListClosure(base::OnceClosure closure) {
+ return base::BindOnce(
+ [](std::unique_ptr<base::ElapsedTimer> timer, base::OnceClosure closure) {
+ UMA_HISTOGRAM_CUSTOM_TIMES("Cookie.GetCookieListCompletionTime",
+ timer->Elapsed(),
+ base::TimeDelta::FromMilliseconds(10),
+ base::TimeDelta::FromSeconds(60), 50);
+ std::move(closure).Run();
+ },
+ std::make_unique<base::ElapsedTimer>(), std::move(closure));
+}
+
} // namespace
namespace net {
@@ -331,31 +351,31 @@ size_t CountCookiesForPossibleDeletion(
} // namespace
-CookieMonster::CookieMonster(PersistentCookieStore* store)
+CookieMonster::CookieMonster(scoped_refptr<PersistentCookieStore> store)
: CookieMonster(
- store,
+ std::move(store),
nullptr,
base::TimeDelta::FromSeconds(kDefaultAccessUpdateThresholdSeconds)) {}
-CookieMonster::CookieMonster(PersistentCookieStore* store,
+CookieMonster::CookieMonster(scoped_refptr<PersistentCookieStore> store,
ChannelIDService* channel_id_service)
: CookieMonster(
- store,
+ std::move(store),
channel_id_service,
base::TimeDelta::FromSeconds(kDefaultAccessUpdateThresholdSeconds)) {}
-CookieMonster::CookieMonster(PersistentCookieStore* store,
+CookieMonster::CookieMonster(scoped_refptr<PersistentCookieStore> store,
base::TimeDelta last_access_threshold)
- : CookieMonster(store, nullptr, last_access_threshold) {}
+ : CookieMonster(std::move(store), nullptr, last_access_threshold) {}
-CookieMonster::CookieMonster(PersistentCookieStore* store,
+CookieMonster::CookieMonster(scoped_refptr<PersistentCookieStore> store,
ChannelIDService* channel_id_service,
base::TimeDelta last_access_threshold)
: initialized_(false),
started_fetching_all_cookies_(false),
finished_fetching_all_cookies_(false),
seen_global_task_(false),
- store_(store),
+ store_(std::move(store)),
last_access_threshold_(last_access_threshold),
channel_id_service_(channel_id_service),
last_statistic_record_time_(base::Time::Now()),
@@ -446,12 +466,12 @@ void CookieMonster::GetCookieListWithOptionsAsync(
const CookieOptions& options,
GetCookieListCallback callback) {
DoCookieCallbackForURL(
- base::BindOnce(
+ InstrumentGetCookieListClosure(base::BindOnce(
// base::Unretained is safe as DoCookieCallbackForURL stores
// the callback on |*this|, so the callback will not outlive
// the object.
&CookieMonster::GetCookieListWithOptions, base::Unretained(this), url,
- options, std::move(callback)),
+ options, std::move(callback))),
url);
}
@@ -565,6 +585,32 @@ bool CookieMonster::IsEphemeral() {
return store_.get() == nullptr;
}
+void CookieMonster::DumpMemoryStats(
+ base::trace_event::ProcessMemoryDump* pmd,
+ const std::string& parent_absolute_name) const {
+ const char kRelPath[] = "/cookie_monster";
+
+ pmd->CreateAllocatorDump(parent_absolute_name + kRelPath + "/cookies")
+ ->AddScalar(base::trace_event::MemoryAllocatorDump::kNameObjectCount,
+ base::trace_event::MemoryAllocatorDump::kUnitsObjects,
+ cookies_.size());
+
+ pmd->CreateAllocatorDump(parent_absolute_name + kRelPath +
+ "/tasks_pending_global")
+ ->AddScalar(base::trace_event::MemoryAllocatorDump::kNameObjectCount,
+ base::trace_event::MemoryAllocatorDump::kUnitsObjects,
+ tasks_pending_.size());
+
+ size_t total_pending_for_key = 0;
+ for (const auto& kv : tasks_pending_for_key_)
+ total_pending_for_key += kv.second.size();
+ pmd->CreateAllocatorDump(parent_absolute_name + kRelPath +
+ "/tasks_pending_for_key")
+ ->AddScalar(base::trace_event::MemoryAllocatorDump::kNameObjectCount,
+ base::trace_event::MemoryAllocatorDump::kUnitsObjects,
+ total_pending_for_key);
+}
+
CookieMonster::~CookieMonster() {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -652,7 +698,7 @@ void CookieMonster::DeleteAllCreatedBetween(const Time& delete_begin,
}
FlushStore(
- base::BindOnce(&MayeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(),
+ base::BindOnce(&MaybeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(),
callback ? base::BindOnce(std::move(callback), num_deleted)
: base::OnceClosure()));
}
@@ -680,7 +726,7 @@ void CookieMonster::DeleteAllCreatedBetweenWithPredicate(
}
FlushStore(
- base::BindOnce(&MayeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(),
+ base::BindOnce(&MaybeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(),
callback ? base::BindOnce(std::move(callback), num_deleted)
: base::OnceClosure()));
}
@@ -749,7 +795,7 @@ void CookieMonster::DeleteCookie(const GURL& url,
}
}
- FlushStore(base::BindOnce(&MayeRunDeleteCallback,
+ FlushStore(base::BindOnce(&MaybeRunDeleteCallback,
weak_ptr_factory_.GetWeakPtr(),
// No callback null check needed as BindOnce
// is not being called and MaybeRunDeleteCallback
@@ -764,15 +810,21 @@ void CookieMonster::DeleteCanonicalCookie(const CanonicalCookie& cookie,
uint32_t result = 0u;
for (CookieMapItPair its = cookies_.equal_range(GetKey(cookie.Domain()));
its.first != its.second; ++its.first) {
- // The creation date acts as the unique index...
- if (its.first->second->CreationDate() == cookie.CreationDate()) {
+ const std::unique_ptr<CanonicalCookie>& candidate = its.first->second;
+ // Historically, this has refused modification if the cookie has changed
+ // value in between the CanonicalCookie object was returned by a getter
+ // and when this ran. The later parts of the conditional (everything but
+ // the equivalence check) attempt to preserve this behavior.
+ if (candidate->IsEquivalent(cookie) &&
+ candidate->CreationDate() == cookie.CreationDate() &&
+ candidate->Value() == cookie.Value()) {
InternalDeleteCookie(its.first, true, DELETE_COOKIE_EXPLICIT);
result = 1u;
break;
}
}
FlushStore(
- base::BindOnce(&MayeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(),
+ base::BindOnce(&MaybeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(),
callback ? base::BindOnce(std::move(callback), result)
: base::OnceClosure()));
}
@@ -794,7 +846,7 @@ void CookieMonster::DeleteSessionCookies(DeleteCallback callback) {
}
FlushStore(
- base::BindOnce(&MayeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(),
+ base::BindOnce(&MaybeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(),
callback ? base::BindOnce(std::move(callback), num_deleted)
: base::OnceClosure()));
}
@@ -872,28 +924,17 @@ void CookieMonster::StoreLoadedCookies(
CookieItVector cookies_with_control_chars;
for (auto& cookie : cookies) {
- int64_t cookie_creation_time = cookie->CreationDate().ToInternalValue();
-
- if (creation_times_.insert(cookie_creation_time).second) {
- CanonicalCookie* cookie_ptr = cookie.get();
- CookieMap::iterator inserted = InternalInsertCookie(
- GetKey(cookie_ptr->Domain()), std::move(cookie), false);
- const Time cookie_access_time(cookie_ptr->LastAccessDate());
- if (earliest_access_time_.is_null() ||
- cookie_access_time < earliest_access_time_)
- earliest_access_time_ = cookie_access_time;
-
- if (ContainsControlCharacter(cookie_ptr->Name()) ||
- ContainsControlCharacter(cookie_ptr->Value())) {
- cookies_with_control_chars.push_back(inserted);
- }
- } else {
- LOG(ERROR) << base::StringPrintf(
- "Found cookies with duplicate creation "
- "times in backing store: "
- "{name='%s', domain='%s', path='%s'}",
- cookie->Name().c_str(), cookie->Domain().c_str(),
- cookie->Path().c_str());
+ CanonicalCookie* cookie_ptr = cookie.get();
+ CookieMap::iterator inserted = InternalInsertCookie(
+ GetKey(cookie_ptr->Domain()), std::move(cookie), false);
+ const Time cookie_access_time(cookie_ptr->LastAccessDate());
+ if (earliest_access_time_.is_null() ||
+ cookie_access_time < earliest_access_time_)
+ earliest_access_time_ = cookie_access_time;
+
+ if (ContainsControlCharacter(cookie_ptr->Name()) ||
+ ContainsControlCharacter(cookie_ptr->Value())) {
+ cookies_with_control_chars.push_back(inserted);
}
}
@@ -943,7 +984,6 @@ void CookieMonster::InvokeQueue() {
DCHECK(tasks_pending_for_key_.empty());
finished_fetching_all_cookies_ = true;
- creation_times_.clear();
keys_loaded_.clear();
}
@@ -969,7 +1009,7 @@ void CookieMonster::TrimDuplicateCookiesForKey(const std::string& key,
DCHECK(thread_checker_.CalledOnValidThread());
// Set of cookies ordered by creation time.
- typedef std::set<CookieMap::iterator, OrderByCreationTimeDesc> CookieSet;
+ typedef std::multiset<CookieMap::iterator, OrderByCreationTimeDesc> CookieSet;
// Helper map we populate to find the duplicates.
typedef std::map<CookieSignature, CookieSet> EquivalenceMap;
@@ -993,9 +1033,7 @@ void CookieMonster::TrimDuplicateCookiesForKey(const std::string& key,
// We save the iterator into |cookies_| rather than the actual cookie
// pointer, since we may need to delete it later.
- bool insert_success = set.insert(it).second;
- DCHECK(insert_success)
- << "Duplicate creation times found in duplicate cookie name scan.";
+ set.insert(it);
}
// If there were no duplicates, we are done!
@@ -1016,8 +1054,9 @@ void CookieMonster::TrimDuplicateCookiesForKey(const std::string& key,
continue; // This cookiename/path has no duplicates.
num_duplicates_found += dupes.size() - 1;
- // Since |dups| is sorted by creation time (descending), the first cookie
- // is the most recent one, so we will keep it. The rest are duplicates.
+ // Since |dupes| is sorted by creation time (descending), the first cookie
+ // is the most recent one (or tied for it), so we will keep it. The rest are
+ // duplicates.
dupes.erase(dupes.begin());
LOG(ERROR) << base::StringPrintf(
diff --git a/chromium/net/cookies/cookie_monster.h b/chromium/net/cookies/cookie_monster.h
index 99edf03b24b..2a691c7697c 100644
--- a/chromium/net/cookies/cookie_monster.h
+++ b/chromium/net/cookies/cookie_monster.h
@@ -57,9 +57,6 @@ class CookieChangeDispatcher;
// latter case, the cookie callback will be queued in tasks_pending_for_key_
// while PermanentCookieStore loads cookies for the specified domain key on DB
// thread.
-//
-// TODO(deanm) Implement CookieMonster, the cookie database.
-// - Verify that our domain enforcement and non-dotted handling is correct
class NET_EXPORT CookieMonster : public CookieStore {
public:
class PersistentCookieStore;
@@ -134,16 +131,16 @@ class NET_EXPORT CookieMonster : public CookieStore {
// this class, but it must remain valid for the duration of the cookie
// monster's existence. If |store| is NULL, then no backing store will be
// updated.
- explicit CookieMonster(PersistentCookieStore* store);
+ explicit CookieMonster(scoped_refptr<PersistentCookieStore> store);
// Like above, but includes a non-owning pointer |channel_id_service| for the
// corresponding ChannelIDService used with this CookieStore. The
// |channel_id_service| must outlive the CookieMonster.
- CookieMonster(PersistentCookieStore* store,
+ CookieMonster(scoped_refptr<PersistentCookieStore> store,
ChannelIDService* channel_id_service);
// Only used during unit testing.
- CookieMonster(PersistentCookieStore* store,
+ CookieMonster(scoped_refptr<PersistentCookieStore> store,
base::TimeDelta last_access_threshold);
~CookieMonster() override;
@@ -207,6 +204,9 @@ class NET_EXPORT CookieMonster : public CookieStore {
bool IsEphemeral() override;
+ void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
+ const std::string& parent_absolute_name) const override;
+
// Find a key based on the given domain, which will be used to find all
// cookies potentially relevant to it. This is used for lookup in cookies_ as
// well as for PersistentCookieStore::LoadCookiesForKey. See comment on keys
@@ -214,7 +214,7 @@ class NET_EXPORT CookieMonster : public CookieStore {
static std::string GetKey(base::StringPiece domain);
private:
- CookieMonster(PersistentCookieStore* store,
+ CookieMonster(scoped_refptr<PersistentCookieStore> store,
ChannelIDService* channel_id_service,
base::TimeDelta last_access_threshold);
@@ -643,12 +643,6 @@ class NET_EXPORT CookieMonster : public CookieStore {
// wanted. Thus this value is not initialized.
base::Time earliest_access_time_;
- // During loading, holds the set of all loaded cookie creation times. Used to
- // avoid ever letting cookies with duplicate creation times into the store;
- // that way we don't have to worry about what sections of code are safe
- // to call while it's in that state.
- std::set<int64_t> creation_times_;
-
std::vector<std::string> cookieable_schemes_;
ChannelIDService* channel_id_service_;
diff --git a/chromium/net/cookies/cookie_monster_change_dispatcher.cc b/chromium/net/cookies/cookie_monster_change_dispatcher.cc
index f3b1ef7dea8..2eadab6ca65 100644
--- a/chromium/net/cookies/cookie_monster_change_dispatcher.cc
+++ b/chromium/net/cookies/cookie_monster_change_dispatcher.cc
@@ -4,13 +4,11 @@
#include "net/cookies/cookie_monster_change_dispatcher.h"
-#include <memory>
-#include <string>
-
#include "base/bind.h"
+#include "base/strings/string_piece.h"
#include "base/task_runner.h"
-#include "base/threading/thread_checker.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_change_dispatcher.h"
@@ -18,84 +16,126 @@ namespace net {
namespace {
-// This class owns the CookieChangeCallbackList::Subscription,
-// thus guaranteeing destruction when it is destroyed. In addition, it
-// wraps the callback for a particular subscription, guaranteeing that it
-// won't be run even if a PostTask completes after the subscription has
-// been destroyed.
-class CookieMonsterChangeSubscription : public CookieChangeSubscription {
- public:
- using CookieChangeCallbackList =
- CookieMonsterChangeDispatcher::CookieChangeCallbackList;
-
- CookieMonsterChangeSubscription(const CookieChangeCallback& callback)
- : callback_(callback), weak_ptr_factory_(this) {}
- ~CookieMonsterChangeSubscription() override {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- }
+// Special key in GlobalDomainMap for global listeners.
+constexpr base::StringPiece kGlobalDomainKey = base::StringPiece("\0", 1);
- void SetCallbackSubscription(
- std::unique_ptr<CookieChangeCallbackList::Subscription> subscription) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+//
+constexpr base::StringPiece kGlobalNameKey = base::StringPiece("\0", 1);
- subscription_ = std::move(subscription);
- }
+} // anonymous namespace
- // The returned callback runs the callback passed to the constructor
- // directly as long as this object hasn't been destroyed.
- CookieChangeCallback WeakCallback() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+CookieMonsterChangeDispatcher::Subscription::Subscription(
+ base::WeakPtr<CookieMonsterChangeDispatcher> change_dispatcher,
+ std::string domain_key,
+ std::string name_key,
+ GURL url,
+ net::CookieChangeCallback callback)
+ : change_dispatcher_(std::move(change_dispatcher)),
+ domain_key_(std::move(domain_key)),
+ name_key_(std::move(name_key)),
+ url_(std::move(url)),
+ callback_(std::move(callback)),
+ task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ weak_ptr_factory_(this) {
+ DCHECK(url_.is_valid() || url_.is_empty());
+ DCHECK_EQ(url_.is_empty(), domain_key_ == kGlobalDomainKey);
+
+ // The net::CookieOptions are hard-coded for now, but future APIs may set
+ // different options. For example, JavaScript observers will not be allowed to
+ // see HTTP-only changes.
+ options_.set_include_httponly();
+ options_.set_same_site_cookie_mode(
+ CookieOptions::SameSiteCookieMode::INCLUDE_STRICT_AND_LAX);
+}
- return base::BindRepeating(&CookieMonsterChangeSubscription::DispatchChange,
- weak_ptr_factory_.GetWeakPtr());
- }
+CookieMonsterChangeDispatcher::Subscription::~Subscription() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- private:
- void DispatchChange(const CanonicalCookie& cookie, CookieChangeCause cause) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ change_dispatcher_->UnlinkSubscription(this);
+}
- callback_.Run(cookie, cause);
- }
+void CookieMonsterChangeDispatcher::Subscription::DispatchChange(
+ const net::CanonicalCookie& cookie,
+ net::CookieChangeCause change_cause) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- const CookieChangeCallback callback_;
- std::unique_ptr<CookieChangeCallbackList::Subscription> subscription_;
+ if (!url_.is_empty() && !cookie.IncludeForRequestURL(url_, options_))
+ return;
- THREAD_CHECKER(thread_checker_);
- base::WeakPtrFactory<CookieMonsterChangeSubscription> weak_ptr_factory_;
+ // TODO(mmenke, pwnall): Run callbacks synchronously?
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&Subscription::DoDispatchChange,
+ weak_ptr_factory_.GetWeakPtr(), cookie, change_cause));
+}
- DISALLOW_COPY_AND_ASSIGN(CookieMonsterChangeSubscription);
-};
+void CookieMonsterChangeDispatcher::Subscription::DoDispatchChange(
+ const net::CanonicalCookie& cookie,
+ net::CookieChangeCause change_cause) const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-void RunAsync(scoped_refptr<base::TaskRunner> proxy,
- const CookieChangeCallback& callback,
- const CanonicalCookie& cookie,
- CookieChangeCause cause) {
- proxy->PostTask(FROM_HERE, base::BindRepeating(callback, cookie, cause));
+ callback_.Run(cookie, change_cause);
}
-} // anonymous namespace
+CookieMonsterChangeDispatcher::CookieMonsterChangeDispatcher()
+ : weak_ptr_factory_(this) {}
-CookieMonsterChangeDispatcher::CookieMonsterChangeDispatcher() = default;
-CookieMonsterChangeDispatcher::~CookieMonsterChangeDispatcher() = default;
+CookieMonsterChangeDispatcher::~CookieMonsterChangeDispatcher() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+}
+
+// static
+std::string CookieMonsterChangeDispatcher::DomainKey(
+ const std::string& domain) {
+ std::string domain_key =
+ net::registry_controlled_domains::GetDomainAndRegistry(
+ domain, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
+ DCHECK_NE(domain_key, kGlobalDomainKey);
+ return domain_key;
+}
+
+// static
+std::string CookieMonsterChangeDispatcher::DomainKey(const GURL& url) {
+ std::string domain_key =
+ net::registry_controlled_domains::GetDomainAndRegistry(
+ url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
+ DCHECK_NE(domain_key, kGlobalDomainKey);
+ return domain_key;
+}
+
+// static
+std::string CookieMonsterChangeDispatcher::NameKey(std::string name) {
+ DCHECK_NE(name, kGlobalNameKey);
+ return name;
+}
std::unique_ptr<CookieChangeSubscription>
CookieMonsterChangeDispatcher::AddCallbackForCookie(
- const GURL& gurl,
+ const GURL& url,
const std::string& name,
CookieChangeCallback callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- std::pair<GURL, std::string> key(gurl, name);
- if (hook_map_.count(key) == 0)
- hook_map_[key] = std::make_unique<CookieChangeCallbackList>();
+ std::unique_ptr<Subscription> subscription = std::make_unique<Subscription>(
+ weak_ptr_factory_.GetWeakPtr(), DomainKey(url), NameKey(name), url,
+ std::move(callback));
- auto subscription =
- std::make_unique<CookieMonsterChangeSubscription>(std::move(callback));
- subscription->SetCallbackSubscription(hook_map_[key]->Add(
- base::BindRepeating(&RunAsync, base::ThreadTaskRunnerHandle::Get(),
- subscription->WeakCallback())));
+ LinkSubscription(subscription.get());
+ return subscription;
+}
- return std::move(subscription);
+std::unique_ptr<CookieChangeSubscription>
+CookieMonsterChangeDispatcher::AddCallbackForUrl(
+ const GURL& url,
+ CookieChangeCallback callback) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ std::unique_ptr<Subscription> subscription = std::make_unique<Subscription>(
+ weak_ptr_factory_.GetWeakPtr(), DomainKey(url),
+ std::string(kGlobalNameKey), url, std::move(callback));
+
+ LinkSubscription(subscription.get());
+ return subscription;
}
std::unique_ptr<CookieChangeSubscription>
@@ -103,12 +143,12 @@ CookieMonsterChangeDispatcher::AddCallbackForAllChanges(
CookieChangeCallback callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- auto subscription =
- std::make_unique<CookieMonsterChangeSubscription>(std::move(callback));
- subscription->SetCallbackSubscription(global_hook_map_.Add(
- base::BindRepeating(&RunAsync, base::ThreadTaskRunnerHandle::Get(),
- subscription->WeakCallback())));
- return std::move(subscription);
+ std::unique_ptr<Subscription> subscription = std::make_unique<Subscription>(
+ weak_ptr_factory_.GetWeakPtr(), std::string(kGlobalDomainKey),
+ std::string(kGlobalNameKey), GURL(""), std::move(callback));
+
+ LinkSubscription(subscription.get());
+ return subscription;
}
void CookieMonsterChangeDispatcher::DispatchChange(
@@ -117,24 +157,80 @@ void CookieMonsterChangeDispatcher::DispatchChange(
bool notify_global_hooks) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- CookieOptions opts;
- opts.set_include_httponly();
- opts.set_same_site_cookie_mode(
- CookieOptions::SameSiteCookieMode::INCLUDE_STRICT_AND_LAX);
- // Note that the callbacks in hook_map_ are wrapped with RunAsync(), so they
- // are guaranteed to not take long - they just post a RunAsync task back to
- // the appropriate thread's message loop and return.
- // TODO(mmenke): Consider running these synchronously?
- for (const auto& key_value_pair : hook_map_) {
- const std::pair<GURL, std::string>& key = key_value_pair.first;
- if (cookie.IncludeForRequestURL(key.first, opts) &&
- cookie.Name() == key.second) {
- key_value_pair.second->Notify(cookie, cause);
- }
+ DispatchChangeToDomainKey(cookie, cause, DomainKey(cookie.Domain()));
+ if (notify_global_hooks)
+ DispatchChangeToDomainKey(cookie, cause, std::string(kGlobalDomainKey));
+}
+
+void CookieMonsterChangeDispatcher::DispatchChangeToDomainKey(
+ const CanonicalCookie& cookie,
+ CookieChangeCause cause,
+ const std::string& domain_key) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ CookieDomainMap::iterator it = cookie_domain_map_.find(domain_key);
+ if (it == cookie_domain_map_.end())
+ return;
+
+ DispatchChangeToNameKey(cookie, cause, it->second, NameKey(cookie.Name()));
+ DispatchChangeToNameKey(cookie, cause, it->second,
+ std::string(kGlobalNameKey));
+}
+
+void CookieMonsterChangeDispatcher::DispatchChangeToNameKey(
+ const CanonicalCookie& cookie,
+ CookieChangeCause cause,
+ CookieNameMap& cookie_name_map,
+ const std::string& name_key) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ CookieNameMap::iterator it = cookie_name_map.find(name_key);
+ if (it == cookie_name_map.end())
+ return;
+
+ SubscriptionList& subscription_list = it->second;
+ for (base::LinkNode<Subscription>* node = subscription_list.head();
+ node != subscription_list.end(); node = node->next()) {
+ node->value()->DispatchChange(cookie, cause);
}
+}
- if (notify_global_hooks)
- global_hook_map_.Notify(cookie, cause);
+void CookieMonsterChangeDispatcher::LinkSubscription(
+ Subscription* subscription) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ // The subscript operator creates empty maps if the lookups fail. This is
+ // exactly what this method needs.
+ CookieNameMap& cookie_name_map =
+ cookie_domain_map_[subscription->domain_key()];
+ SubscriptionList& subscription_list =
+ cookie_name_map[subscription->name_key()];
+ subscription_list.Append(subscription);
+}
+
+void CookieMonsterChangeDispatcher::UnlinkSubscription(
+ Subscription* subscription) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ CookieDomainMap::iterator cookie_domain_map_iterator =
+ cookie_domain_map_.find(subscription->domain_key());
+ DCHECK(cookie_domain_map_iterator != cookie_domain_map_.end());
+
+ CookieNameMap& cookie_name_map = cookie_domain_map_iterator->second;
+ CookieNameMap::iterator cookie_name_map_iterator =
+ cookie_name_map.find(subscription->name_key());
+ DCHECK(cookie_name_map_iterator != cookie_name_map.end());
+
+ SubscriptionList& subscription_list = cookie_name_map_iterator->second;
+ subscription->RemoveFromList();
+ if (!subscription_list.empty())
+ return;
+
+ cookie_name_map.erase(cookie_name_map_iterator);
+ if (!cookie_name_map.empty())
+ return;
+
+ cookie_domain_map_.erase(cookie_domain_map_iterator);
}
} // namespace net
diff --git a/chromium/net/cookies/cookie_monster_change_dispatcher.h b/chromium/net/cookies/cookie_monster_change_dispatcher.h
index 74abe23e408..caf35e8d91e 100644
--- a/chromium/net/cookies/cookie_monster_change_dispatcher.h
+++ b/chromium/net/cookies/cookie_monster_change_dispatcher.h
@@ -12,6 +12,10 @@
#include "base/callback.h"
#include "base/callback_list.h"
#include "base/compiler_specific.h"
+#include "base/containers/linked_list.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "net/cookies/cookie_change_dispatcher.h"
#include "url/gurl.h"
@@ -30,32 +34,123 @@ class CookieMonsterChangeDispatcher : public CookieChangeDispatcher {
CookieMonsterChangeDispatcher();
~CookieMonsterChangeDispatcher() override;
+ // The key in CookieNameMap for a cookie name.
+ static std::string NameKey(std::string name);
+
+ // The key in CookieDomainName for a cookie domain.
+ static std::string DomainKey(const std::string& domain);
+
+ // The key in CookieDomainName for a listener URL.
+ static std::string DomainKey(const GURL& url);
+
// net::CookieChangeDispatcher
std::unique_ptr<CookieChangeSubscription> AddCallbackForCookie(
const GURL& url,
const std::string& name,
CookieChangeCallback callback) override WARN_UNUSED_RESULT;
+ std::unique_ptr<CookieChangeSubscription> AddCallbackForUrl(
+ const GURL& url,
+ CookieChangeCallback callback) override WARN_UNUSED_RESULT;
std::unique_ptr<CookieChangeSubscription> AddCallbackForAllChanges(
CookieChangeCallback callback) override WARN_UNUSED_RESULT;
- // Dispatch a cookie change to all interested listeners.
- //
// |notify_global_hooks| is true if the function should run the
// global hooks in addition to the per-cookie hooks.
- // TODO(pwnall): Remove |notify_global_hooks|.
+ //
+ // TODO(pwnall): Remove |notify_global_hooks| and fix consumers.
void DispatchChange(const CanonicalCookie& cookie,
CookieChangeCause cause,
bool notify_global_hooks);
private:
- using CookieChangeHookMap =
- std::map<std::pair<GURL, std::string>,
- std::unique_ptr<CookieChangeCallbackList>>;
- CookieChangeHookMap hook_map_;
- CookieChangeCallbackList global_hook_map_;
+ class Subscription : public base::LinkNode<Subscription>,
+ public CookieChangeSubscription {
+ public:
+ Subscription(base::WeakPtr<CookieMonsterChangeDispatcher> change_dispatcher,
+ std::string domain_key,
+ std::string name_key,
+ GURL url,
+ net::CookieChangeCallback callback);
+
+ ~Subscription() override;
+
+ // The lookup key used in the domain subscription map.
+ //
+ // The empty string means no domain filtering.
+ const std::string& domain_key() const { return domain_key_; }
+ // The lookup key used in the name subscription map.
+ //
+ // The empty string means no name filtering.
+ const std::string& name_key() const { return name_key_; }
+
+ // Dispatches a cookie change notification if the listener is interested.
+ void DispatchChange(const net::CanonicalCookie& cookie,
+ net::CookieChangeCause change_cause);
+
+ private:
+ base::WeakPtr<CookieMonsterChangeDispatcher> change_dispatcher_;
+ const std::string domain_key_; // kGlobalDomainKey means no filtering.
+ const std::string name_key_; // kGlobalNameKey means no filtering.
+ const GURL url_; // empty() means no URL-based filtering.
+ net::CookieOptions options_;
+ const net::CookieChangeCallback callback_;
+
+ void DoDispatchChange(const net::CanonicalCookie& cookie,
+ net::CookieChangeCause change_cause) const;
+
+ // Used to post DoDispatchChange() calls to this subscription's thread.
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
+ THREAD_CHECKER(thread_checker_);
+
+ // Used to cancel delayed calls to DoDispatchChange() when the subscription
+ // gets destroyed.
+ base::WeakPtrFactory<Subscription> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(Subscription);
+ };
+
+ // The last level of the subscription data structures.
+ using SubscriptionList = base::LinkedList<Subscription>;
+
+ // Buckets subscriptions according to cookie names.
+ //
+ // Map keys are cookie names, as we only support exact name matching.
+ using CookieNameMap = std::map<std::string, SubscriptionList>;
+
+ // Buckets subscriptions according to cookie domains.
+ //
+ // Map keys are the eTLD+1 of cookie domains. Cookies are either host-locked,
+ // or visible to all the subdomain of a given domain. A cookie's scope cannot
+ // exceed eTLD+1, so we stop there.
+ using CookieDomainMap = std::map<std::string, CookieNameMap>;
+
+ void DispatchChangeToDomainKey(const CanonicalCookie& cookie,
+ CookieChangeCause cause,
+ const std::string& domain_key);
+
+ void DispatchChangeToNameKey(const CanonicalCookie& cookie,
+ CookieChangeCause cause,
+ CookieNameMap& name_map,
+ const std::string& name_key);
+
+ // Inserts a subscription into the map.
+ //
+ // Called by the AddCallback* methods, after creating the Subscription.
+ void LinkSubscription(Subscription* subscription);
+
+ // Removes a subscription from the map.
+ //
+ // Called by the Subscription destructor.
+ void UnlinkSubscription(Subscription* subscription);
+
+ CookieDomainMap cookie_domain_map_;
THREAD_CHECKER(thread_checker_);
+ // Vends weak pointers to subscriptions.
+ base::WeakPtrFactory<CookieMonsterChangeDispatcher> weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(CookieMonsterChangeDispatcher);
};
diff --git a/chromium/net/cookies/cookie_monster_store_test.h b/chromium/net/cookies/cookie_monster_store_test.h
index 6d8a8335a4b..05bdb93dcc6 100644
--- a/chromium/net/cookies/cookie_monster_store_test.h
+++ b/chromium/net/cookies/cookie_monster_store_test.h
@@ -137,6 +137,7 @@ void AddCookieToList(const GURL& url,
// Just act like a backing database. Keep cookie information from
// Add/Update/Delete and regurgitate it when Load is called.
+// TODO(morlovich): This still assumes that creation times are unique.
class MockSimplePersistentCookieStore
: public CookieMonster::PersistentCookieStore {
public:
diff --git a/chromium/net/cookies/cookie_monster_unittest.cc b/chromium/net/cookies/cookie_monster_unittest.cc
index dbd8f8c1d57..84a386da82e 100644
--- a/chromium/net/cookies/cookie_monster_unittest.cc
+++ b/chromium/net/cookies/cookie_monster_unittest.cc
@@ -11,6 +11,7 @@
#include <vector>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/containers/queue.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
@@ -18,6 +19,7 @@
#include "base/metrics/histogram_samples.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
@@ -34,6 +36,7 @@
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_monster_store_test.h" // For CookieStore mock
#include "net/cookies/cookie_store_change_unittest.h"
+#include "net/cookies/cookie_store_test_helpers.h"
#include "net/cookies/cookie_store_unittest.h"
#include "net/cookies/cookie_util.h"
#include "net/cookies/parsed_cookie.h"
@@ -110,7 +113,7 @@ struct CookieMonsterTestTraits {
return std::make_unique<CookieMonster>(nullptr);
}
- static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
+ static void DeliverChangeNotifications() { base::RunLoop().RunUntilIdle(); }
static const bool supports_http_only = true;
static const bool supports_non_dotted_domains = true;
@@ -119,8 +122,11 @@ struct CookieMonsterTestTraits {
static const bool has_path_prefix_bug = false;
static const bool forbids_setting_empty_name = false;
static const bool supports_global_cookie_tracking = true;
+ static const bool supports_url_cookie_tracking = true;
static const bool supports_named_cookie_tracking = true;
static const bool supports_multiple_tracking_callbacks = true;
+ static const bool has_exact_change_cause = true;
+ static const bool has_exact_change_ordering = true;
static const int creation_time_granularity_in_ms = 0;
};
@@ -128,7 +134,13 @@ INSTANTIATE_TYPED_TEST_CASE_P(CookieMonster,
CookieStoreTest,
CookieMonsterTestTraits);
INSTANTIATE_TYPED_TEST_CASE_P(CookieMonster,
- CookieStoreChangeTest,
+ CookieStoreChangeGlobalTest,
+ CookieMonsterTestTraits);
+INSTANTIATE_TYPED_TEST_CASE_P(CookieMonster,
+ CookieStoreChangeUrlTest,
+ CookieMonsterTestTraits);
+INSTANTIATE_TYPED_TEST_CASE_P(CookieMonster,
+ CookieStoreChangeNamedTest,
CookieMonsterTestTraits);
template <typename T>
@@ -1853,11 +1865,11 @@ TEST_F(CookieMonsterTest, DontImportDuplicateCookies) {
}
// Tests importing from a persistent cookie store that contains cookies
-// with duplicate creation times. This situation should be handled by
-// dropping the cookies before insertion/visibility to user.
+// with duplicate creation times. This is OK now, but it still interacts
+// with the de-duplication algorithm.
//
// This is a regression test for: http://crbug.com/43188.
-TEST_F(CookieMonsterTest, DontImportDuplicateCreationTimes) {
+TEST_F(CookieMonsterTest, ImportDuplicateCreationTimes) {
scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
Time now(Time::Now());
@@ -2063,6 +2075,41 @@ TEST_F(CookieMonsterTest, BackingStoreCommunication) {
}
}
+TEST_F(CookieMonsterTest, RestoreDifferentCookieSameCreationTime) {
+ // Test that we can restore different cookies with duplicate creation times.
+ base::Time current(base::Time::Now());
+ scoped_refptr<MockPersistentCookieStore> store =
+ base::MakeRefCounted<MockPersistentCookieStore>();
+
+ {
+ CookieMonster cmout(store.get());
+ GURL url("http://www.example.com/");
+ EXPECT_TRUE(
+ SetCookieWithCreationTime(&cmout, url, "A=1; max-age=600", current));
+ EXPECT_TRUE(
+ SetCookieWithCreationTime(&cmout, url, "B=2; max-age=600", current));
+ }
+
+ // Play back the cookies into store 2.
+ scoped_refptr<MockPersistentCookieStore> store2 =
+ base::MakeRefCounted<MockPersistentCookieStore>();
+ std::vector<std::unique_ptr<CanonicalCookie>> load_expectation;
+ EXPECT_EQ(2u, store->commands().size());
+ for (const CookieStoreCommand& command : store->commands()) {
+ ASSERT_EQ(command.type, CookieStoreCommand::ADD);
+ load_expectation.push_back(
+ std::make_unique<CanonicalCookie>(command.cookie));
+ }
+ store2->SetLoadExpectation(true, std::move(load_expectation));
+
+ // Now read them in. Should get two cookies, not one.
+ {
+ CookieMonster cmin(store2.get());
+ CookieList cookies(GetAllCookies(&cmin));
+ ASSERT_EQ(2u, cookies.size());
+ }
+}
+
TEST_F(CookieMonsterTest, CookieListOrdering) {
// Put a random set of cookies into a monster and make sure
// they're returned in the right order.
@@ -2393,67 +2440,11 @@ TEST_F(CookieMonsterTest, CheckOrderOfCookieTaskQueueWhenLoadingCompletes) {
EXPECT_EQ(1u, get_cookie_list_callback2.cookies().size());
}
-namespace {
-
-// Mock PersistentCookieStore that keeps track of the number of Flush() calls.
-class FlushablePersistentStore : public CookieMonster::PersistentCookieStore {
- public:
- FlushablePersistentStore() : flush_count_(0) {}
-
- void Load(const LoadedCallback& loaded_callback) override {
- std::vector<std::unique_ptr<CanonicalCookie>> out_cookies;
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(loaded_callback, base::Passed(&out_cookies)));
- }
-
- void LoadCookiesForKey(const std::string& key,
- const LoadedCallback& loaded_callback) override {
- Load(loaded_callback);
- }
-
- void AddCookie(const CanonicalCookie&) override {}
- void UpdateCookieAccessTime(const CanonicalCookie&) override {}
- void DeleteCookie(const CanonicalCookie&) override {}
- void SetForceKeepSessionState() override {}
- void SetBeforeFlushCallback(base::RepeatingClosure callback) override {}
-
- void Flush(base::OnceClosure callback) override {
- ++flush_count_;
- if (!callback.is_null())
- std::move(callback).Run();
- }
-
- int flush_count() { return flush_count_; }
-
- private:
- ~FlushablePersistentStore() override = default;
-
- volatile int flush_count_;
-};
-
-// Counts the number of times Callback() has been run.
-class CallbackCounter : public base::RefCountedThreadSafe<CallbackCounter> {
- public:
- CallbackCounter() : callback_count_(0) {}
-
- void Callback() { ++callback_count_; }
-
- int callback_count() { return callback_count_; }
-
- private:
- friend class base::RefCountedThreadSafe<CallbackCounter>;
- ~CallbackCounter() = default;
-
- volatile int callback_count_;
-};
-
-} // namespace
-
// Test that FlushStore() is forwarded to the store and callbacks are posted.
TEST_F(CookieMonsterTest, FlushStore) {
- scoped_refptr<CallbackCounter> counter(new CallbackCounter());
- scoped_refptr<FlushablePersistentStore> store(new FlushablePersistentStore());
- std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get()));
+ auto counter = base::MakeRefCounted<CallbackCounter>();
+ auto store = base::MakeRefCounted<FlushablePersistentStore>();
+ auto cm = std::make_unique<CookieMonster>(store);
ASSERT_EQ(0, store->flush_count());
ASSERT_EQ(0, counter->callback_count());
@@ -2481,7 +2472,7 @@ TEST_F(CookieMonsterTest, FlushStore) {
ASSERT_EQ(2, counter->callback_count());
// NULL callback is still safe.
- cm->FlushStore(base::Closure());
+ cm->FlushStore(base::DoNothing());
base::RunLoop().RunUntilIdle();
ASSERT_EQ(2, store->flush_count());
@@ -2490,7 +2481,7 @@ TEST_F(CookieMonsterTest, FlushStore) {
// If there's no backing store, FlushStore() is always a safe no-op.
cm.reset(new CookieMonster(nullptr));
GetAllCookies(cm.get()); // Force init.
- cm->FlushStore(base::Closure());
+ cm->FlushStore(base::DoNothing());
base::RunLoop().RunUntilIdle();
ASSERT_EQ(2, counter->callback_count());
@@ -3152,6 +3143,47 @@ TEST_F(CookieMonsterTest, SetCanonicalCookieDoesNotBlockForLoadAll) {
}
}
+TEST_F(CookieMonsterTest, DeleteDuplicateCTime) {
+ const char* const kNames[] = {"A", "B", "C"};
+ const size_t kNum = arraysize(kNames);
+
+ // Tests that DeleteCanonicalCookie properly distinguishes different cookies
+ // (e.g. different name or path) with identical ctime on same domain.
+ // This gets tested a few times with different deletion target, to make sure
+ // that the implementation doesn't just happen to pick the right one because
+ // of implementation details.
+ for (size_t run = 0; run < kNum; ++run) {
+ CookieMonster cm(nullptr);
+ Time now = Time::Now();
+ GURL url("http://www.example.com");
+
+ for (size_t i = 0; i < kNum; ++i) {
+ std::string cookie_string =
+ base::StrCat({kNames[i], "=", base::NumberToString(i)});
+ EXPECT_TRUE(SetCookieWithCreationTime(&cm, url, cookie_string, now));
+ }
+
+ // Delete the run'th cookie.
+ CookieList all_cookies =
+ GetAllCookiesForURLWithOptions(&cm, url, CookieOptions());
+ ASSERT_EQ(all_cookies.size(), kNum);
+ for (size_t i = 0; i < kNum; ++i) {
+ const CanonicalCookie& cookie = all_cookies[i];
+ if (cookie.Name() == kNames[run]) {
+ EXPECT_TRUE(DeleteCanonicalCookie(&cm, cookie));
+ }
+ }
+
+ // Check that the right cookie got removed.
+ all_cookies = GetAllCookiesForURLWithOptions(&cm, url, CookieOptions());
+ ASSERT_EQ(all_cookies.size(), kNum - 1);
+ for (size_t i = 0; i < kNum - 1; ++i) {
+ const CanonicalCookie& cookie = all_cookies[i];
+ EXPECT_NE(cookie.Name(), kNames[run]);
+ }
+ }
+}
+
class CookieMonsterNotificationTest : public CookieMonsterTest {
public:
CookieMonsterNotificationTest()
diff --git a/chromium/net/cookies/cookie_store.cc b/chromium/net/cookies/cookie_store.cc
index 6d273b94799..e536dbd276f 100644
--- a/chromium/net/cookies/cookie_store.cc
+++ b/chromium/net/cookies/cookie_store.cc
@@ -40,6 +40,10 @@ int CookieStore::GetChannelIDServiceID() {
return channel_id_service_id_;
}
+void CookieStore::DumpMemoryStats(
+ base::trace_event::ProcessMemoryDump* pmd,
+ const std::string& parent_absolute_name) const {}
+
CookieStore::CookieStore() : channel_id_service_id_(-1) {}
} // namespace net
diff --git a/chromium/net/cookies/cookie_store.h b/chromium/net/cookies/cookie_store.h
index cfe57f7f6b7..980da01ced5 100644
--- a/chromium/net/cookies/cookie_store.h
+++ b/chromium/net/cookies/cookie_store.h
@@ -21,6 +21,12 @@
class GURL;
+namespace base {
+namespace trace_event {
+class ProcessMemoryDump;
+}
+} // namespace base
+
namespace net {
class CookieChangeDispatcher;
@@ -146,6 +152,10 @@ class NET_EXPORT CookieStore {
void SetChannelIDServiceID(int id);
int GetChannelIDServiceID();
+ // Reports the estimate of dynamically allocated memory in bytes.
+ virtual void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
+ const std::string& parent_absolute_name) const;
+
protected:
CookieStore();
int channel_id_service_id_;
diff --git a/chromium/net/cookies/cookie_store_change_unittest.h b/chromium/net/cookies/cookie_store_change_unittest.h
index a613bb4c1b4..32df87dfa12 100644
--- a/chromium/net/cookies/cookie_store_change_unittest.h
+++ b/chromium/net/cookies/cookie_store_change_unittest.h
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "net/cookies/canonical_cookie.h"
+#include "net/cookies/cookie_change_dispatcher_test_helpers.h"
#include "net/cookies/cookie_store.h"
#include "net/cookies/cookie_store_unittest.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -14,24 +15,107 @@
namespace net {
-template <class CookieStoreTestTraits>
-class CookieStoreChangeTest : public CookieStoreTest<CookieStoreTestTraits> {};
-TYPED_TEST_CASE_P(CookieStoreChangeTest);
-
namespace {
using CookieChange = std::pair<CanonicalCookie, CookieChangeCause>;
-void OnCookieChange(std::vector<CookieChange>* changes,
- const CanonicalCookie& cookie,
- CookieChangeCause cause) {
- CookieChange notification(cookie, cause);
- changes->push_back(notification);
+// Used to sort CookieChanges when testing stores without exact change ordering.
+//
+// The ordering relation must match the order in which the tests below issue
+// cookie calls. Changes to this method should be tested by running the tests
+// below with CookieMonsterTestTraits::has_exact_change_ordering set to both
+// true and false.
+bool CookieChangeLessThan(const CookieChange& lhs, const CookieChange& rhs) {
+ if (lhs.first.Name() != rhs.first.Name())
+ return lhs.first.Name() < rhs.first.Name();
+
+ if (lhs.first.Value() != rhs.first.Value())
+ return lhs.first.Value() < rhs.first.Value();
+
+ if (lhs.first.Domain() != rhs.first.Domain())
+ return lhs.first.Domain() < rhs.first.Domain();
+
+ return lhs.second < rhs.second;
}
} // namespace
-TYPED_TEST_P(CookieStoreChangeTest, Global_NoCookie) {
+// Google Test supports at most 50 tests per typed case, so the tests here are
+// broken up into multiple cases.
+template <class CookieStoreTestTraits>
+class CookieStoreChangeTestBase
+ : public CookieStoreTest<CookieStoreTestTraits> {
+ protected:
+ using CookieStoreTest<CookieStoreTestTraits>::FindAndDeleteCookie;
+
+ // Drains all pending tasks on the run loop(s) involved in the test.
+ void DeliverChangeNotifications() {
+ CookieStoreTestTraits::DeliverChangeNotifications();
+ }
+
+ bool FindAndDeleteCookie(CookieStore* cs,
+ const std::string& domain,
+ const std::string& name,
+ const std::string& path) {
+ for (auto& cookie : this->GetAllCookies(cs)) {
+ if (cookie.Domain() == domain && cookie.Name() == name &&
+ cookie.Path() == path) {
+ return this->DeleteCanonicalCookie(cs, cookie);
+ }
+ }
+
+ return false;
+ }
+
+ // Could be static, but it's actually easier to have it be a member function.
+ ::testing::AssertionResult MatchesCause(CookieChangeCause expected_cause,
+ CookieChangeCause actual_cause) {
+ if (!CookieChangeCauseIsDeletion(expected_cause) ||
+ CookieStoreTestTraits::has_exact_change_cause) {
+ if (expected_cause == actual_cause)
+ return ::testing::AssertionSuccess();
+ return ::testing::AssertionFailure()
+ << "expected " << expected_cause << " got " << actual_cause;
+ }
+ if (CookieChangeCauseIsDeletion(actual_cause))
+ return ::testing::AssertionSuccess();
+ return ::testing::AssertionFailure()
+ << "expected a deletion cause, got " << actual_cause;
+ }
+
+ static void OnCookieChange(std::vector<CookieChange>* changes,
+ const CanonicalCookie& cookie,
+ CookieChangeCause cause) {
+ CookieChange notification(cookie, cause);
+
+ if (CookieStoreTestTraits::has_exact_change_ordering) {
+ changes->push_back(notification);
+ } else {
+ // Assumes the vector is sorted before the insertion. If true, the vector
+ // will remain sorted.
+ changes->insert(std::upper_bound(changes->begin(), changes->end(),
+ notification, CookieChangeLessThan),
+ notification);
+ }
+ }
+};
+
+template <class CookieStoreTestTraits>
+class CookieStoreChangeGlobalTest
+ : public CookieStoreChangeTestBase<CookieStoreTestTraits> {};
+TYPED_TEST_CASE_P(CookieStoreChangeGlobalTest);
+
+template <class CookieStoreTestTraits>
+class CookieStoreChangeUrlTest
+ : public CookieStoreChangeTestBase<CookieStoreTestTraits> {};
+TYPED_TEST_CASE_P(CookieStoreChangeUrlTest);
+
+template <class CookieStoreTestTraits>
+class CookieStoreChangeNamedTest
+ : public CookieStoreChangeTestBase<CookieStoreTestTraits> {};
+TYPED_TEST_CASE_P(CookieStoreChangeNamedTest);
+
+TYPED_TEST_P(CookieStoreChangeGlobalTest, NoCookie) {
if (!TypeParam::supports_global_cookie_tracking)
return;
@@ -39,27 +123,29 @@ TYPED_TEST_P(CookieStoreChangeTest, Global_NoCookie) {
std::vector<CookieChange> cookie_changes;
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
- &OnCookieChange, base::Unretained(&cookie_changes)));
- this->RunUntilIdle();
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
EXPECT_EQ(0u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Global_InitialCookie) {
+TYPED_TEST_P(CookieStoreChangeGlobalTest, InitialCookie) {
if (!TypeParam::supports_global_cookie_tracking)
return;
CookieStore* cs = this->GetCookieStore();
std::vector<CookieChange> cookie_changes;
- this->SetCookie(cs, this->http_www_foo_.url(), "abc=def");
- this->RunUntilIdle();
+ this->SetCookie(cs, this->http_www_foo_.url(), "A=B");
+ this->DeliverChangeNotifications();
std::unique_ptr<CookieChangeSubscription> subscription(
cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
- &OnCookieChange, base::Unretained(&cookie_changes))));
- this->RunUntilIdle();
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes))));
+ this->DeliverChangeNotifications();
EXPECT_EQ(0u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Global_Insert) {
+TYPED_TEST_P(CookieStoreChangeGlobalTest, InsertOne) {
if (!TypeParam::supports_global_cookie_tracking)
return;
@@ -67,75 +153,150 @@ TYPED_TEST_P(CookieStoreChangeTest, Global_Insert) {
std::vector<CookieChange> cookie_changes;
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
- &OnCookieChange, base::Unretained(&cookie_changes)));
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(0u, cookie_changes.size());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ this->DeliverChangeNotifications();
+
+ ASSERT_EQ(1u, cookie_changes.size());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[0].second));
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
+ EXPECT_EQ("A", cookie_changes[0].first.Name());
+ EXPECT_EQ("B", cookie_changes[0].first.Value());
+}
+
+TYPED_TEST_P(CookieStoreChangeGlobalTest, InsertMany) {
+ if (!TypeParam::supports_global_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F"));
EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "G=H"));
+ this->DeliverChangeNotifications();
+
+ // Check that the cookie changes are dispatched before calling GetCookies.
+ // This is not an ASSERT because the following expectations produce useful
+ // debugging information if they fail.
+ EXPECT_EQ(4u, cookie_changes.size());
EXPECT_EQ("A=B; C=D; E=F", this->GetCookies(cs, this->http_www_foo_.url()));
EXPECT_EQ("G=H", this->GetCookies(cs, this->http_bar_com_.url()));
- this->RunUntilIdle();
- ASSERT_EQ(4u, cookie_changes.size());
- EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[0].second);
+
+ ASSERT_LE(1u, cookie_changes.size());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[0].second));
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
EXPECT_EQ("A", cookie_changes[0].first.Name());
EXPECT_EQ("B", cookie_changes[0].first.Value());
+
+ ASSERT_LE(2u, cookie_changes.size());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
- EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[1].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[1].second));
EXPECT_EQ("C", cookie_changes[1].first.Name());
EXPECT_EQ("D", cookie_changes[1].first.Value());
+
+ ASSERT_LE(3u, cookie_changes.size());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[2].first.Domain());
- EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[2].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[2].second));
EXPECT_EQ("E", cookie_changes[2].first.Name());
EXPECT_EQ("F", cookie_changes[2].first.Value());
+
+ ASSERT_LE(4u, cookie_changes.size());
EXPECT_EQ(this->http_bar_com_.url().host(), cookie_changes[3].first.Domain());
- EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[3].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[3].second));
EXPECT_EQ("G", cookie_changes[3].first.Name());
EXPECT_EQ("H", cookie_changes[3].first.Value());
+
+ EXPECT_EQ(4u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Global_Delete) {
+TYPED_TEST_P(CookieStoreChangeGlobalTest, DeleteOne) {
if (!TypeParam::supports_global_cookie_tracking)
return;
CookieStore* cs = this->GetCookieStore();
std::vector<CookieChange> cookie_changes;
- EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
- EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
- EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F"));
- EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "G=H"));
-
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
- &OnCookieChange, base::Unretained(&cookie_changes)));
- this->RunUntilIdle();
- ASSERT_EQ(0u, cookie_changes.size());
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ this->DeliverChangeNotifications();
+ EXPECT_EQ(1u, cookie_changes.size());
+ cookie_changes.clear();
EXPECT_TRUE(
- this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "C"));
- EXPECT_EQ("A=B; E=F", this->GetCookies(cs, this->http_www_foo_.url()));
- EXPECT_EQ("G=H", this->GetCookies(cs, this->http_bar_com_.url()));
- this->RunUntilIdle();
+ this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "A"));
+ this->DeliverChangeNotifications();
+
ASSERT_EQ(1u, cookie_changes.size());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
- EXPECT_EQ(CookieChangeCause::EXPLICIT, cookie_changes[0].second);
- EXPECT_EQ("C", cookie_changes[0].first.Name());
- EXPECT_EQ("D", cookie_changes[0].first.Value());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
+ cookie_changes[0].second));
+ EXPECT_EQ("A", cookie_changes[0].first.Name());
+ EXPECT_EQ("B", cookie_changes[0].first.Value());
+}
+
+TYPED_TEST_P(CookieStoreChangeGlobalTest, DeleteTwo) {
+ if (!TypeParam::supports_global_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "G=H"));
+ this->DeliverChangeNotifications();
+ EXPECT_EQ(4u, cookie_changes.size());
cookie_changes.clear();
EXPECT_TRUE(
+ this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "C"));
+ EXPECT_TRUE(
this->FindAndDeleteCookie(cs, this->http_bar_com_.url().host(), "G"));
+ this->DeliverChangeNotifications();
+
+ // Check that the cookie changes are dispatched before calling GetCookies.
+ // This is not an ASSERT because the following expectations produce useful
+ // debugging information if they fail.
+ EXPECT_EQ(2u, cookie_changes.size());
EXPECT_EQ("A=B; E=F", this->GetCookies(cs, this->http_www_foo_.url()));
EXPECT_EQ("", this->GetCookies(cs, this->http_bar_com_.url()));
- this->RunUntilIdle();
- ASSERT_EQ(1u, cookie_changes.size());
- EXPECT_EQ(this->http_bar_com_.url().host(), cookie_changes[0].first.Domain());
- EXPECT_EQ(CookieChangeCause::EXPLICIT, cookie_changes[0].second);
- EXPECT_EQ("G", cookie_changes[0].first.Name());
- EXPECT_EQ("H", cookie_changes[0].first.Value());
+
+ ASSERT_LE(1u, cookie_changes.size());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
+ cookie_changes[0].second));
+ EXPECT_EQ("C", cookie_changes[0].first.Name());
+ EXPECT_EQ("D", cookie_changes[0].first.Value());
+
+ ASSERT_EQ(2u, cookie_changes.size());
+ EXPECT_EQ(this->http_bar_com_.url().host(), cookie_changes[1].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
+ cookie_changes[1].second));
+ EXPECT_EQ("G", cookie_changes[1].first.Name());
+ EXPECT_EQ("H", cookie_changes[1].first.Value());
}
-TYPED_TEST_P(CookieStoreChangeTest, Global_Overwrite) {
+TYPED_TEST_P(CookieStoreChangeGlobalTest, Overwrite) {
if (!TypeParam::supports_global_cookie_tracking)
return;
@@ -143,31 +304,39 @@ TYPED_TEST_P(CookieStoreChangeTest, Global_Overwrite) {
std::vector<CookieChange> cookie_changes;
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
- &OnCookieChange, base::Unretained(&cookie_changes)));
- this->RunUntilIdle();
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes.size());
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes.size());
cookie_changes.clear();
// Replacing an existing cookie is actually a two-phase delete + set
// operation, so we get an extra notification.
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=C"));
- this->RunUntilIdle();
- ASSERT_EQ(2u, cookie_changes.size());
+ this->DeliverChangeNotifications();
+
+ ASSERT_LE(1u, cookie_changes.size());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
- EXPECT_EQ(CookieChangeCause::OVERWRITE, cookie_changes[0].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
+ cookie_changes[0].second));
EXPECT_EQ("A", cookie_changes[0].first.Name());
EXPECT_EQ("B", cookie_changes[0].first.Value());
+
+ ASSERT_LE(2u, cookie_changes.size());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
- EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[1].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[1].second));
EXPECT_EQ("A", cookie_changes[1].first.Name());
EXPECT_EQ("C", cookie_changes[1].first.Value());
+
+ EXPECT_EQ(2u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Global_OverwriteWithHttpOnly) {
+TYPED_TEST_P(CookieStoreChangeGlobalTest, OverwriteWithHttpOnly) {
if (!TypeParam::supports_global_cookie_tracking)
return;
@@ -176,18 +345,21 @@ TYPED_TEST_P(CookieStoreChangeTest, Global_OverwriteWithHttpOnly) {
std::vector<CookieChange> cookie_changes;
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
- &OnCookieChange, base::Unretained(&cookie_changes)));
- this->RunUntilIdle();
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes.size());
EXPECT_TRUE(
this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/path1"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes.size());
- EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[0].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[0].second));
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
EXPECT_EQ("A", cookie_changes[0].first.Name());
EXPECT_EQ("B", cookie_changes[0].first.Value());
+ EXPECT_FALSE(cookie_changes[0].first.IsHttpOnly());
cookie_changes.clear();
// Insert a cookie "A" for path "/path1", that is httponly. This should
@@ -197,19 +369,28 @@ TYPED_TEST_P(CookieStoreChangeTest, Global_OverwriteWithHttpOnly) {
EXPECT_TRUE(this->SetCookieWithOptions(cs, this->http_www_foo_.url(),
"A=C; path=/path1; httponly",
allow_httponly));
- this->RunUntilIdle();
- ASSERT_EQ(2u, cookie_changes.size());
+ this->DeliverChangeNotifications();
+
+ ASSERT_LE(1u, cookie_changes.size());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
- EXPECT_EQ(CookieChangeCause::OVERWRITE, cookie_changes[0].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
+ cookie_changes[0].second));
EXPECT_EQ("A", cookie_changes[0].first.Name());
EXPECT_EQ("B", cookie_changes[0].first.Value());
+ EXPECT_FALSE(cookie_changes[0].first.IsHttpOnly());
+
+ ASSERT_LE(2u, cookie_changes.size());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
- EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[1].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[1].second));
EXPECT_EQ("A", cookie_changes[1].first.Name());
EXPECT_EQ("C", cookie_changes[1].first.Value());
+ EXPECT_TRUE(cookie_changes[1].first.IsHttpOnly());
+
+ EXPECT_EQ(2u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Global_Deregister) {
+TYPED_TEST_P(CookieStoreChangeGlobalTest, Deregister) {
if (!TypeParam::supports_global_cookie_tracking)
return;
@@ -218,13 +399,14 @@ TYPED_TEST_P(CookieStoreChangeTest, Global_Deregister) {
std::vector<CookieChange> cookie_changes;
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
- &OnCookieChange, base::Unretained(&cookie_changes)));
- this->RunUntilIdle();
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes.size());
// Insert a cookie and make sure it is seen.
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes.size());
EXPECT_EQ("A", cookie_changes[0].first.Name());
EXPECT_EQ("B", cookie_changes[0].first.Value());
@@ -235,12 +417,12 @@ TYPED_TEST_P(CookieStoreChangeTest, Global_Deregister) {
// Insert a second cookie and make sure that it's not visible.
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
EXPECT_EQ(0u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Global_DeregisterMultiple) {
+TYPED_TEST_P(CookieStoreChangeGlobalTest, DeregisterMultiple) {
if (!TypeParam::supports_global_cookie_tracking ||
!TypeParam::supports_multiple_tracking_callbacks)
return;
@@ -251,19 +433,21 @@ TYPED_TEST_P(CookieStoreChangeTest, Global_DeregisterMultiple) {
std::vector<CookieChange> cookie_changes_1;
std::unique_ptr<CookieChangeSubscription> subscription1 =
cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
- &OnCookieChange, base::Unretained(&cookie_changes_1)));
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
std::vector<CookieChange> cookie_changes_2;
std::unique_ptr<CookieChangeSubscription> subscription2 =
cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
- &OnCookieChange, base::Unretained(&cookie_changes_2)));
- this->RunUntilIdle();
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes_1.size());
ASSERT_EQ(0u, cookie_changes_2.size());
// Insert a cookie and make sure it's seen.
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ("A", cookie_changes_1[0].first.Name());
EXPECT_EQ("B", cookie_changes_1[0].first.Value());
@@ -280,7 +464,7 @@ TYPED_TEST_P(CookieStoreChangeTest, Global_DeregisterMultiple) {
// Insert a second cookie and make sure that it's only visible in one
// change array.
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ("C", cookie_changes_1[0].first.Name());
EXPECT_EQ("D", cookie_changes_1[0].first.Value());
@@ -289,10 +473,39 @@ TYPED_TEST_P(CookieStoreChangeTest, Global_DeregisterMultiple) {
ASSERT_EQ(0u, cookie_changes_2.size());
}
-// Confirm that deregistering a subscription blocks the notification
-// if the deregistration happened after the change but before the
-// notification was received.
-TYPED_TEST_P(CookieStoreChangeTest, Global_DeregisterRace) {
+// Confirm that a listener does not receive notifications for changes that
+// happened right before the subscription was established.
+TYPED_TEST_P(CookieStoreChangeGlobalTest, DispatchRace) {
+ if (!TypeParam::supports_global_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+
+ // This cookie insertion should not be seen.
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ // DeliverChangeNotifications() must NOT be called before the subscription is
+ // established.
+
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
+ this->DeliverChangeNotifications();
+
+ EXPECT_LE(1u, cookie_changes.size());
+ EXPECT_EQ("C", cookie_changes[0].first.Name());
+ EXPECT_EQ("D", cookie_changes[0].first.Value());
+
+ ASSERT_EQ(1u, cookie_changes.size());
+}
+
+// Confirm that deregistering a subscription blocks the notification if the
+// deregistration happened after the change but before the notification was
+// received.
+TYPED_TEST_P(CookieStoreChangeGlobalTest, DeregisterRace) {
if (!TypeParam::supports_global_cookie_tracking)
return;
@@ -301,13 +514,14 @@ TYPED_TEST_P(CookieStoreChangeTest, Global_DeregisterRace) {
std::vector<CookieChange> cookie_changes;
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
- &OnCookieChange, base::Unretained(&cookie_changes)));
- this->RunUntilIdle();
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes.size());
// Insert a cookie and make sure it's seen.
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes.size());
EXPECT_EQ("A", cookie_changes[0].first.Name());
EXPECT_EQ("B", cookie_changes[0].first.Value());
@@ -328,11 +542,11 @@ TYPED_TEST_P(CookieStoreChangeTest, Global_DeregisterRace) {
// valid. Destroy the subscription so as to lose the race and make sure the
// task posted arrives after the subscription was destroyed.
subscription.reset();
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Global_DeregisterRaceMultiple) {
+TYPED_TEST_P(CookieStoreChangeGlobalTest, DeregisterRaceMultiple) {
if (!TypeParam::supports_global_cookie_tracking ||
!TypeParam::supports_multiple_tracking_callbacks)
return;
@@ -343,17 +557,19 @@ TYPED_TEST_P(CookieStoreChangeTest, Global_DeregisterRaceMultiple) {
std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
std::unique_ptr<CookieChangeSubscription> subscription1 =
cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
- &OnCookieChange, base::Unretained(&cookie_changes_1)));
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
std::unique_ptr<CookieChangeSubscription> subscription2 =
cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
- &OnCookieChange, base::Unretained(&cookie_changes_2)));
- this->RunUntilIdle();
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes_1.size());
ASSERT_EQ(0u, cookie_changes_2.size());
// Insert a cookie and make sure it's seen.
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ("A", cookie_changes_1[0].first.Name());
@@ -372,17 +588,15 @@ TYPED_TEST_P(CookieStoreChangeTest, Global_DeregisterRaceMultiple) {
// Note that by the API contract it's perfectly valid to have received the
// notification immediately, i.e. synchronously with the cookie change. In
// that case, there's nothing to test.
- if (1u == cookie_changes_2.size()) {
- LOG(ERROR) << "Nothing to test.";
+ if (1u == cookie_changes_2.size())
return;
- }
// A task was posted by the SetCookie() above, but has not yet arrived. If it
// arrived before the subscription is destroyed, callback execution would be
// valid. Destroy one of the subscriptions so as to lose the race and make
// sure the task posted arrives after the subscription was destroyed.
subscription2.reset();
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ("C", cookie_changes_1[0].first.Name());
EXPECT_EQ("D", cookie_changes_1[0].first.Value());
@@ -391,7 +605,7 @@ TYPED_TEST_P(CookieStoreChangeTest, Global_DeregisterRaceMultiple) {
ASSERT_EQ(0u, cookie_changes_2.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Global_MultipleSubscriptions) {
+TYPED_TEST_P(CookieStoreChangeGlobalTest, MultipleSubscriptions) {
if (!TypeParam::supports_global_cookie_tracking ||
!TypeParam::supports_multiple_tracking_callbacks)
return;
@@ -401,25 +615,988 @@ TYPED_TEST_P(CookieStoreChangeTest, Global_MultipleSubscriptions) {
std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
std::unique_ptr<CookieChangeSubscription> subscription1 =
cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
- &OnCookieChange, base::Unretained(&cookie_changes_1)));
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
std::unique_ptr<CookieChangeSubscription> subscription2 =
cs->GetChangeDispatcher().AddCallbackForAllChanges(base::BindRepeating(
- &OnCookieChange, base::Unretained(&cookie_changes_2)));
- this->RunUntilIdle();
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ this->DeliverChangeNotifications();
- EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
- this->RunUntilIdle();
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ this->DeliverChangeNotifications();
ASSERT_EQ(1U, cookie_changes_1.size());
- EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
- EXPECT_EQ("def", cookie_changes_1[0].first.Value());
+ EXPECT_EQ("A", cookie_changes_1[0].first.Name());
+ EXPECT_EQ("B", cookie_changes_1[0].first.Value());
ASSERT_EQ(1U, cookie_changes_2.size());
- EXPECT_EQ("abc", cookie_changes_2[0].first.Name());
- EXPECT_EQ("def", cookie_changes_2[0].first.Value());
+ EXPECT_EQ("A", cookie_changes_2[0].first.Name());
+ EXPECT_EQ("B", cookie_changes_2[0].first.Value());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_NoCookie) {
+TYPED_TEST_P(CookieStoreChangeUrlTest, NoCookie) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
+ EXPECT_EQ(0u, cookie_changes.size());
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, InitialCookie) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+ std::vector<CookieChange> cookie_changes;
+ this->SetCookie(cs, this->http_www_foo_.url(), "A=B");
+ this->DeliverChangeNotifications();
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
+ EXPECT_EQ(0u, cookie_changes.size());
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, InsertOne) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(0u, cookie_changes.size());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(1u, cookie_changes.size());
+
+ EXPECT_EQ("A", cookie_changes[0].first.Name());
+ EXPECT_EQ("B", cookie_changes[0].first.Value());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[0].second));
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, InsertMany) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F"));
+ this->DeliverChangeNotifications();
+
+ ASSERT_LE(1u, cookie_changes.size());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[0].second));
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
+ EXPECT_EQ("A", cookie_changes[0].first.Name());
+ EXPECT_EQ("B", cookie_changes[0].first.Value());
+
+ ASSERT_LE(2u, cookie_changes.size());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[1].second));
+ EXPECT_EQ("C", cookie_changes[1].first.Name());
+ EXPECT_EQ("D", cookie_changes[1].first.Value());
+
+ ASSERT_LE(3u, cookie_changes.size());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[2].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[2].second));
+ EXPECT_EQ("E", cookie_changes[2].first.Name());
+ EXPECT_EQ("F", cookie_changes[2].first.Value());
+
+ EXPECT_EQ(3u, cookie_changes.size());
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, InsertFiltering) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->www_foo_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(0u, cookie_changes.size());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D; path=/"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F; path=/bar"));
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "G=H; path=/foo/bar"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "I=J; path=/foo"));
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "K=L; domain=foo.com"));
+ this->DeliverChangeNotifications();
+
+ ASSERT_LE(1u, cookie_changes.size());
+ EXPECT_EQ("A", cookie_changes[0].first.Name());
+ EXPECT_EQ("B", cookie_changes[0].first.Value());
+ EXPECT_EQ("/", cookie_changes[0].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[0].second));
+
+ ASSERT_LE(2u, cookie_changes.size());
+ EXPECT_EQ("I", cookie_changes[1].first.Name());
+ EXPECT_EQ("J", cookie_changes[1].first.Value());
+ EXPECT_EQ("/foo", cookie_changes[1].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[1].second));
+
+ ASSERT_LE(3u, cookie_changes.size());
+ EXPECT_EQ("K", cookie_changes[2].first.Name());
+ EXPECT_EQ("L", cookie_changes[2].first.Value());
+ EXPECT_EQ("/", cookie_changes[2].first.Path());
+ EXPECT_EQ(".foo.com", cookie_changes[2].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[2].second));
+
+ EXPECT_EQ(3u, cookie_changes.size());
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, DeleteOne) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ this->DeliverChangeNotifications();
+ EXPECT_EQ(1u, cookie_changes.size());
+ cookie_changes.clear();
+
+ EXPECT_TRUE(
+ this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "A"));
+ this->DeliverChangeNotifications();
+
+ ASSERT_EQ(1u, cookie_changes.size());
+ EXPECT_EQ("A", cookie_changes[0].first.Name());
+ EXPECT_EQ("B", cookie_changes[0].first.Value());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
+ ASSERT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
+ cookie_changes[0].second));
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, DeleteTwo) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "G=H"));
+ this->DeliverChangeNotifications();
+ EXPECT_EQ(4u, cookie_changes.size());
+ cookie_changes.clear();
+
+ EXPECT_TRUE(
+ this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "C"));
+ EXPECT_TRUE(
+ this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "G"));
+ this->DeliverChangeNotifications();
+
+ // Check that the cookie changes are dispatched before calling GetCookies.
+ // This is not an ASSERT because the following expectations produce useful
+ // debugging information if they fail.
+ EXPECT_EQ(2u, cookie_changes.size());
+ EXPECT_EQ("A=B; E=F", this->GetCookies(cs, this->http_www_foo_.url()));
+
+ ASSERT_LE(1u, cookie_changes.size());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
+ cookie_changes[0].second));
+ EXPECT_EQ("C", cookie_changes[0].first.Name());
+ EXPECT_EQ("D", cookie_changes[0].first.Value());
+
+ ASSERT_EQ(2u, cookie_changes.size());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
+ cookie_changes[1].second));
+ EXPECT_EQ("G", cookie_changes[1].first.Name());
+ EXPECT_EQ("H", cookie_changes[1].first.Value());
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, DeleteFiltering) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->www_foo_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D; path=/"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F; path=/bar"));
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "G=H; path=/foo/bar"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "I=J; path=/foo"));
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "K=L; domain=foo.com"));
+ this->DeliverChangeNotifications();
+ EXPECT_EQ(3u, cookie_changes.size());
+ cookie_changes.clear();
+
+ EXPECT_TRUE(
+ this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "A"));
+ EXPECT_TRUE(
+ this->FindAndDeleteCookie(cs, this->http_bar_com_.url().host(), "C"));
+ EXPECT_TRUE(
+ this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "E"));
+ EXPECT_TRUE(
+ this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "G"));
+ EXPECT_TRUE(
+ this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "I"));
+ EXPECT_TRUE(this->FindAndDeleteCookie(cs, ".foo.com", "K"));
+ this->DeliverChangeNotifications();
+
+ ASSERT_LE(1u, cookie_changes.size());
+ EXPECT_EQ("A", cookie_changes[0].first.Name());
+ EXPECT_EQ("B", cookie_changes[0].first.Value());
+ EXPECT_EQ("/", cookie_changes[0].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
+ cookie_changes[0].second));
+
+ ASSERT_LE(2u, cookie_changes.size());
+ EXPECT_EQ("I", cookie_changes[1].first.Name());
+ EXPECT_EQ("J", cookie_changes[1].first.Value());
+ EXPECT_EQ("/foo", cookie_changes[1].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
+ cookie_changes[1].second));
+
+ ASSERT_LE(3u, cookie_changes.size());
+ EXPECT_EQ("K", cookie_changes[2].first.Name());
+ EXPECT_EQ("L", cookie_changes[2].first.Value());
+ EXPECT_EQ("/", cookie_changes[2].first.Path());
+ EXPECT_EQ(".foo.com", cookie_changes[2].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
+ cookie_changes[2].second));
+
+ EXPECT_EQ(3u, cookie_changes.size());
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, Overwrite) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(0u, cookie_changes.size());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(1u, cookie_changes.size());
+ cookie_changes.clear();
+
+ // Replacing an existing cookie is actually a two-phase delete + set
+ // operation, so we get an extra notification.
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=C"));
+ this->DeliverChangeNotifications();
+
+ ASSERT_LE(1u, cookie_changes.size());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
+ cookie_changes[0].second));
+ EXPECT_EQ("A", cookie_changes[0].first.Name());
+ EXPECT_EQ("B", cookie_changes[0].first.Value());
+
+ ASSERT_LE(2u, cookie_changes.size());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[1].second));
+ EXPECT_EQ("A", cookie_changes[1].first.Name());
+ EXPECT_EQ("C", cookie_changes[1].first.Value());
+
+ EXPECT_EQ(2u, cookie_changes.size());
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, OverwriteFiltering) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->www_foo_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(0u, cookie_changes.size());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D; path=/"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F; path=/bar"));
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "G=H; path=/foo/bar"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "I=J; path=/foo"));
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "K=L; domain=foo.com"));
+ this->DeliverChangeNotifications();
+ EXPECT_EQ(3u, cookie_changes.size());
+ cookie_changes.clear();
+
+ // Replacing an existing cookie is actually a two-phase delete + set
+ // operation, so we get two notifications per overwrite.
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=b; path=/"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=d; path=/"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=f; path=/bar"));
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "G=h; path=/foo/bar"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "I=j; path=/foo"));
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "K=l; domain=foo.com"));
+ this->DeliverChangeNotifications();
+
+ ASSERT_LE(1u, cookie_changes.size());
+ EXPECT_EQ("A", cookie_changes[0].first.Name());
+ EXPECT_EQ("B", cookie_changes[0].first.Value());
+ EXPECT_EQ("/", cookie_changes[0].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
+ cookie_changes[0].second));
+
+ ASSERT_LE(2u, cookie_changes.size());
+ EXPECT_EQ("A", cookie_changes[1].first.Name());
+ EXPECT_EQ("b", cookie_changes[1].first.Value());
+ EXPECT_EQ("/", cookie_changes[1].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
+ EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[1].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[1].second));
+
+ ASSERT_LE(3u, cookie_changes.size());
+ EXPECT_EQ("I", cookie_changes[2].first.Name());
+ EXPECT_EQ("J", cookie_changes[2].first.Value());
+ EXPECT_EQ("/foo", cookie_changes[2].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[2].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
+ cookie_changes[2].second));
+
+ ASSERT_LE(4u, cookie_changes.size());
+ EXPECT_EQ("I", cookie_changes[3].first.Name());
+ EXPECT_EQ("j", cookie_changes[3].first.Value());
+ EXPECT_EQ("/foo", cookie_changes[3].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[3].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[3].second));
+
+ ASSERT_LE(5u, cookie_changes.size());
+ EXPECT_EQ("K", cookie_changes[4].first.Name());
+ EXPECT_EQ("L", cookie_changes[4].first.Value());
+ EXPECT_EQ("/", cookie_changes[4].first.Path());
+ EXPECT_EQ(".foo.com", cookie_changes[4].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
+ cookie_changes[4].second));
+
+ ASSERT_LE(6u, cookie_changes.size());
+ EXPECT_EQ("K", cookie_changes[5].first.Name());
+ EXPECT_EQ("l", cookie_changes[5].first.Value());
+ EXPECT_EQ("/", cookie_changes[5].first.Path());
+ EXPECT_EQ(".foo.com", cookie_changes[5].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[5].second));
+
+ EXPECT_EQ(6u, cookie_changes.size());
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, OverwriteWithHttpOnly) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ // Insert a cookie "A" for path "/foo".
+ CookieStore* cs = this->GetCookieStore();
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->www_foo_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(0u, cookie_changes.size());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B; path=/foo"));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(1u, cookie_changes.size());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[0].second));
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
+ EXPECT_EQ("A", cookie_changes[0].first.Name());
+ EXPECT_EQ("B", cookie_changes[0].first.Value());
+ EXPECT_FALSE(cookie_changes[0].first.IsHttpOnly());
+ cookie_changes.clear();
+
+ // Insert a cookie "A" for path "/foo", that is httponly. This should
+ // overwrite the non-http-only version.
+ CookieOptions allow_httponly;
+ allow_httponly.set_include_httponly();
+ EXPECT_TRUE(this->SetCookieWithOptions(cs, this->http_www_foo_.url(),
+ "A=C; path=/foo; httponly",
+ allow_httponly));
+ this->DeliverChangeNotifications();
+
+ ASSERT_LE(1u, cookie_changes.size());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
+ cookie_changes[0].second));
+ EXPECT_EQ("A", cookie_changes[0].first.Name());
+ EXPECT_EQ("B", cookie_changes[0].first.Value());
+ EXPECT_FALSE(cookie_changes[0].first.IsHttpOnly());
+
+ ASSERT_LE(2u, cookie_changes.size());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[1].second));
+ EXPECT_EQ("A", cookie_changes[1].first.Name());
+ EXPECT_EQ("C", cookie_changes[1].first.Value());
+ EXPECT_TRUE(cookie_changes[1].first.IsHttpOnly());
+
+ EXPECT_EQ(2u, cookie_changes.size());
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, Deregister) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(0u, cookie_changes.size());
+
+ // Insert a cookie and make sure it is seen.
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(1u, cookie_changes.size());
+ EXPECT_EQ("A", cookie_changes[0].first.Name());
+ EXPECT_EQ("B", cookie_changes[0].first.Value());
+ cookie_changes.clear();
+
+ // De-register the subscription.
+ subscription.reset();
+
+ // Insert a second cookie and make sure it's not visible.
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
+ this->DeliverChangeNotifications();
+
+ EXPECT_EQ(0u, cookie_changes.size());
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, DeregisterMultiple) {
+ if (!TypeParam::supports_url_cookie_tracking ||
+ !TypeParam::supports_multiple_tracking_callbacks)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+
+ // Register two subscriptions.
+ std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
+ std::unique_ptr<CookieChangeSubscription> subscription1 =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
+ std::unique_ptr<CookieChangeSubscription> subscription2 =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(0u, cookie_changes_1.size());
+ ASSERT_EQ(0u, cookie_changes_2.size());
+
+ // Insert a cookie and make sure it's seen.
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(1u, cookie_changes_1.size());
+ EXPECT_EQ("A", cookie_changes_1[0].first.Name());
+ EXPECT_EQ("B", cookie_changes_1[0].first.Value());
+ cookie_changes_1.clear();
+
+ ASSERT_EQ(1u, cookie_changes_2.size());
+ EXPECT_EQ("A", cookie_changes_2[0].first.Name());
+ EXPECT_EQ("B", cookie_changes_2[0].first.Value());
+ cookie_changes_2.clear();
+
+ // De-register the second registration.
+ subscription2.reset();
+
+ // Insert a second cookie and make sure that it's only visible in one
+ // change array.
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(1u, cookie_changes_1.size());
+ EXPECT_EQ("C", cookie_changes_1[0].first.Name());
+ EXPECT_EQ("D", cookie_changes_1[0].first.Value());
+
+ EXPECT_EQ(0u, cookie_changes_2.size());
+}
+
+// Confirm that a listener does not receive notifications for changes that
+// happened right before the subscription was established.
+TYPED_TEST_P(CookieStoreChangeUrlTest, DispatchRace) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+
+ // This cookie insertion should not be seen.
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ // DeliverChangeNotifications() must NOT be called before the subscription is
+ // established.
+
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
+ this->DeliverChangeNotifications();
+
+ EXPECT_LE(1u, cookie_changes.size());
+ EXPECT_EQ("C", cookie_changes[0].first.Name());
+ EXPECT_EQ("D", cookie_changes[0].first.Value());
+
+ ASSERT_EQ(1u, cookie_changes.size());
+}
+
+// Confirm that deregistering a subscription blocks the notification if the
+// deregistration happened after the change but before the notification was
+// received.
+TYPED_TEST_P(CookieStoreChangeUrlTest, DeregisterRace) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(0u, cookie_changes.size());
+
+ // Insert a cookie and make sure it's seen.
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(1u, cookie_changes.size());
+ EXPECT_EQ("A", cookie_changes[0].first.Name());
+ EXPECT_EQ("B", cookie_changes[0].first.Value());
+ cookie_changes.clear();
+
+ // Insert a cookie, confirm it is not seen, deregister the subscription, run
+ // until idle, and confirm the cookie is still not seen.
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
+
+ // Note that by the API contract it's perfectly valid to have received the
+ // notification immediately, i.e. synchronously with the cookie change. In
+ // that case, there's nothing to test.
+ if (1u == cookie_changes.size())
+ return;
+
+ // A task was posted by the SetCookie() above, but has not yet arrived. If it
+ // arrived before the subscription is destroyed, callback execution would be
+ // valid. Destroy the subscription so as to lose the race and make sure the
+ // task posted arrives after the subscription was destroyed.
+ subscription.reset();
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(0u, cookie_changes.size());
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, DeregisterRaceMultiple) {
+ if (!TypeParam::supports_url_cookie_tracking ||
+ !TypeParam::supports_multiple_tracking_callbacks)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+
+ // Register two subscriptions.
+ std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
+ std::unique_ptr<CookieChangeSubscription> subscription1 =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
+ std::unique_ptr<CookieChangeSubscription> subscription2 =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(0u, cookie_changes_1.size());
+ ASSERT_EQ(0u, cookie_changes_2.size());
+
+ // Insert a cookie and make sure it's seen.
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ this->DeliverChangeNotifications();
+
+ ASSERT_EQ(1u, cookie_changes_1.size());
+ EXPECT_EQ("A", cookie_changes_1[0].first.Name());
+ EXPECT_EQ("B", cookie_changes_1[0].first.Value());
+ cookie_changes_1.clear();
+
+ ASSERT_EQ(1u, cookie_changes_2.size());
+ EXPECT_EQ("A", cookie_changes_2[0].first.Name());
+ EXPECT_EQ("B", cookie_changes_2[0].first.Value());
+ cookie_changes_2.clear();
+
+ // Insert a cookie, confirm it is not seen, deregister a subscription, run
+ // until idle, and confirm the cookie is still not seen.
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D"));
+
+ // Note that by the API contract it's perfectly valid to have received the
+ // notification immediately, i.e. synchronously with the cookie change. In
+ // that case, there's nothing to test.
+ if (1u == cookie_changes_2.size())
+ return;
+
+ // A task was posted by the SetCookie() above, but has not yet arrived. If it
+ // arrived before the subscription is destroyed, callback execution would be
+ // valid. Destroy one of the subscriptions so as to lose the race and make
+ // sure the task posted arrives after the subscription was destroyed.
+ subscription2.reset();
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(1u, cookie_changes_1.size());
+ EXPECT_EQ("C", cookie_changes_1[0].first.Name());
+ EXPECT_EQ("D", cookie_changes_1[0].first.Value());
+
+ // No late notification was received.
+ ASSERT_EQ(0u, cookie_changes_2.size());
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, DifferentSubscriptionsDisjoint) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+
+ std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
+ std::unique_ptr<CookieChangeSubscription> subscription1 =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
+ std::unique_ptr<CookieChangeSubscription> subscription2 =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_bar_com_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(0u, cookie_changes_1.size());
+ ASSERT_EQ(0u, cookie_changes_2.size());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ this->DeliverChangeNotifications();
+ EXPECT_EQ(1u, cookie_changes_1.size());
+ EXPECT_EQ(0u, cookie_changes_2.size());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D"));
+ this->DeliverChangeNotifications();
+
+ ASSERT_EQ(1u, cookie_changes_1.size());
+ EXPECT_EQ("A", cookie_changes_1[0].first.Name());
+ EXPECT_EQ("B", cookie_changes_1[0].first.Value());
+ EXPECT_EQ(this->http_www_foo_.url().host(),
+ cookie_changes_1[0].first.Domain());
+
+ ASSERT_EQ(1u, cookie_changes_2.size());
+ EXPECT_EQ("C", cookie_changes_2[0].first.Name());
+ EXPECT_EQ("D", cookie_changes_2[0].first.Value());
+ EXPECT_EQ(this->http_bar_com_.url().host(),
+ cookie_changes_2[0].first.Domain());
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, DifferentSubscriptionsDomains) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+
+ std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
+ std::unique_ptr<CookieChangeSubscription> subscription1 =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
+ std::unique_ptr<CookieChangeSubscription> subscription2 =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_bar_com_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(0u, cookie_changes_1.size());
+ ASSERT_EQ(0u, cookie_changes_2.size());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ this->DeliverChangeNotifications();
+ EXPECT_EQ(1u, cookie_changes_1.size());
+ EXPECT_EQ(0u, cookie_changes_2.size());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D"));
+ this->DeliverChangeNotifications();
+
+ ASSERT_EQ(1u, cookie_changes_1.size());
+ EXPECT_EQ("A", cookie_changes_1[0].first.Name());
+ EXPECT_EQ("B", cookie_changes_1[0].first.Value());
+ EXPECT_EQ(this->http_www_foo_.url().host(),
+ cookie_changes_1[0].first.Domain());
+
+ ASSERT_EQ(1u, cookie_changes_2.size());
+ EXPECT_EQ("C", cookie_changes_2[0].first.Name());
+ EXPECT_EQ("D", cookie_changes_2[0].first.Value());
+ EXPECT_EQ(this->http_bar_com_.url().host(),
+ cookie_changes_2[0].first.Domain());
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, DifferentSubscriptionsPaths) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+
+ std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
+ std::unique_ptr<CookieChangeSubscription> subscription1 =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
+ std::unique_ptr<CookieChangeSubscription> subscription2 =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->www_foo_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(0u, cookie_changes_1.size());
+ ASSERT_EQ(0u, cookie_changes_2.size());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ this->DeliverChangeNotifications();
+ EXPECT_EQ(1u, cookie_changes_1.size());
+ EXPECT_EQ(1u, cookie_changes_2.size());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "C=D; path=/foo"));
+ this->DeliverChangeNotifications();
+
+ ASSERT_EQ(1u, cookie_changes_1.size());
+ EXPECT_EQ("A", cookie_changes_1[0].first.Name());
+ EXPECT_EQ("B", cookie_changes_1[0].first.Value());
+ EXPECT_EQ("/", cookie_changes_1[0].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(),
+ cookie_changes_1[0].first.Domain());
+
+ ASSERT_LE(1u, cookie_changes_2.size());
+ EXPECT_EQ("A", cookie_changes_2[0].first.Name());
+ EXPECT_EQ("B", cookie_changes_2[0].first.Value());
+ EXPECT_EQ("/", cookie_changes_2[0].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(),
+ cookie_changes_2[0].first.Domain());
+
+ ASSERT_LE(2u, cookie_changes_2.size());
+ EXPECT_EQ("C", cookie_changes_2[1].first.Name());
+ EXPECT_EQ("D", cookie_changes_2[1].first.Value());
+ EXPECT_EQ("/foo", cookie_changes_2[1].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(),
+ cookie_changes_2[1].first.Domain());
+
+ EXPECT_EQ(2u, cookie_changes_2.size());
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, DifferentSubscriptionsFiltering) {
+ if (!TypeParam::supports_url_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+
+ std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
+ std::vector<CookieChange> cookie_changes_3;
+ std::unique_ptr<CookieChangeSubscription> subscription1 =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
+ std::unique_ptr<CookieChangeSubscription> subscription2 =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_bar_com_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ std::unique_ptr<CookieChangeSubscription> subscription3 =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->www_foo_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_3)));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(0u, cookie_changes_1.size());
+ ASSERT_EQ(0u, cookie_changes_2.size());
+ EXPECT_EQ(0u, cookie_changes_3.size());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ this->DeliverChangeNotifications();
+ EXPECT_EQ(1u, cookie_changes_1.size());
+ EXPECT_EQ(0u, cookie_changes_2.size());
+ EXPECT_EQ(1u, cookie_changes_3.size());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "C=D"));
+ this->DeliverChangeNotifications();
+ EXPECT_EQ(1u, cookie_changes_1.size());
+ EXPECT_EQ(1u, cookie_changes_2.size());
+ EXPECT_EQ(1u, cookie_changes_3.size());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "E=F; path=/foo"));
+ this->DeliverChangeNotifications();
+
+ ASSERT_LE(1u, cookie_changes_1.size());
+ EXPECT_EQ("A", cookie_changes_1[0].first.Name());
+ EXPECT_EQ("B", cookie_changes_1[0].first.Value());
+ EXPECT_EQ(this->http_www_foo_.url().host(),
+ cookie_changes_1[0].first.Domain());
+ EXPECT_EQ(1u, cookie_changes_1.size());
+
+ ASSERT_LE(1u, cookie_changes_2.size());
+ EXPECT_EQ("C", cookie_changes_2[0].first.Name());
+ EXPECT_EQ("D", cookie_changes_2[0].first.Value());
+ EXPECT_EQ(this->http_bar_com_.url().host(),
+ cookie_changes_2[0].first.Domain());
+ EXPECT_EQ(1u, cookie_changes_2.size());
+
+ ASSERT_LE(1u, cookie_changes_3.size());
+ EXPECT_EQ("A", cookie_changes_3[0].first.Name());
+ EXPECT_EQ("B", cookie_changes_3[0].first.Value());
+ EXPECT_EQ("/", cookie_changes_3[0].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(),
+ cookie_changes_3[0].first.Domain());
+
+ ASSERT_LE(2u, cookie_changes_3.size());
+ EXPECT_EQ("E", cookie_changes_3[1].first.Name());
+ EXPECT_EQ("F", cookie_changes_3[1].first.Value());
+ EXPECT_EQ("/foo", cookie_changes_3[1].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(),
+ cookie_changes_3[1].first.Domain());
+
+ EXPECT_EQ(2u, cookie_changes_3.size());
+}
+
+TYPED_TEST_P(CookieStoreChangeUrlTest, MultipleSubscriptions) {
+ if (!TypeParam::supports_url_cookie_tracking ||
+ !TypeParam::supports_multiple_tracking_callbacks)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+
+ std::vector<CookieChange> cookie_changes_1, cookie_changes_2;
+ std::unique_ptr<CookieChangeSubscription> subscription1 =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
+ std::unique_ptr<CookieChangeSubscription> subscription2 =
+ cs->GetChangeDispatcher().AddCallbackForUrl(
+ this->http_www_foo_.url(),
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ this->DeliverChangeNotifications();
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "A=B"));
+ this->DeliverChangeNotifications();
+
+ ASSERT_EQ(1U, cookie_changes_1.size());
+ EXPECT_EQ("A", cookie_changes_1[0].first.Name());
+ EXPECT_EQ("B", cookie_changes_1[0].first.Value());
+
+ ASSERT_EQ(1U, cookie_changes_2.size());
+ EXPECT_EQ("A", cookie_changes_2[0].first.Name());
+ EXPECT_EQ("B", cookie_changes_2[0].first.Value());
+}
+
+TYPED_TEST_P(CookieStoreChangeNamedTest, NoCookie) {
if (!TypeParam::supports_named_cookie_tracking)
return;
@@ -428,30 +1605,32 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_NoCookie) {
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_www_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
EXPECT_EQ(0u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_InitialCookie) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, InitialCookie) {
if (!TypeParam::supports_named_cookie_tracking)
return;
CookieStore* cs = this->GetCookieStore();
std::vector<CookieChange> cookie_changes;
this->SetCookie(cs, this->http_www_foo_.url(), "abc=def");
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_www_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
EXPECT_EQ(0u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_Insert) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, InsertOne) {
if (!TypeParam::supports_named_cookie_tracking)
return;
@@ -460,22 +1639,63 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_Insert) {
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_www_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes.size());
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes.size());
EXPECT_EQ("abc", cookie_changes[0].first.Name());
EXPECT_EQ("def", cookie_changes[0].first.Value());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
- EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[0].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[0].second));
+}
+
+TYPED_TEST_P(CookieStoreChangeNamedTest, InsertTwo) {
+ if (!TypeParam::supports_named_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForCookie(
+ this->www_foo_foo_.url(), "abc",
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
+ ASSERT_EQ(0u, cookie_changes.size());
+
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/foo"));
+ this->DeliverChangeNotifications();
+
+ ASSERT_LE(1u, cookie_changes.size());
+ EXPECT_EQ("abc", cookie_changes[0].first.Name());
+ EXPECT_EQ("def", cookie_changes[0].first.Value());
+ EXPECT_EQ("/", cookie_changes[0].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[0].second));
+
+ ASSERT_LE(2u, cookie_changes.size());
+ EXPECT_EQ("abc", cookie_changes[1].first.Name());
+ EXPECT_EQ("hij", cookie_changes[1].first.Value());
+ EXPECT_EQ("/foo", cookie_changes[1].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[1].second));
+
+ EXPECT_EQ(2u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_InsertFiltering) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, InsertFiltering) {
if (!TypeParam::supports_named_cookie_tracking)
return;
@@ -484,9 +1704,10 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_InsertFiltering) {
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->www_foo_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes.size());
EXPECT_TRUE(
@@ -495,26 +1716,43 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_InsertFiltering) {
this->SetCookie(cs, this->http_bar_com_.url(), "abc=ghi; path=/"));
EXPECT_TRUE(
this->SetCookie(cs, this->http_www_foo_.url(), "abc=jkl; path=/bar"));
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "abc=mno; path=/foo/bar"));
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx"));
EXPECT_TRUE(
- this->SetCookie(cs, this->http_www_foo_.url(), "abc=mno; path=/foo"));
- this->RunUntilIdle();
- ASSERT_EQ(2u, cookie_changes.size());
+ this->SetCookie(cs, this->http_www_foo_.url(), "abc=pqr; path=/foo"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
+ "abc=stu; domain=foo.com"));
+ this->DeliverChangeNotifications();
+ ASSERT_LE(1u, cookie_changes.size());
EXPECT_EQ("abc", cookie_changes[0].first.Name());
EXPECT_EQ("def", cookie_changes[0].first.Value());
EXPECT_EQ("/", cookie_changes[0].first.Path());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
- EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[0].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[0].second));
+ ASSERT_LE(2u, cookie_changes.size());
EXPECT_EQ("abc", cookie_changes[1].first.Name());
- EXPECT_EQ("mno", cookie_changes[1].first.Value());
+ EXPECT_EQ("pqr", cookie_changes[1].first.Value());
EXPECT_EQ("/foo", cookie_changes[1].first.Path());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
- EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[1].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[1].second));
+
+ ASSERT_LE(3u, cookie_changes.size());
+ EXPECT_EQ("abc", cookie_changes[2].first.Name());
+ EXPECT_EQ("stu", cookie_changes[2].first.Value());
+ EXPECT_EQ("/", cookie_changes[2].first.Path());
+ EXPECT_EQ(".foo.com", cookie_changes[2].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[2].second));
+
+ EXPECT_EQ(3u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_Delete) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, DeleteOne) {
if (!TypeParam::supports_named_cookie_tracking)
return;
@@ -523,25 +1761,69 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_Delete) {
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_www_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes)));
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
EXPECT_EQ(1u, cookie_changes.size());
cookie_changes.clear();
EXPECT_TRUE(
this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "abc"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
+
ASSERT_EQ(1u, cookie_changes.size());
+ EXPECT_EQ("abc", cookie_changes[0].first.Name());
+ EXPECT_EQ("def", cookie_changes[0].first.Value());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
+ cookie_changes[0].second));
+}
+
+TYPED_TEST_P(CookieStoreChangeNamedTest, DeleteTwo) {
+ if (!TypeParam::supports_named_cookie_tracking)
+ return;
+ CookieStore* cs = this->GetCookieStore();
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForCookie(
+ this->www_foo_foo_.url(), "abc",
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/foo"));
+ this->DeliverChangeNotifications();
+ EXPECT_EQ(2u, cookie_changes.size());
+ cookie_changes.clear();
+
+ EXPECT_TRUE(this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(),
+ "abc", "/"));
+ EXPECT_TRUE(this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(),
+ "abc", "/foo"));
+ this->DeliverChangeNotifications();
+
+ ASSERT_LE(1u, cookie_changes.size());
EXPECT_EQ("abc", cookie_changes[0].first.Name());
EXPECT_EQ("def", cookie_changes[0].first.Value());
+ EXPECT_EQ("/", cookie_changes[0].first.Path());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
- EXPECT_EQ(CookieChangeCause::EXPLICIT, cookie_changes[0].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
+ cookie_changes[0].second));
+
+ ASSERT_EQ(2u, cookie_changes.size());
+ EXPECT_EQ("abc", cookie_changes[1].first.Name());
+ EXPECT_EQ("hij", cookie_changes[1].first.Value());
+ EXPECT_EQ("/foo", cookie_changes[1].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
+ cookie_changes[1].second));
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_DeleteFiltering) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, DeleteFiltering) {
if (!TypeParam::supports_named_cookie_tracking)
return;
@@ -549,32 +1831,67 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DeleteFiltering) {
std::vector<CookieChange> cookie_changes;
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForCookie(
- this->http_www_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes)));
- EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx"));
- EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "abc=def"));
- EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij"));
- this->RunUntilIdle();
- EXPECT_EQ(1u, cookie_changes.size());
+ this->www_foo_foo_.url(), "abc",
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx; path=/"));
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_bar_com_.url(), "abc=def; path=/"));
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/foo/bar"));
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "abc=mno; path=/foo"));
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "abc=pqr; path=/"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
+ "abc=stu; domain=foo.com"));
+ this->DeliverChangeNotifications();
+ EXPECT_EQ(3u, cookie_changes.size());
cookie_changes.clear();
EXPECT_TRUE(
this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "xyz"));
EXPECT_TRUE(
this->FindAndDeleteCookie(cs, this->http_bar_com_.url().host(), "abc"));
- EXPECT_TRUE(
- this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(), "abc"));
- this->RunUntilIdle();
- ASSERT_EQ(1u, cookie_changes.size());
-
+ EXPECT_TRUE(this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(),
+ "abc", "/foo/bar"));
+ EXPECT_TRUE(this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(),
+ "abc", "/foo"));
+ EXPECT_TRUE(this->FindAndDeleteCookie(cs, this->http_www_foo_.url().host(),
+ "abc", "/"));
+ EXPECT_TRUE(this->FindAndDeleteCookie(cs, ".foo.com", "abc", "/"));
+ this->DeliverChangeNotifications();
+
+ ASSERT_LE(1u, cookie_changes.size());
EXPECT_EQ("abc", cookie_changes[0].first.Name());
- EXPECT_EQ("hij", cookie_changes[0].first.Value());
+ EXPECT_EQ("mno", cookie_changes[0].first.Value());
+ EXPECT_EQ("/foo", cookie_changes[0].first.Path());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
- EXPECT_EQ(CookieChangeCause::EXPLICIT, cookie_changes[0].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
+ cookie_changes[0].second));
+
+ ASSERT_LE(2u, cookie_changes.size());
+ EXPECT_EQ("abc", cookie_changes[1].first.Name());
+ EXPECT_EQ("pqr", cookie_changes[1].first.Value());
+ EXPECT_EQ("/", cookie_changes[1].first.Path());
+ EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
+ cookie_changes[1].second));
+
+ ASSERT_LE(3u, cookie_changes.size());
+ EXPECT_EQ("abc", cookie_changes[2].first.Name());
+ EXPECT_EQ("stu", cookie_changes[2].first.Value());
+ EXPECT_EQ("/", cookie_changes[2].first.Path());
+ EXPECT_EQ(".foo.com", cookie_changes[2].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::EXPLICIT,
+ cookie_changes[2].second));
+
+ EXPECT_EQ(3u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_Overwrite) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, Overwrite) {
if (!TypeParam::supports_named_cookie_tracking)
return;
@@ -583,34 +1900,40 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_Overwrite) {
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_www_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes.size());
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
EXPECT_EQ(1u, cookie_changes.size());
cookie_changes.clear();
// Replacing an existing cookie is actually a two-phase delete + set
// operation, so we get an extra notification.
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=ghi"));
- this->RunUntilIdle();
- ASSERT_EQ(2u, cookie_changes.size());
+ this->DeliverChangeNotifications();
+ EXPECT_LE(1u, cookie_changes.size());
EXPECT_EQ("abc", cookie_changes[0].first.Name());
EXPECT_EQ("def", cookie_changes[0].first.Value());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
- EXPECT_EQ(CookieChangeCause::OVERWRITE, cookie_changes[0].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
+ cookie_changes[0].second));
+ EXPECT_LE(2u, cookie_changes.size());
EXPECT_EQ("abc", cookie_changes[1].first.Name());
EXPECT_EQ("ghi", cookie_changes[1].first.Value());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
- EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[1].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[1].second));
+
+ EXPECT_EQ(2u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_OverwriteFiltering) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, OverwriteFiltering) {
if (!TypeParam::supports_named_cookie_tracking)
return;
@@ -619,108 +1942,152 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_OverwriteFiltering) {
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->www_foo_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes.size());
EXPECT_TRUE(
- this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/"));
+ this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx1; path=/"));
EXPECT_TRUE(
- this->SetCookie(cs, this->http_bar_com_.url(), "abc=ghi; path=/"));
+ this->SetCookie(cs, this->http_bar_com_.url(), "abc=def1; path=/"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
+ "abc=hij1; path=/foo/bar"));
EXPECT_TRUE(
- this->SetCookie(cs, this->http_www_foo_.url(), "abc=jkl; path=/bar"));
- EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx"));
+ this->SetCookie(cs, this->http_www_foo_.url(), "abc=mno1; path=/foo"));
EXPECT_TRUE(
- this->SetCookie(cs, this->http_www_foo_.url(), "abc=mno; path=/foo"));
- this->RunUntilIdle();
- EXPECT_EQ(2u, cookie_changes.size());
+ this->SetCookie(cs, this->http_www_foo_.url(), "abc=pqr1; path=/"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
+ "abc=stu1; domain=foo.com"));
+ this->DeliverChangeNotifications();
+ EXPECT_EQ(3u, cookie_changes.size());
cookie_changes.clear();
// Replacing an existing cookie is actually a two-phase delete + set
// operation, so we get two notifications per overwrite.
EXPECT_TRUE(
- this->SetCookie(cs, this->http_www_foo_.url(), "abc=pqr; path=/"));
+ this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx2; path=/"));
EXPECT_TRUE(
- this->SetCookie(cs, this->http_bar_com_.url(), "abc=stu; path=/"));
+ this->SetCookie(cs, this->http_bar_com_.url(), "abc=def2; path=/"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
+ "abc=hij2; path=/foo/bar"));
EXPECT_TRUE(
- this->SetCookie(cs, this->http_www_foo_.url(), "abc=vwx; path=/bar"));
- EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx"));
+ this->SetCookie(cs, this->http_www_foo_.url(), "abc=mno2; path=/foo"));
EXPECT_TRUE(
- this->SetCookie(cs, this->http_www_foo_.url(), "abc=yz0; path=/foo"));
- this->RunUntilIdle();
- ASSERT_EQ(4u, cookie_changes.size());
+ this->SetCookie(cs, this->http_www_foo_.url(), "abc=pqr2; path=/"));
+ EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(),
+ "abc=stu2; domain=foo.com"));
+ this->DeliverChangeNotifications();
+ ASSERT_LE(1u, cookie_changes.size());
EXPECT_EQ("abc", cookie_changes[0].first.Name());
- EXPECT_EQ("def", cookie_changes[0].first.Value());
- EXPECT_EQ("/", cookie_changes[0].first.Path());
+ EXPECT_EQ("mno1", cookie_changes[0].first.Value());
+ EXPECT_EQ("/foo", cookie_changes[0].first.Path());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
- EXPECT_EQ(CookieChangeCause::OVERWRITE, cookie_changes[0].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
+ cookie_changes[0].second));
+ ASSERT_LE(2u, cookie_changes.size());
EXPECT_EQ("abc", cookie_changes[1].first.Name());
- EXPECT_EQ("pqr", cookie_changes[1].first.Value());
- EXPECT_EQ("/", cookie_changes[1].first.Path());
+ EXPECT_EQ("mno2", cookie_changes[1].first.Value());
+ EXPECT_EQ("/foo", cookie_changes[1].first.Path());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
- EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[1].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[1].second));
+ ASSERT_LE(3u, cookie_changes.size());
EXPECT_EQ("abc", cookie_changes[2].first.Name());
- EXPECT_EQ("mno", cookie_changes[2].first.Value());
- EXPECT_EQ("/foo", cookie_changes[2].first.Path());
+ EXPECT_EQ("pqr1", cookie_changes[2].first.Value());
+ EXPECT_EQ("/", cookie_changes[2].first.Path());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[2].first.Domain());
- EXPECT_EQ(CookieChangeCause::OVERWRITE, cookie_changes[2].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
+ cookie_changes[2].second));
+ ASSERT_LE(4u, cookie_changes.size());
EXPECT_EQ("abc", cookie_changes[3].first.Name());
- EXPECT_EQ("yz0", cookie_changes[3].first.Value());
- EXPECT_EQ("/foo", cookie_changes[3].first.Path());
+ EXPECT_EQ("pqr2", cookie_changes[3].first.Value());
+ EXPECT_EQ("/", cookie_changes[3].first.Path());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[3].first.Domain());
- EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[3].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[3].second));
+
+ ASSERT_LE(5u, cookie_changes.size());
+ EXPECT_EQ("abc", cookie_changes[4].first.Name());
+ EXPECT_EQ("stu1", cookie_changes[4].first.Value());
+ EXPECT_EQ("/", cookie_changes[4].first.Path());
+ EXPECT_EQ(".foo.com", cookie_changes[4].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
+ cookie_changes[4].second));
+
+ ASSERT_LE(6u, cookie_changes.size());
+ EXPECT_EQ("abc", cookie_changes[5].first.Name());
+ EXPECT_EQ("stu2", cookie_changes[5].first.Value());
+ EXPECT_EQ("/", cookie_changes[5].first.Path());
+ EXPECT_EQ(".foo.com", cookie_changes[5].first.Domain());
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[5].second));
+
+ EXPECT_EQ(6u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_OverwriteWithHttpOnly) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, OverwriteWithHttpOnly) {
if (!TypeParam::supports_named_cookie_tracking)
return;
- // Insert a cookie "abc" for path "/foo"
+ // Insert a cookie "abc" for path "/foo".
CookieStore* cs = this->GetCookieStore();
std::vector<CookieChange> cookie_changes;
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->www_foo_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes.size());
EXPECT_TRUE(
this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes.size());
- EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[0].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[0].second));
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
EXPECT_EQ("abc", cookie_changes[0].first.Name());
EXPECT_EQ("def", cookie_changes[0].first.Value());
+ EXPECT_FALSE(cookie_changes[0].first.IsHttpOnly());
cookie_changes.clear();
- // Insert a cookie "a" for path "/path1", that is httponly. This should
+ // Insert a cookie "a" for path "/foo", that is httponly. This should
// overwrite the non-http-only version.
CookieOptions allow_httponly;
allow_httponly.set_include_httponly();
EXPECT_TRUE(this->SetCookieWithOptions(cs, this->http_www_foo_.url(),
"abc=hij; path=/foo; httponly",
allow_httponly));
- this->RunUntilIdle();
- ASSERT_EQ(2u, cookie_changes.size());
+ this->DeliverChangeNotifications();
+
+ ASSERT_LE(1u, cookie_changes.size());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[0].first.Domain());
- EXPECT_EQ(CookieChangeCause::OVERWRITE, cookie_changes[0].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::OVERWRITE,
+ cookie_changes[0].second));
EXPECT_EQ("abc", cookie_changes[0].first.Name());
EXPECT_EQ("def", cookie_changes[0].first.Value());
+ EXPECT_FALSE(cookie_changes[0].first.IsHttpOnly());
+
+ ASSERT_LE(2u, cookie_changes.size());
EXPECT_EQ(this->http_www_foo_.url().host(), cookie_changes[1].first.Domain());
- EXPECT_EQ(CookieChangeCause::INSERTED, cookie_changes[1].second);
+ EXPECT_TRUE(this->MatchesCause(CookieChangeCause::INSERTED,
+ cookie_changes[1].second));
EXPECT_EQ("abc", cookie_changes[1].first.Name());
EXPECT_EQ("hij", cookie_changes[1].first.Value());
+ EXPECT_TRUE(cookie_changes[1].first.IsHttpOnly());
+
+ EXPECT_EQ(2u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_Deregister) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, Deregister) {
if (!TypeParam::supports_named_cookie_tracking)
return;
@@ -730,15 +2097,16 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_Deregister) {
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->www_foo_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes.size());
// Insert a cookie and make sure it is seen.
EXPECT_TRUE(
this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes.size());
EXPECT_EQ("abc", cookie_changes[0].first.Name());
EXPECT_EQ("def", cookie_changes[0].first.Value());
@@ -751,12 +2119,12 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_Deregister) {
// Insert a second cookie and make sure it's not visible.
EXPECT_TRUE(
this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
EXPECT_EQ(0u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_DeregisterMultiple) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, DeregisterMultiple) {
if (!TypeParam::supports_named_cookie_tracking ||
!TypeParam::supports_multiple_tracking_callbacks)
return;
@@ -768,21 +2136,23 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DeregisterMultiple) {
std::unique_ptr<CookieChangeSubscription> subscription1 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->www_foo_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_1)));
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
std::unique_ptr<CookieChangeSubscription> subscription2 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->www_foo_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_2)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes_1.size());
ASSERT_EQ(0u, cookie_changes_2.size());
// Insert a cookie and make sure it's seen.
EXPECT_TRUE(
this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
EXPECT_EQ("def", cookie_changes_1[0].first.Value());
@@ -802,7 +2172,7 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DeregisterMultiple) {
// change array.
EXPECT_TRUE(
this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
EXPECT_EQ("hij", cookie_changes_1[0].first.Value());
@@ -811,10 +2181,44 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DeregisterMultiple) {
EXPECT_EQ(0u, cookie_changes_2.size());
}
-// Confirm that deregistering a subscription blocks the notification
-// if the deregistration happened after the change but before the
-// notification was received.
-TYPED_TEST_P(CookieStoreChangeTest, Named_DeregisterRace) {
+// Confirm that a listener does not receive notifications for changes that
+// happened right before the subscription was established.
+TYPED_TEST_P(CookieStoreChangeNamedTest, DispatchRace) {
+ if (!TypeParam::supports_named_cookie_tracking)
+ return;
+
+ CookieStore* cs = this->GetCookieStore();
+
+ // This cookie insertion should not be seen.
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
+ // DeliverChangeNotifications() must NOT be called before the subscription is
+ // established.
+
+ std::vector<CookieChange> cookie_changes;
+ std::unique_ptr<CookieChangeSubscription> subscription =
+ cs->GetChangeDispatcher().AddCallbackForCookie(
+ this->www_foo_foo_.url(), "abc",
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+
+ EXPECT_TRUE(
+ this->SetCookie(cs, this->http_www_foo_.url(), "abc=hij; path=/"));
+ this->DeliverChangeNotifications();
+
+ EXPECT_LE(1u, cookie_changes.size());
+ EXPECT_EQ("abc", cookie_changes[0].first.Name());
+ EXPECT_EQ("hij", cookie_changes[0].first.Value());
+ EXPECT_EQ("/", cookie_changes[0].first.Path());
+
+ ASSERT_EQ(1u, cookie_changes.size());
+}
+
+// Confirm that deregistering a subscription blocks the notification if the
+// deregistration happened after the change but before the notification was
+// received.
+TYPED_TEST_P(CookieStoreChangeNamedTest, DeregisterRace) {
if (!TypeParam::supports_named_cookie_tracking)
return;
@@ -824,15 +2228,16 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DeregisterRace) {
std::unique_ptr<CookieChangeSubscription> subscription =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->www_foo_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes.size());
// Insert a cookie and make sure it's seen.
EXPECT_TRUE(
this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes.size());
EXPECT_EQ("abc", cookie_changes[0].first.Name());
EXPECT_EQ("def", cookie_changes[0].first.Value());
@@ -855,11 +2260,11 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DeregisterRace) {
// valid. Destroy the subscription so as to lose the race and make sure the
// task posted arrives after the subscription was destroyed.
subscription.reset();
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_DeregisterRaceMultiple) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, DeregisterRaceMultiple) {
if (!TypeParam::supports_named_cookie_tracking ||
!TypeParam::supports_multiple_tracking_callbacks)
return;
@@ -870,21 +2275,23 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DeregisterRaceMultiple) {
std::unique_ptr<CookieChangeSubscription> subscription1 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->www_foo_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_1)));
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
std::unique_ptr<CookieChangeSubscription> subscription2 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->www_foo_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_2)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes_1.size());
ASSERT_EQ(0u, cookie_changes_2.size());
// Insert a cookie and make sure it's seen.
EXPECT_TRUE(
this->SetCookie(cs, this->http_www_foo_.url(), "abc=def; path=/foo"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
@@ -906,17 +2313,15 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DeregisterRaceMultiple) {
// Note that by the API contract it's perfectly valid to have received the
// notification immediately, i.e. synchronously with the cookie change. In
// that case, there's nothing to test.
- if (1u == cookie_changes_2.size()) {
- LOG(ERROR) << "Nothing to test.";
+ if (1u == cookie_changes_2.size())
return;
- }
// A task was posted by the SetCookie() above, but has not yet arrived. If it
// arrived before the subscription is destroyed, callback execution would be
// valid. Destroy one of the subscriptions so as to lose the race and make
// sure the task posted arrives after the subscription was destroyed.
subscription2.reset();
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
EXPECT_EQ("hij", cookie_changes_1[0].first.Value());
@@ -926,7 +2331,7 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DeregisterRaceMultiple) {
ASSERT_EQ(0u, cookie_changes_2.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsDisjoint) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, DifferentSubscriptionsDisjoint) {
if (!TypeParam::supports_named_cookie_tracking)
return;
@@ -936,24 +2341,26 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsDisjoint) {
std::unique_ptr<CookieChangeSubscription> subscription1 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_www_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_1)));
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
std::unique_ptr<CookieChangeSubscription> subscription2 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_bar_com_.url(), "ghi",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_2)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes_1.size());
ASSERT_EQ(0u, cookie_changes_2.size());
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
EXPECT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ(0u, cookie_changes_2.size());
EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "ghi=jkl"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
@@ -968,7 +2375,7 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsDisjoint) {
cookie_changes_2[0].first.Domain());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsDomains) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, DifferentSubscriptionsDomains) {
if (!TypeParam::supports_named_cookie_tracking)
return;
@@ -978,24 +2385,26 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsDomains) {
std::unique_ptr<CookieChangeSubscription> subscription1 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_www_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_1)));
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
std::unique_ptr<CookieChangeSubscription> subscription2 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_bar_com_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_2)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes_1.size());
ASSERT_EQ(0u, cookie_changes_2.size());
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
EXPECT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ(0u, cookie_changes_2.size());
EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "abc=ghi"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
@@ -1010,7 +2419,7 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsDomains) {
cookie_changes_2[0].first.Domain());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsNames) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, DifferentSubscriptionsNames) {
if (!TypeParam::supports_named_cookie_tracking)
return;
@@ -1020,24 +2429,26 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsNames) {
std::unique_ptr<CookieChangeSubscription> subscription1 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_www_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_1)));
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
std::unique_ptr<CookieChangeSubscription> subscription2 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_www_foo_.url(), "ghi",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_2)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes_1.size());
ASSERT_EQ(0u, cookie_changes_2.size());
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
EXPECT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ(0u, cookie_changes_2.size());
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "ghi=jkl"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
@@ -1052,7 +2463,7 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsNames) {
cookie_changes_2[0].first.Domain());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsPaths) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, DifferentSubscriptionsPaths) {
if (!TypeParam::supports_named_cookie_tracking)
return;
@@ -1062,25 +2473,27 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsPaths) {
std::unique_ptr<CookieChangeSubscription> subscription1 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_www_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_1)));
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
std::unique_ptr<CookieChangeSubscription> subscription2 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->www_foo_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_2)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes_1.size());
ASSERT_EQ(0u, cookie_changes_2.size());
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
EXPECT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ(1u, cookie_changes_2.size());
EXPECT_TRUE(
this->SetCookie(cs, this->http_www_foo_.url(), "abc=ghi; path=/foo"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
@@ -1096,15 +2509,17 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsPaths) {
EXPECT_EQ(this->http_www_foo_.url().host(),
cookie_changes_2[0].first.Domain());
- ASSERT_EQ(2u, cookie_changes_2.size());
+ ASSERT_LE(2u, cookie_changes_2.size());
EXPECT_EQ("abc", cookie_changes_2[1].first.Name());
EXPECT_EQ("ghi", cookie_changes_2[1].first.Value());
EXPECT_EQ("/foo", cookie_changes_2[1].first.Path());
EXPECT_EQ(this->http_www_foo_.url().host(),
cookie_changes_2[1].first.Domain());
+
+ EXPECT_EQ(2u, cookie_changes_2.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsFiltering) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, DifferentSubscriptionsFiltering) {
if (!TypeParam::supports_named_cookie_tracking)
return;
@@ -1115,31 +2530,35 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsFiltering) {
std::unique_ptr<CookieChangeSubscription> subscription1 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_www_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_1)));
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
std::unique_ptr<CookieChangeSubscription> subscription2 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_www_foo_.url(), "hij",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_2)));
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
std::unique_ptr<CookieChangeSubscription> subscription3 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_bar_com_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_3)));
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_3)));
std::unique_ptr<CookieChangeSubscription> subscription4 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->www_foo_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_4)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_4)));
+ this->DeliverChangeNotifications();
ASSERT_EQ(0u, cookie_changes_1.size());
ASSERT_EQ(0u, cookie_changes_2.size());
EXPECT_EQ(0u, cookie_changes_3.size());
EXPECT_EQ(0u, cookie_changes_4.size());
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
EXPECT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ(0u, cookie_changes_2.size());
EXPECT_EQ(0u, cookie_changes_3.size());
@@ -1147,7 +2566,7 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsFiltering) {
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx"));
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "hij=mno"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
EXPECT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ(1u, cookie_changes_2.size());
EXPECT_EQ(0u, cookie_changes_3.size());
@@ -1156,7 +2575,7 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsFiltering) {
EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "hij=pqr"));
EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "xyz=zyx"));
EXPECT_TRUE(this->SetCookie(cs, this->http_bar_com_.url(), "abc=stu"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
EXPECT_EQ(1u, cookie_changes_1.size());
EXPECT_EQ(1u, cookie_changes_2.size());
EXPECT_EQ(1u, cookie_changes_3.size());
@@ -1164,25 +2583,28 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsFiltering) {
EXPECT_TRUE(
this->SetCookie(cs, this->http_www_foo_.url(), "abc=vwx; path=/foo"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
- ASSERT_EQ(1u, cookie_changes_1.size());
+ ASSERT_LE(1u, cookie_changes_1.size());
EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
EXPECT_EQ("def", cookie_changes_1[0].first.Value());
EXPECT_EQ(this->http_www_foo_.url().host(),
cookie_changes_1[0].first.Domain());
+ EXPECT_EQ(1u, cookie_changes_1.size());
- ASSERT_EQ(1u, cookie_changes_2.size());
+ ASSERT_LE(1u, cookie_changes_2.size());
EXPECT_EQ("hij", cookie_changes_2[0].first.Name());
EXPECT_EQ("mno", cookie_changes_2[0].first.Value());
EXPECT_EQ(this->http_www_foo_.url().host(),
cookie_changes_2[0].first.Domain());
+ EXPECT_EQ(1u, cookie_changes_2.size());
- ASSERT_EQ(1u, cookie_changes_3.size());
+ ASSERT_LE(1u, cookie_changes_3.size());
EXPECT_EQ("abc", cookie_changes_3[0].first.Name());
EXPECT_EQ("stu", cookie_changes_3[0].first.Value());
EXPECT_EQ(this->http_bar_com_.url().host(),
cookie_changes_3[0].first.Domain());
+ EXPECT_EQ(1u, cookie_changes_3.size());
ASSERT_LE(1u, cookie_changes_4.size());
EXPECT_EQ("abc", cookie_changes_4[0].first.Name());
@@ -1191,15 +2613,17 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_DifferentSubscriptionsFiltering) {
EXPECT_EQ(this->http_www_foo_.url().host(),
cookie_changes_4[0].first.Domain());
- ASSERT_EQ(2u, cookie_changes_4.size());
+ ASSERT_LE(2u, cookie_changes_4.size());
EXPECT_EQ("abc", cookie_changes_4[1].first.Name());
EXPECT_EQ("vwx", cookie_changes_4[1].first.Value());
EXPECT_EQ("/foo", cookie_changes_4[1].first.Path());
EXPECT_EQ(this->http_www_foo_.url().host(),
cookie_changes_4[1].first.Domain());
+
+ EXPECT_EQ(2u, cookie_changes_4.size());
}
-TYPED_TEST_P(CookieStoreChangeTest, Named_MultipleSubscriptions) {
+TYPED_TEST_P(CookieStoreChangeNamedTest, MultipleSubscriptions) {
if (!TypeParam::supports_named_cookie_tracking ||
!TypeParam::supports_multiple_tracking_callbacks)
return;
@@ -1210,18 +2634,20 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_MultipleSubscriptions) {
std::unique_ptr<CookieChangeSubscription> subscription1 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_www_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_1)));
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_1)));
std::unique_ptr<CookieChangeSubscription> subscription2 =
cs->GetChangeDispatcher().AddCallbackForCookie(
this->http_www_foo_.url(), "abc",
- base::BindRepeating(&OnCookieChange,
- base::Unretained(&cookie_changes_2)));
- this->RunUntilIdle();
+ base::BindRepeating(
+ &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
+ base::Unretained(&cookie_changes_2)));
+ this->DeliverChangeNotifications();
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "xyz=zyx"));
EXPECT_TRUE(this->SetCookie(cs, this->http_www_foo_.url(), "abc=def"));
- this->RunUntilIdle();
+ this->DeliverChangeNotifications();
ASSERT_EQ(1U, cookie_changes_1.size());
EXPECT_EQ("abc", cookie_changes_1[0].first.Name());
@@ -1234,37 +2660,68 @@ TYPED_TEST_P(CookieStoreChangeTest, Named_MultipleSubscriptions) {
cookie_changes_2.clear();
}
-REGISTER_TYPED_TEST_CASE_P(CookieStoreChangeTest,
- Global_NoCookie,
- Global_InitialCookie,
- Global_Insert,
- Global_Delete,
- Global_Overwrite,
- Global_OverwriteWithHttpOnly,
- Global_Deregister,
- Global_DeregisterMultiple,
- Global_DeregisterRace,
- Global_DeregisterRaceMultiple,
- Global_MultipleSubscriptions,
- Named_NoCookie,
- Named_InitialCookie,
- Named_Insert,
- Named_InsertFiltering,
- Named_Delete,
- Named_DeleteFiltering,
- Named_Overwrite,
- Named_OverwriteFiltering,
- Named_OverwriteWithHttpOnly,
- Named_Deregister,
- Named_DeregisterMultiple,
- Named_DeregisterRace,
- Named_DeregisterRaceMultiple,
- Named_DifferentSubscriptionsDisjoint,
- Named_DifferentSubscriptionsDomains,
- Named_DifferentSubscriptionsNames,
- Named_DifferentSubscriptionsPaths,
- Named_DifferentSubscriptionsFiltering,
- Named_MultipleSubscriptions);
+REGISTER_TYPED_TEST_CASE_P(CookieStoreChangeGlobalTest,
+ NoCookie,
+ InitialCookie,
+ InsertOne,
+ InsertMany,
+ DeleteOne,
+ DeleteTwo,
+ Overwrite,
+ OverwriteWithHttpOnly,
+ Deregister,
+ DeregisterMultiple,
+ DispatchRace,
+ DeregisterRace,
+ DeregisterRaceMultiple,
+ MultipleSubscriptions);
+
+REGISTER_TYPED_TEST_CASE_P(CookieStoreChangeUrlTest,
+ NoCookie,
+ InitialCookie,
+ InsertOne,
+ InsertMany,
+ InsertFiltering,
+ DeleteOne,
+ DeleteTwo,
+ DeleteFiltering,
+ Overwrite,
+ OverwriteFiltering,
+ OverwriteWithHttpOnly,
+ Deregister,
+ DeregisterMultiple,
+ DispatchRace,
+ DeregisterRace,
+ DeregisterRaceMultiple,
+ DifferentSubscriptionsDisjoint,
+ DifferentSubscriptionsDomains,
+ DifferentSubscriptionsPaths,
+ DifferentSubscriptionsFiltering,
+ MultipleSubscriptions);
+
+REGISTER_TYPED_TEST_CASE_P(CookieStoreChangeNamedTest,
+ NoCookie,
+ InitialCookie,
+ InsertOne,
+ InsertTwo,
+ InsertFiltering,
+ DeleteOne,
+ DeleteTwo,
+ DeleteFiltering,
+ Overwrite,
+ OverwriteFiltering,
+ OverwriteWithHttpOnly,
+ Deregister,
+ DeregisterMultiple,
+ DispatchRace,
+ DeregisterRace,
+ DeregisterRaceMultiple,
+ DifferentSubscriptionsDisjoint,
+ DifferentSubscriptionsDomains,
+ DifferentSubscriptionsNames,
+ DifferentSubscriptionsPaths,
+ DifferentSubscriptionsFiltering,
+ MultipleSubscriptions);
} // namespace net
diff --git a/chromium/net/cookies/cookie_store_test_helpers.cc b/chromium/net/cookies/cookie_store_test_helpers.cc
index 13e0f20b64a..66d66609240 100644
--- a/chromium/net/cookies/cookie_store_test_helpers.cc
+++ b/chromium/net/cookies/cookie_store_test_helpers.cc
@@ -49,6 +49,13 @@ DelayedCookieMonsterChangeDispatcher::AddCallbackForCookie(
return nullptr;
}
std::unique_ptr<CookieChangeSubscription>
+DelayedCookieMonsterChangeDispatcher::AddCallbackForUrl(
+ const GURL& url,
+ CookieChangeCallback callback) {
+ ADD_FAILURE();
+ return nullptr;
+}
+std::unique_ptr<CookieChangeSubscription>
DelayedCookieMonsterChangeDispatcher::AddCallbackForAllChanges(
CookieChangeCallback callback) {
ADD_FAILURE();
@@ -220,4 +227,62 @@ std::string CookieURLHelper::Format(const std::string& format_string) const {
return new_string;
}
+//
+// FlushablePersistentStore
+//
+FlushablePersistentStore::FlushablePersistentStore() : flush_count_(0) {}
+
+void FlushablePersistentStore::Load(const LoadedCallback& loaded_callback) {
+ std::vector<std::unique_ptr<CanonicalCookie>> out_cookies;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(loaded_callback, std::move(out_cookies)));
+}
+
+void FlushablePersistentStore::LoadCookiesForKey(
+ const std::string& key,
+ const LoadedCallback& loaded_callback) {
+ Load(loaded_callback);
+}
+
+void FlushablePersistentStore::AddCookie(const CanonicalCookie&) {}
+
+void FlushablePersistentStore::UpdateCookieAccessTime(const CanonicalCookie&) {}
+
+void FlushablePersistentStore::DeleteCookie(const CanonicalCookie&) {}
+
+void FlushablePersistentStore::SetForceKeepSessionState() {}
+
+void FlushablePersistentStore::SetBeforeFlushCallback(
+ base::RepeatingClosure callback) {}
+
+void FlushablePersistentStore::Flush(base::OnceClosure callback) {
+ base::AutoLock lock(flush_count_lock_);
+ ++flush_count_;
+ std::move(callback).Run();
+}
+
+int FlushablePersistentStore::flush_count() {
+ base::AutoLock lock(flush_count_lock_);
+ return flush_count_;
+}
+
+FlushablePersistentStore::~FlushablePersistentStore() = default;
+
+//
+// CallbackCounter
+//
+CallbackCounter::CallbackCounter() : callback_count_(0) {}
+
+void CallbackCounter::Callback() {
+ base::AutoLock lock(callback_count_lock_);
+ ++callback_count_;
+}
+
+int CallbackCounter::callback_count() {
+ base::AutoLock lock(callback_count_lock_);
+ return callback_count_;
+}
+
+CallbackCounter::~CallbackCounter() = default;
+
} // namespace net
diff --git a/chromium/net/cookies/cookie_store_test_helpers.h b/chromium/net/cookies/cookie_store_test_helpers.h
index e833147ab0e..440f70cf8ce 100644
--- a/chromium/net/cookies/cookie_store_test_helpers.h
+++ b/chromium/net/cookies/cookie_store_test_helpers.h
@@ -12,6 +12,7 @@
#include "base/callback_forward.h"
#include "base/macros.h"
+#include "base/synchronization/lock.h"
#include "net/cookies/cookie_change_dispatcher.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -29,6 +30,9 @@ class DelayedCookieMonsterChangeDispatcher : public CookieChangeDispatcher {
const GURL& url,
const std::string& name,
CookieChangeCallback callback) override WARN_UNUSED_RESULT;
+ std::unique_ptr<CookieChangeSubscription> AddCallbackForUrl(
+ const GURL& url,
+ CookieChangeCallback callback) override WARN_UNUSED_RESULT;
std::unique_ptr<CookieChangeSubscription> AddCallbackForAllChanges(
CookieChangeCallback callback) override WARN_UNUSED_RESULT;
@@ -144,6 +148,46 @@ class CookieURLHelper {
const std::string domain_and_registry_;
};
+// Mock PersistentCookieStore that keeps track of the number of Flush() calls.
+class FlushablePersistentStore : public CookieMonster::PersistentCookieStore {
+ public:
+ FlushablePersistentStore();
+
+ // CookieMonster::PersistentCookieStore implementation:
+ void Load(const LoadedCallback& loaded_callback) override;
+ void LoadCookiesForKey(const std::string& key,
+ const LoadedCallback& loaded_callback) override;
+ void AddCookie(const CanonicalCookie&) override;
+ void UpdateCookieAccessTime(const CanonicalCookie&) override;
+ void DeleteCookie(const CanonicalCookie&) override;
+ void SetForceKeepSessionState() override;
+ void SetBeforeFlushCallback(base::RepeatingClosure callback) override;
+ void Flush(base::OnceClosure callback) override;
+
+ int flush_count();
+
+ private:
+ ~FlushablePersistentStore() override;
+
+ int flush_count_;
+ base::Lock flush_count_lock_; // Protects |flush_count_|.
+};
+
+// Counts the number of times Callback() has been run.
+class CallbackCounter : public base::RefCountedThreadSafe<CallbackCounter> {
+ public:
+ CallbackCounter();
+ void Callback();
+ int callback_count();
+
+ private:
+ friend class base::RefCountedThreadSafe<CallbackCounter>;
+ ~CallbackCounter();
+
+ int callback_count_;
+ base::Lock callback_count_lock_; // Protects |callback_count_|.
+};
+
} // namespace net
#endif // NET_COOKIES_COOKIE_STORE_TEST_HELPERS_H_
diff --git a/chromium/net/cookies/cookie_store_unittest.h b/chromium/net/cookies/cookie_store_unittest.h
index 1d36cbe603a..c715a19ce3b 100644
--- a/chromium/net/cookies/cookie_store_unittest.h
+++ b/chromium/net/cookies/cookie_store_unittest.h
@@ -47,8 +47,8 @@ const char kValidCookieLine[] = "A=B; path=/";
// // Factory function. Will be called at most once per test.
// static std::unique_ptr<CookieStore> Create();
//
-// // Drains the run loop(s) involved in the test.
-// static void RunUntilIdle();
+// // Drains the run loop(s) used to deliver cookie change notifications.
+// static void DeliverChangeNotifications();
//
// // The cookie store supports cookies with the exclude_httponly() option.
// static const bool supports_http_only;
@@ -75,6 +75,10 @@ const char kValidCookieLine[] = "A=B; path=/";
// // calls to CookieStore::AddCallbackForAllChanges()).
// static const bool supports_global_cookie_tracking;
//
+// // The cookie store supports tracking of cookie changes for an URL (i.e.
+// // calls to CookieStore::AddCallbackForUrl()).
+// static const bool supports_url_cookie_tracking;
+//
// // The cookie store supports tracking of named cookie changes (i.e.
// // calls to CookieStore::AddCallbackForCookie()).
// static const bool supports_named_cookie_tracking;
@@ -82,6 +86,16 @@ const char kValidCookieLine[] = "A=B; path=/";
// // The cookie store supports more than one callback per cookie change type.
// static const bool supports_multiple_tracking_callbacks;
//
+// // The cookie store correctly distinguishes between OVERWRITE and EXPLICIT
+// // (deletion) change causes.
+// static const bool has_exact_change_cause;
+//
+// // The cookie store is guaranteed to deliver cookie changes in the order
+// // in which calls were issued. This only applies to changes coming from
+// // _different_ calls. If a call results in a cookie overwrite, the deletion
+// // change must still be issued before the insertion change.
+// static const bool has_exact_change_ordering;
+//
// // Time to wait between two cookie insertions to ensure that cookies have
// // different creation times.
// static const int creation_time_granularity_in_ms;
@@ -298,9 +312,6 @@ class CookieStoreTest : public testing::Test {
return cookie_store_.get();
}
- // Drains all pending tasks on the run loop(s) involved in the test.
- void RunUntilIdle() { CookieStoreTestTraits::RunUntilIdle(); }
-
// Compares two cookie lines.
void MatchCookieLines(const std::string& line1, const std::string& line2) {
EXPECT_EQ(TokenizeCookieLine(line1), TokenizeCookieLine(line2));
diff --git a/chromium/net/cookies/cookie_util.cc b/chromium/net/cookies/cookie_util.cc
index cf133b61913..0a1ecac9b95 100644
--- a/chromium/net/cookies/cookie_util.cc
+++ b/chromium/net/cookies/cookie_util.cc
@@ -273,6 +273,39 @@ GURL CookieOriginToURL(const std::string& domain, bool is_https) {
return GURL(scheme + "://" + host);
}
+bool IsDomainMatch(const std::string& domain, const std::string& host) {
+ // Can domain match in two ways; as a domain cookie (where the cookie
+ // domain begins with ".") or as a host cookie (where it doesn't).
+
+ // Some consumers of the CookieMonster expect to set cookies on
+ // URLs like http://.strange.url. To retrieve cookies in this instance,
+ // we allow matching as a host cookie even when the domain_ starts with
+ // a period.
+ if (host == domain)
+ return true;
+
+ // Domain cookie must have an initial ".". To match, it must be
+ // equal to url's host with initial period removed, or a suffix of
+ // it.
+
+ // Arguably this should only apply to "http" or "https" cookies, but
+ // extension cookie tests currently use the funtionality, and if we
+ // ever decide to implement that it should be done by preventing
+ // such cookies from being set.
+ if (domain.empty() || domain[0] != '.')
+ return false;
+
+ // The host with a "." prefixed.
+ if (domain.compare(1, std::string::npos, host) == 0)
+ return true;
+
+ // A pure suffix of the host (ok since we know the domain already
+ // starts with a ".")
+ return (host.length() > domain.length() &&
+ host.compare(host.length() - domain.length(), domain.length(),
+ domain) == 0);
+}
+
void ParseRequestCookieLine(const std::string& header_value,
ParsedRequestCookies* parsed_cookies) {
std::string::const_iterator i = header_value.begin();
diff --git a/chromium/net/cookies/cookie_util.h b/chromium/net/cookies/cookie_util.h
index 60e5f661cd4..18a3bfbeb50 100644
--- a/chromium/net/cookies/cookie_util.h
+++ b/chromium/net/cookies/cookie_util.h
@@ -48,6 +48,11 @@ NET_EXPORT base::Time ParseCookieExpirationTime(const std::string& time_string);
// Convenience for converting a cookie origin (domain and https pair) to a URL.
NET_EXPORT GURL CookieOriginToURL(const std::string& domain, bool is_https);
+// Returns true if the cookie |domain| matches the given |host| as described
+// in section 5.1.3 of RFC 6265.
+NET_EXPORT bool IsDomainMatch(const std::string& domain,
+ const std::string& host);
+
// A ParsedRequestCookie consists of the key and value of the cookie.
typedef std::pair<base::StringPiece, base::StringPiece> ParsedRequestCookie;
typedef std::vector<ParsedRequestCookie> ParsedRequestCookies;
diff --git a/chromium/net/cookies/cookie_util_unittest.cc b/chromium/net/cookies/cookie_util_unittest.cc
index 7d55dd9e9d2..79c952bd04b 100644
--- a/chromium/net/cookies/cookie_util_unittest.cc
+++ b/chromium/net/cookies/cookie_util_unittest.cc
@@ -250,6 +250,19 @@ TEST(CookieUtilTest, TestGetEffectiveDomain) {
cookie_util::GetEffectiveDomain("ftp", "www.example.com"));
}
+TEST(CookieUtilTest, TestIsDomainMatch) {
+ EXPECT_TRUE(cookie_util::IsDomainMatch("example.com", "example.com"));
+ EXPECT_FALSE(cookie_util::IsDomainMatch("www.example.com", "example.com"));
+
+ EXPECT_TRUE(cookie_util::IsDomainMatch(".example.com", "example.com"));
+ EXPECT_TRUE(cookie_util::IsDomainMatch(".example.com", "www.example.com"));
+ EXPECT_FALSE(cookie_util::IsDomainMatch(".www.example.com", "example.com"));
+
+ EXPECT_FALSE(cookie_util::IsDomainMatch("example.com", "example.de"));
+ EXPECT_FALSE(cookie_util::IsDomainMatch(".example.com", "example.de"));
+ EXPECT_FALSE(cookie_util::IsDomainMatch(".example.de", "example.de.vu"));
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/cookies/parsed_cookie.cc b/chromium/net/cookies/parsed_cookie.cc
index 1be10eed753..450e869e8ba 100644
--- a/chromium/net/cookies/parsed_cookie.cc
+++ b/chromium/net/cookies/parsed_cookie.cc
@@ -150,7 +150,7 @@ ParsedCookie::ParsedCookie(const std::string& cookie_line)
ParsedCookie::~ParsedCookie() = default;
bool ParsedCookie::IsValid() const {
- return !pairs_.empty() && IsSameSiteAttributeValid();
+ return !pairs_.empty();
}
CookieSameSite ParsedCookie::SameSite() const {
@@ -501,8 +501,4 @@ void ParsedCookie::ClearAttributePair(size_t index) {
pairs_.erase(pairs_.begin() + index);
}
-bool ParsedCookie::IsSameSiteAttributeValid() const {
- return same_site_index_ == 0 || SameSite() != CookieSameSite::DEFAULT_MODE;
-}
-
} // namespace net
diff --git a/chromium/net/cookies/parsed_cookie.h b/chromium/net/cookies/parsed_cookie.h
index 8bc5e99b678..d6b951a1598 100644
--- a/chromium/net/cookies/parsed_cookie.h
+++ b/chromium/net/cookies/parsed_cookie.h
@@ -131,10 +131,6 @@ class NET_EXPORT ParsedCookie {
// |index| refers to a position in |pairs_|.
void ClearAttributePair(size_t index);
- // Returns false if a 'SameSite' attribute is present, but has an unrecognized
- // value. In particular, this includes attributes with empty values.
- bool IsSameSiteAttributeValid() const;
-
PairList pairs_;
// These will default to 0, but that should never be valid since the
// 0th index is the user supplied token/value, not an attribute.
diff --git a/chromium/net/cookies/parsed_cookie_unittest.cc b/chromium/net/cookies/parsed_cookie_unittest.cc
index e1e3f9beca7..fc7d206a340 100644
--- a/chromium/net/cookies/parsed_cookie_unittest.cc
+++ b/chromium/net/cookies/parsed_cookie_unittest.cc
@@ -467,7 +467,7 @@ TEST(ParsedCookieTest, SetSameSite) {
EXPECT_EQ("name=value", pc.ToCookieLine());
EXPECT_EQ(CookieSameSite::DEFAULT_MODE, pc.SameSite());
- // Test each priority, expect case-insensitive compare.
+ // Test each samesite directive, expect case-insensitive compare.
EXPECT_TRUE(pc.SetSameSite("strict"));
EXPECT_EQ("name=value; samesite=strict", pc.ToCookieLine());
EXPECT_EQ(CookieSameSite::STRICT_MODE, pc.SameSite());
@@ -483,24 +483,28 @@ TEST(ParsedCookieTest, SetSameSite) {
EXPECT_EQ(CookieSameSite::LAX_MODE, pc.SameSite());
EXPECT_TRUE(pc.IsValid());
+ // Remove the SameSite attribute.
EXPECT_TRUE(pc.SetSameSite(""));
EXPECT_EQ("name=value", pc.ToCookieLine());
EXPECT_EQ(CookieSameSite::DEFAULT_MODE, pc.SameSite());
EXPECT_TRUE(pc.IsValid());
EXPECT_TRUE(pc.SetSameSite("Blah"));
- EXPECT_FALSE(pc.IsValid());
+ EXPECT_EQ("name=value; samesite=Blah", pc.ToCookieLine());
+ EXPECT_EQ(CookieSameSite::NO_RESTRICTION, pc.SameSite());
+ EXPECT_TRUE(pc.IsValid());
}
-TEST(ParsedCookieTest, InvalidSameSiteValue) {
+TEST(ParsedCookieTest, SameSiteValues) {
struct TestCase {
const char* cookie;
bool valid;
CookieSameSite mode;
} cases[]{{"n=v; samesite=strict", true, CookieSameSite::STRICT_MODE},
{"n=v; samesite=lax", true, CookieSameSite::LAX_MODE},
- {"n=v; samesite=boo", false, CookieSameSite::DEFAULT_MODE},
- {"n=v; samesite", false, CookieSameSite::DEFAULT_MODE}};
+ {"n=v; samesite=boo", true, CookieSameSite::NO_RESTRICTION},
+ {"n=v; samesite", true, CookieSameSite::NO_RESTRICTION},
+ {"n=v", true, CookieSameSite::DEFAULT_MODE}};
for (const auto& test : cases) {
SCOPED_TRACE(test.cookie);
diff --git a/chromium/net/data/gencerts/__init__.py b/chromium/net/data/gencerts/__init__.py
index a7e82b57760..d1f8ef2ea7c 100755
--- a/chromium/net/data/gencerts/__init__.py
+++ b/chromium/net/data/gencerts/__init__.py
@@ -250,6 +250,12 @@ class Certificate(object):
return self.config.get_section('req_ext')
+ def get_subject(self):
+ """Returns the configuration section responsible for the subject of the
+ certificate. This can be used to alter the subject to be more complex."""
+ return self.config.get_section('req_dn')
+
+
def get_path(self, suffix):
"""Forms a path to an output file for this certificate, containing the
indicated suffix. The certificate's name will be used as its basis."""
diff --git a/chromium/net/data/gencerts/openssl_conf.py b/chromium/net/data/gencerts/openssl_conf.py
index fe1838d6638..c12771cc0be 100755
--- a/chromium/net/data/gencerts/openssl_conf.py
+++ b/chromium/net/data/gencerts/openssl_conf.py
@@ -105,6 +105,11 @@ class Section(object):
return
+ def clear_properties(self):
+ """Removes all configured properties."""
+ self.properties = []
+
+
def write_to(self, out):
"""Outputs the section in the format used by .cnf files"""
out.write('[%s]\n' % (self.name))
diff --git a/chromium/net/data/ov_name_constraints/README.md b/chromium/net/data/ov_name_constraints/README.md
new file mode 100644
index 00000000000..b1e26afb9b2
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/README.md
@@ -0,0 +1,7 @@
+This directory contains files to support //components/certificate_transparency,
+particularly those policies and preferences related to disabling Certificate
+Transparency support for OV-constrained certificates.
+
+It exists in //net/data due to its close coupling to the certificate generation
+scripts and the existing net_unittests_bundle_data used extensively for
+certificate tests.
diff --git a/chromium/net/data/ov_name_constraints/generate-certs.py b/chromium/net/data/ov_name_constraints/generate-certs.py
new file mode 100755
index 00000000000..a99036db8e2
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/generate-certs.py
@@ -0,0 +1,201 @@
+#!/usr/bin/env python
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os
+import sys
+sys.path += ['..']
+
+import gencerts
+
+gencerts.set_default_validity_range(gencerts.JANUARY_1_2015_UTC,
+ gencerts.JANUARY_1_2021_UTC)
+
+# Generate the keys -- the same key is used between all intermediate certs and
+# between all leaf certs.
+root_key = gencerts.get_or_generate_rsa_key(2048,
+ gencerts.create_key_path('root'))
+i_key = gencerts.get_or_generate_rsa_key(2048, gencerts.create_key_path('i'))
+leaf_key = gencerts.get_or_generate_rsa_key(2048,
+ gencerts.create_key_path('leaf'))
+
+# Self-signed root certificate.
+root = gencerts.create_self_signed_root_certificate('Root')
+root.set_key(root_key)
+# Preserve the ordering of the distinguished name in CSRs when issuing
+# certificates. This must be in the BASE ('ca') section.
+root.config.get_section('ca').set_property('preserve', 'yes')
+gencerts.write_string_to_file(root.get_cert_pem(), 'root.pem')
+
+## Create intermediate certs
+
+# Intermediate with two organizations as two distinct SETs, ordered O1 and O2
+i_o1_o2 = gencerts.create_intermediate_certificate('I1', root)
+i_o1_o2.set_key(i_key)
+dn = i_o1_o2.get_subject()
+dn.clear_properties()
+dn.add_property('0.organizationName', 'O1')
+dn.add_property('1.organizationName', 'O2')
+gencerts.write_string_to_file(i_o1_o2.get_cert_pem(), 'int-o1-o2.pem')
+
+# Intermediate with two organizations as two distinct SETs, ordered O2 and O1
+i_o2_o1 = gencerts.create_intermediate_certificate('I2', root)
+i_o2_o1.set_key(i_key)
+dn = i_o2_o1.get_subject()
+dn.clear_properties()
+dn.add_property('0.organizationName', 'O2')
+dn.add_property('1.organizationName', 'O1')
+gencerts.write_string_to_file(i_o2_o1.get_cert_pem(), 'int-o2-o1.pem')
+
+# Intermediate with a single organization name, O3
+i_o3 = gencerts.create_intermediate_certificate('I3', root)
+i_o3.set_key(i_key)
+dn = i_o3.get_subject()
+dn.clear_properties()
+dn.add_property('organizationName', 'O3')
+gencerts.write_string_to_file(i_o3.get_cert_pem(), 'int-o3.pem')
+
+# Intermediate with a single organization name, O1, encoded as BMPString
+i_bmp_o1 = gencerts.create_intermediate_certificate('I4', root)
+i_bmp_o1.set_key(i_key)
+# 2048 = 0x0800, B_ASN1_BMPSTRING
+i_bmp_o1.config.get_section('req').set_property('string_mask', 'MASK:2048')
+i_bmp_o1.config.get_section('req').set_property('utf8', 'no')
+dn = i_bmp_o1.get_subject()
+dn.clear_properties()
+dn.add_property('organizationName', 'O1')
+gencerts.write_string_to_file(i_bmp_o1.get_cert_pem(), 'int-bmp-o1.pem')
+
+# Intermediate with two organizations as a single SET, ordered O1 and O2
+i_o1_plus_o2 = gencerts.create_intermediate_certificate('I5', root)
+i_o1_plus_o2.set_key(i_key)
+dn = i_o1_plus_o2.get_subject()
+dn.clear_properties()
+dn.add_property('organizationName', 'O1')
+dn.add_property('+organizationName', 'O2')
+gencerts.write_string_to_file(i_o1_plus_o2.get_cert_pem(), 'int-o1-plus-o2.pem')
+
+# Intermediate with no organization name (not BR compliant)
+i_cn = gencerts.create_intermediate_certificate('I6', root)
+i_cn.set_key(i_key)
+dn = i_cn.get_subject()
+dn.clear_properties()
+dn.add_property('commonName', 'O1')
+gencerts.write_string_to_file(i_cn.get_cert_pem(), 'int-cn.pem')
+
+## Create name-constrained intermediate certs
+
+# Create a name-constrained intermediate that has O1 as a permitted
+# organizationName in a directoryName nameConstraint
+nc_permit_o1 = gencerts.create_intermediate_certificate('NC1', root)
+nc_permit_o1.set_key(i_key)
+nc_permit_o1.get_extensions().set_property('nameConstraints', 'critical,@nc')
+nc = nc_permit_o1.config.get_section('nc')
+nc.add_property('permitted;dirName.1', 'nc_1')
+nc_1 = nc_permit_o1.config.get_section('nc_1')
+nc_1.add_property('organizationName', 'O1')
+gencerts.write_string_to_file(nc_permit_o1.get_cert_pem(),
+ 'nc-int-permit-o1.pem')
+
+# Create a name-constrained intermediate that has O1 as a permitted
+# organizationName, but encoded as a BMPString within a directoryName
+# nameConstraint
+nc_permit_bmp_o1 = gencerts.create_intermediate_certificate('NC2', root)
+nc_permit_bmp_o1.set_key(i_key)
+# 2048 = 0x0800, B_ASN1_BMPSTRING
+nc_permit_bmp_o1.config.get_section('req').set_property('string_mask',
+ 'MASK:2048')
+nc_permit_bmp_o1.config.get_section('req').set_property('utf8', 'no')
+nc = nc_permit_bmp_o1.config.get_section('nc')
+nc.add_property('permitted;dirName.1', 'nc_1')
+nc_1 = nc_permit_bmp_o1.config.get_section('nc_1')
+nc_1.add_property('organizationName', 'O1')
+gencerts.write_string_to_file(nc_permit_bmp_o1.get_cert_pem(),
+ 'nc-int-permit-bmp-o1.pem')
+
+# Create a name-constrained intermediate that has O1 as a permitted
+# commonName in a directoryName nameConstraint
+nc_permit_cn = gencerts.create_intermediate_certificate('NC3', root)
+nc_permit_cn.set_key(i_key)
+nc_permit_cn.get_extensions().set_property('nameConstraints', 'critical,@nc')
+nc = nc_permit_cn.config.get_section('nc')
+nc.add_property('permitted;dirName.1', 'nc_1')
+nc_1 = nc_permit_cn.config.get_section('nc_1')
+nc_1.add_property('commonName', 'O1')
+gencerts.write_string_to_file(nc_permit_cn.get_cert_pem(),
+ 'nc-int-permit-cn.pem')
+
+# Create a name-constrainted intermediate that has O1 as an excluded
+# commonName in a directoryName nameConstraint
+nc_exclude_o1 = gencerts.create_intermediate_certificate('NC4', root)
+nc_exclude_o1.set_key(i_key)
+nc_exclude_o1.get_extensions().set_property('nameConstraints', 'critical,@nc')
+nc = nc_exclude_o1.config.get_section('nc')
+nc.add_property('excluded;dirName.1', 'nc_1')
+nc_1 = nc_exclude_o1.config.get_section('nc_1')
+nc_1.add_property('organizationName', 'O1')
+gencerts.write_string_to_file(nc_exclude_o1.get_cert_pem(),
+ 'nc-int-exclude-o1.pem')
+
+# Create a name-constrained intermediate that does not have a directoryName
+# nameConstraint
+nc_permit_dns = gencerts.create_intermediate_certificate('NC5', root)
+nc_permit_dns.set_key(i_key)
+nc_permit_dns.get_extensions().set_property('nameConstraints', 'critical,@nc')
+nc = nc_permit_dns.config.get_section('nc')
+nc.add_property('permitted;DNS.1', 'test.invalid')
+gencerts.write_string_to_file(nc_permit_dns.get_cert_pem(),
+ 'nc-int-permit-dns.pem')
+
+# Create a name-constrained intermediate with multiple directoryName
+# nameConstraints
+nc_permit_o2_o1_o3 = gencerts.create_intermediate_certificate('NC6', root)
+nc_permit_o2_o1_o3.set_key(i_key)
+nc_permit_o2_o1_o3.get_extensions().set_property('nameConstraints',
+ 'critical,@nc')
+nc = nc_permit_o2_o1_o3.config.get_section('nc')
+nc.add_property('permitted;dirName.1', 'nc_1')
+nc_1 = nc_permit_o2_o1_o3.config.get_section('nc_1')
+nc_1.add_property('organizationName', 'O2')
+
+nc.add_property('permitted;dirName.2', 'nc_2')
+nc_2 = nc_permit_o2_o1_o3.config.get_section('nc_2')
+nc_2.add_property('organizationName', 'O1')
+
+nc.add_property('permitted;dirName.3', 'nc_3')
+nc_3 = nc_permit_o2_o1_o3.config.get_section('nc_3')
+nc_3.add_property('organizationName', 'O3')
+
+gencerts.write_string_to_file(nc_permit_o2_o1_o3.get_cert_pem(),
+ 'nc-int-permit-o2-o1-o3.pem')
+
+## Create leaf certs (note: The issuer name does not matter for these tests)
+
+# Leaf missing an organization name
+leaf_no_o = gencerts.create_end_entity_certificate('L1', root)
+leaf_no_o.set_key(leaf_key)
+dn = leaf_no_o.get_subject()
+dn.clear_properties()
+dn.add_property('commonName', 'O1')
+gencerts.write_string_to_file(leaf_no_o.get_cert_pem(), 'leaf-no-o.pem')
+
+# Leaf with two organizations as two distinct SETs, ordered O1 and O2
+leaf_o1_o2 = gencerts.create_end_entity_certificate('L2', root)
+leaf_o1_o2.set_key(leaf_key)
+dn = leaf_o1_o2.get_subject()
+dn.clear_properties()
+dn.add_property('0.organizationName', 'O1')
+dn.add_property('1.organizationName', 'O2')
+dn.add_property('commonName', 'Leaf')
+gencerts.write_string_to_file(leaf_o1_o2.get_cert_pem(), 'leaf-o1-o2.pem')
+
+# Leaf with a single organization name, O1
+leaf_o1 = gencerts.create_end_entity_certificate('L3', root)
+leaf_o1.set_key(leaf_key)
+dn = leaf_o1.get_subject()
+dn.clear_properties()
+dn.add_property('0.organizationName', 'O1')
+dn.add_property('commonName', 'Leaf')
+gencerts.write_string_to_file(leaf_o1.get_cert_pem(), 'leaf-o1.pem')
+
diff --git a/chromium/net/data/ov_name_constraints/int-bmp-o1.pem b/chromium/net/data/ov_name_constraints/int-bmp-o1.pem
new file mode 100644
index 00000000000..95120656244
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/int-bmp-o1.pem
@@ -0,0 +1,88 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 5 (0x5)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2021 GMT
+ Subject: O=\x00O\x001
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d5:ac:80:14:b9:d2:78:ad:43:c8:51:69:3e:98:
+ 7f:bd:a8:57:a3:65:28:19:6d:44:e5:6a:5d:f7:c2:
+ 31:ed:4e:66:a9:f1:d2:9d:36:b6:b9:98:3f:d8:54:
+ d2:e9:77:3a:fb:9f:d5:c9:f9:c9:df:5e:b7:da:34:
+ 42:f6:cb:e3:66:e0:b7:5a:82:9b:77:20:0f:b1:17:
+ 1e:2a:70:62:d2:67:9b:a0:54:f2:1b:a4:9f:06:b7:
+ bb:af:5a:6f:55:b1:7e:f8:20:cb:ed:e4:55:d8:18:
+ cb:4f:0e:c3:c4:5d:13:fc:fd:d7:b1:1c:c5:58:81:
+ cf:e9:56:78:67:78:aa:fe:06:29:9e:34:3e:4b:fe:
+ 7e:ec:22:16:15:d6:2b:c3:6e:17:23:42:1b:28:2e:
+ 21:13:31:8b:8a:33:23:a2:67:f6:23:bc:f2:68:9b:
+ 71:92:92:7f:23:09:53:96:67:3c:fe:c2:81:88:9f:
+ 00:55:93:4d:b3:e7:02:01:13:48:4b:34:12:45:6e:
+ 48:6a:88:21:33:ff:5a:03:49:56:a2:69:64:97:a4:
+ 53:0e:90:73:84:c6:b8:28:b0:5b:c0:67:85:fd:9a:
+ 25:f2:cf:0e:79:24:78:20:80:f0:2c:ae:46:8e:c5:
+ cf:29:be:7f:f5:7d:73:6d:aa:0b:10:59:4f:d6:46:
+ f1:bf
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 9D:44:AA:2B:9B:4C:66:4C:20:C5:32:B2:EA:08:13:13:69:17:49:B1
+ X509v3 Authority Key Identifier:
+ keyid:FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Root.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Root.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ Signature Algorithm: sha256WithRSAEncryption
+ 8b:c5:75:75:94:dd:8c:24:f7:e4:c5:fb:b3:06:5f:84:1c:29:
+ b7:1f:3d:89:ef:5e:25:3e:cf:43:fb:ad:e1:84:d1:53:af:59:
+ 66:0e:f4:fd:f8:04:bc:2e:74:96:04:0e:af:10:8e:4c:d9:6d:
+ 2c:d9:f5:8e:b6:de:72:ff:54:ff:af:7d:41:f3:4b:f6:e0:e8:
+ 06:e8:c9:92:4e:0f:f2:9a:95:58:6f:a1:cf:2e:45:ca:77:f4:
+ 69:48:45:4e:0b:a9:cb:c9:25:da:84:33:a2:e5:7c:61:b6:aa:
+ 1f:cb:b1:f3:1a:30:b4:09:85:7c:34:b3:83:bd:9b:d5:40:8e:
+ 3c:62:56:e9:c3:f0:72:57:1d:00:98:2e:8a:00:75:fd:3a:a9:
+ 7f:63:80:64:d8:03:25:09:a7:89:ce:39:54:13:86:af:17:f1:
+ f0:63:84:c1:e1:7f:67:f4:77:ee:eb:a8:bf:62:5e:df:51:14:
+ e4:14:3e:53:eb:f9:75:c6:a6:c7:e8:9b:6f:bb:fe:c8:9c:4c:
+ 95:0b:22:8c:06:0f:a7:91:72:a6:ee:6d:bf:03:a2:05:de:68:
+ e6:d3:00:b4:73:54:34:5f:f9:f3:8f:26:be:a6:6d:4f:37:23:
+ 2b:17:b6:04:a7:01:e9:39:88:36:79:a3:63:92:dd:22:25:54:
+ 11:01:84:7f
+-----BEGIN CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBBTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowDzENMAsGA1UECh4EAE8A
+MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANWsgBS50nitQ8hRaT6Y
+f72oV6NlKBltROVqXffCMe1OZqnx0p02trmYP9hU0ul3Ovuf1cn5yd9et9o0QvbL
+42bgt1qCm3cgD7EXHipwYtJnm6BU8huknwa3u69ab1Wxfvggy+3kVdgYy08Ow8Rd
+E/z917EcxViBz+lWeGd4qv4GKZ40Pkv+fuwiFhXWK8NuFyNCGyguIRMxi4ozI6Jn
+9iO88mibcZKSfyMJU5ZnPP7CgYifAFWTTbPnAgETSEs0EkVuSGqIITP/WgNJVqJp
+ZJekUw6Qc4TGuCiwW8Bnhf2aJfLPDnkkeCCA8CyuRo7Fzym+f/V9c22qCxBZT9ZG
+8b8CAwEAAaOByzCByDAdBgNVHQ4EFgQUnUSqK5tMZkwgxTKy6ggTE2kXSbEwHwYD
+VR0jBBgwFoAU/4v8pWk2L2I71BvtWC/pdz0pgYMwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCLxXV1lN2M
+JPfkxfuzBl+EHCm3Hz2J714lPs9D+63hhNFTr1lmDvT9+AS8LnSWBA6vEI5M2W0s
+2fWOtt5y/1T/r31B80v24OgG6MmSTg/ympVYb6HPLkXKd/RpSEVOC6nLySXahDOi
+5Xxhtqofy7HzGjC0CYV8NLODvZvVQI48Ylbpw/ByVx0AmC6KAHX9Oql/Y4Bk2AMl
+CaeJzjlUE4avF/HwY4TB4X9n9Hfu66i/Yl7fURTkFD5T6/l1xqbH6Jtvu/7InEyV
+CyKMBg+nkXKm7m2/A6IF3mjm0wC0c1Q0X/nzjya+pm1PNyMrF7YEpwHpOYg2eaNj
+kt0iJVQRAYR/
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ov_name_constraints/int-cn.pem b/chromium/net/data/ov_name_constraints/int-cn.pem
new file mode 100644
index 00000000000..aaee1338c17
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/int-cn.pem
@@ -0,0 +1,88 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 7 (0x7)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2021 GMT
+ Subject: CN=O1
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d5:ac:80:14:b9:d2:78:ad:43:c8:51:69:3e:98:
+ 7f:bd:a8:57:a3:65:28:19:6d:44:e5:6a:5d:f7:c2:
+ 31:ed:4e:66:a9:f1:d2:9d:36:b6:b9:98:3f:d8:54:
+ d2:e9:77:3a:fb:9f:d5:c9:f9:c9:df:5e:b7:da:34:
+ 42:f6:cb:e3:66:e0:b7:5a:82:9b:77:20:0f:b1:17:
+ 1e:2a:70:62:d2:67:9b:a0:54:f2:1b:a4:9f:06:b7:
+ bb:af:5a:6f:55:b1:7e:f8:20:cb:ed:e4:55:d8:18:
+ cb:4f:0e:c3:c4:5d:13:fc:fd:d7:b1:1c:c5:58:81:
+ cf:e9:56:78:67:78:aa:fe:06:29:9e:34:3e:4b:fe:
+ 7e:ec:22:16:15:d6:2b:c3:6e:17:23:42:1b:28:2e:
+ 21:13:31:8b:8a:33:23:a2:67:f6:23:bc:f2:68:9b:
+ 71:92:92:7f:23:09:53:96:67:3c:fe:c2:81:88:9f:
+ 00:55:93:4d:b3:e7:02:01:13:48:4b:34:12:45:6e:
+ 48:6a:88:21:33:ff:5a:03:49:56:a2:69:64:97:a4:
+ 53:0e:90:73:84:c6:b8:28:b0:5b:c0:67:85:fd:9a:
+ 25:f2:cf:0e:79:24:78:20:80:f0:2c:ae:46:8e:c5:
+ cf:29:be:7f:f5:7d:73:6d:aa:0b:10:59:4f:d6:46:
+ f1:bf
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 9D:44:AA:2B:9B:4C:66:4C:20:C5:32:B2:EA:08:13:13:69:17:49:B1
+ X509v3 Authority Key Identifier:
+ keyid:FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Root.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Root.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ Signature Algorithm: sha256WithRSAEncryption
+ 6e:8f:9c:09:b3:53:32:b8:34:56:41:d4:ea:aa:bc:1e:9f:16:
+ 48:3f:3d:75:b7:96:f9:2d:17:e9:73:1a:fa:ff:de:98:f9:ce:
+ 01:e8:b8:00:ff:06:27:a1:16:a8:63:56:b3:79:98:94:6d:0c:
+ af:9c:bf:1e:c4:a4:b8:1d:f2:fa:9d:a2:50:e7:5d:0d:ab:7e:
+ 78:df:94:58:06:37:96:13:be:39:f8:19:73:8d:21:cf:0c:64:
+ 68:ba:ce:f2:b6:19:3a:af:3d:1d:a6:55:bd:6e:a9:2b:fd:d2:
+ 8c:e7:b6:b0:d6:fa:61:49:0b:92:2b:11:73:aa:60:57:89:c3:
+ 0f:0c:c2:d1:a2:43:a2:1b:9c:4c:f6:af:dd:44:a9:b5:94:c5:
+ bf:ab:6d:ba:ca:b8:91:a7:e3:14:5d:50:a3:89:95:0f:3b:df:
+ f8:33:e1:49:28:19:82:84:37:fe:ba:ba:99:be:d3:10:4c:18:
+ 7a:86:92:da:16:00:18:ec:5b:ff:f0:ec:e0:72:da:e4:a9:8e:
+ 89:8c:d7:ec:68:b3:9a:43:da:78:84:47:37:d2:6d:a5:54:ba:
+ 20:6e:92:1e:72:f4:1a:d9:f3:38:9e:8a:e5:45:2b:1b:f8:97:
+ 98:bb:4c:6a:e3:57:30:b5:5d:34:0e:5d:d6:a3:4d:8e:37:fa:
+ e3:4c:b0:70
+-----BEGIN CERTIFICATE-----
+MIIDYzCCAkugAwIBAgIBBzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowDTELMAkGA1UEAwwCTzEw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVrIAUudJ4rUPIUWk+mH+9
+qFejZSgZbUTlal33wjHtTmap8dKdNra5mD/YVNLpdzr7n9XJ+cnfXrfaNEL2y+Nm
+4Ldagpt3IA+xFx4qcGLSZ5ugVPIbpJ8Gt7uvWm9VsX74IMvt5FXYGMtPDsPEXRP8
+/dexHMVYgc/pVnhneKr+BimeND5L/n7sIhYV1ivDbhcjQhsoLiETMYuKMyOiZ/Yj
+vPJom3GSkn8jCVOWZzz+woGInwBVk02z5wIBE0hLNBJFbkhqiCEz/1oDSVaiaWSX
+pFMOkHOExrgosFvAZ4X9miXyzw55JHgggPAsrkaOxc8pvn/1fXNtqgsQWU/WRvG/
+AgMBAAGjgcswgcgwHQYDVR0OBBYEFJ1EqiubTGZMIMUysuoIExNpF0mxMB8GA1Ud
+IwQYMBaAFP+L/KVpNi9iO9Qb7Vgv6Xc9KYGDMDcGCCsGAQUFBwEBBCswKTAnBggr
+BgEFBQcwAoYbaHR0cDovL3VybC1mb3ItYWlhL1Jvb3QuY2VyMCwGA1UdHwQlMCMw
+IaAfoB2GG2h0dHA6Ly91cmwtZm9yLWNybC9Sb290LmNybDAOBgNVHQ8BAf8EBAMC
+AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAbo+cCbNTMrg0
+VkHU6qq8Hp8WSD89dbeW+S0X6XMa+v/emPnOAei4AP8GJ6EWqGNWs3mYlG0Mr5y/
+HsSkuB3y+p2iUOddDat+eN+UWAY3lhO+OfgZc40hzwxkaLrO8rYZOq89HaZVvW6p
+K/3SjOe2sNb6YUkLkisRc6pgV4nDDwzC0aJDohucTPav3USptZTFv6ttusq4kafj
+FF1Qo4mVDzvf+DPhSSgZgoQ3/rq6mb7TEEwYeoaS2hYAGOxb//Ds4HLa5KmOiYzX
+7GizmkPaeIRHN9JtpVS6IG6SHnL0GtnzOJ6K5UUrG/iXmLtMauNXMLVdNA5d1qNN
+jjf640ywcA==
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ov_name_constraints/int-o1-o2.pem b/chromium/net/data/ov_name_constraints/int-o1-o2.pem
new file mode 100644
index 00000000000..4810ab8b619
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/int-o1-o2.pem
@@ -0,0 +1,88 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 2 (0x2)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2021 GMT
+ Subject: O=O1, O=O2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d5:ac:80:14:b9:d2:78:ad:43:c8:51:69:3e:98:
+ 7f:bd:a8:57:a3:65:28:19:6d:44:e5:6a:5d:f7:c2:
+ 31:ed:4e:66:a9:f1:d2:9d:36:b6:b9:98:3f:d8:54:
+ d2:e9:77:3a:fb:9f:d5:c9:f9:c9:df:5e:b7:da:34:
+ 42:f6:cb:e3:66:e0:b7:5a:82:9b:77:20:0f:b1:17:
+ 1e:2a:70:62:d2:67:9b:a0:54:f2:1b:a4:9f:06:b7:
+ bb:af:5a:6f:55:b1:7e:f8:20:cb:ed:e4:55:d8:18:
+ cb:4f:0e:c3:c4:5d:13:fc:fd:d7:b1:1c:c5:58:81:
+ cf:e9:56:78:67:78:aa:fe:06:29:9e:34:3e:4b:fe:
+ 7e:ec:22:16:15:d6:2b:c3:6e:17:23:42:1b:28:2e:
+ 21:13:31:8b:8a:33:23:a2:67:f6:23:bc:f2:68:9b:
+ 71:92:92:7f:23:09:53:96:67:3c:fe:c2:81:88:9f:
+ 00:55:93:4d:b3:e7:02:01:13:48:4b:34:12:45:6e:
+ 48:6a:88:21:33:ff:5a:03:49:56:a2:69:64:97:a4:
+ 53:0e:90:73:84:c6:b8:28:b0:5b:c0:67:85:fd:9a:
+ 25:f2:cf:0e:79:24:78:20:80:f0:2c:ae:46:8e:c5:
+ cf:29:be:7f:f5:7d:73:6d:aa:0b:10:59:4f:d6:46:
+ f1:bf
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 9D:44:AA:2B:9B:4C:66:4C:20:C5:32:B2:EA:08:13:13:69:17:49:B1
+ X509v3 Authority Key Identifier:
+ keyid:FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Root.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Root.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ Signature Algorithm: sha256WithRSAEncryption
+ 6c:a0:aa:88:e0:41:66:d8:72:4a:45:2e:55:07:c8:c6:0c:10:
+ 37:1f:94:07:fb:88:58:9f:75:55:4f:92:06:d9:53:73:2d:b0:
+ 7d:ae:d7:b1:e4:03:e6:67:ed:eb:ec:3b:1a:0e:d8:74:66:86:
+ 76:e1:b4:17:23:64:2f:34:11:ed:7e:21:be:0a:f9:7f:a5:ba:
+ a8:dc:f5:1c:89:8e:d5:96:e5:db:64:a9:60:09:d3:be:b2:50:
+ b7:4c:bb:1d:8a:26:33:af:3a:43:59:32:84:81:b2:7f:3c:fd:
+ 26:67:da:39:ca:e6:f1:6a:6f:ad:86:a7:4d:32:cc:5b:c0:f8:
+ 53:3e:e4:9e:9a:43:a7:4a:3d:e2:72:26:0a:4e:27:04:03:eb:
+ 76:f2:ae:c5:9d:f2:72:52:9d:41:0a:9c:ea:29:00:54:c8:36:
+ 5d:79:55:74:91:48:3d:cc:1e:66:fa:b2:88:2d:27:74:32:d3:
+ ff:3f:87:e9:47:1f:84:ce:92:7e:a5:e2:9b:58:f2:90:25:9e:
+ e9:6e:3d:f8:b5:6f:c4:c1:e5:e2:83:f4:eb:9a:1e:63:5f:46:
+ 55:72:af:46:88:a0:ff:62:f8:cd:fc:ef:8f:82:1b:f2:aa:a1:
+ 6f:cd:70:0a:77:9e:18:b1:d9:11:7f:d3:65:84:1a:06:2e:5d:
+ 67:8f:b1:aa
+-----BEGIN CERTIFICATE-----
+MIIDcDCCAligAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowGjELMAkGA1UECgwCTzEx
+CzAJBgNVBAoMAk8yMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1ayA
+FLnSeK1DyFFpPph/vahXo2UoGW1E5Wpd98Ix7U5mqfHSnTa2uZg/2FTS6Xc6+5/V
+yfnJ31632jRC9svjZuC3WoKbdyAPsRceKnBi0meboFTyG6SfBre7r1pvVbF++CDL
+7eRV2BjLTw7DxF0T/P3XsRzFWIHP6VZ4Z3iq/gYpnjQ+S/5+7CIWFdYrw24XI0Ib
+KC4hEzGLijMjomf2I7zyaJtxkpJ/IwlTlmc8/sKBiJ8AVZNNs+cCARNISzQSRW5I
+aoghM/9aA0lWomlkl6RTDpBzhMa4KLBbwGeF/Zol8s8OeSR4IIDwLK5GjsXPKb5/
+9X1zbaoLEFlP1kbxvwIDAQABo4HLMIHIMB0GA1UdDgQWBBSdRKorm0xmTCDFMrLq
+CBMTaRdJsTAfBgNVHSMEGDAWgBT/i/ylaTYvYjvUG+1YL+l3PSmBgzA3BggrBgEF
+BQcBAQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNl
+cjAsBgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmww
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD
+ggEBAGygqojgQWbYckpFLlUHyMYMEDcflAf7iFifdVVPkgbZU3MtsH2u17HkA+Zn
+7evsOxoO2HRmhnbhtBcjZC80Ee1+Ib4K+X+luqjc9RyJjtWW5dtkqWAJ076yULdM
+ux2KJjOvOkNZMoSBsn88/SZn2jnK5vFqb62Gp00yzFvA+FM+5J6aQ6dKPeJyJgpO
+JwQD63byrsWd8nJSnUEKnOopAFTINl15VXSRSD3MHmb6sogtJ3Qy0/8/h+lHH4TO
+kn6l4ptY8pAlnuluPfi1b8TB5eKD9OuaHmNfRlVyr0aIoP9i+M3874+CG/KqoW/N
+cAp3nhix2RF/02WEGgYuXWePsao=
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ov_name_constraints/int-o1-plus-o2.pem b/chromium/net/data/ov_name_constraints/int-o1-plus-o2.pem
new file mode 100644
index 00000000000..8d167f079d8
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/int-o1-plus-o2.pem
@@ -0,0 +1,88 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 6 (0x6)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2021 GMT
+ Subject: O=O1, O=O2
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d5:ac:80:14:b9:d2:78:ad:43:c8:51:69:3e:98:
+ 7f:bd:a8:57:a3:65:28:19:6d:44:e5:6a:5d:f7:c2:
+ 31:ed:4e:66:a9:f1:d2:9d:36:b6:b9:98:3f:d8:54:
+ d2:e9:77:3a:fb:9f:d5:c9:f9:c9:df:5e:b7:da:34:
+ 42:f6:cb:e3:66:e0:b7:5a:82:9b:77:20:0f:b1:17:
+ 1e:2a:70:62:d2:67:9b:a0:54:f2:1b:a4:9f:06:b7:
+ bb:af:5a:6f:55:b1:7e:f8:20:cb:ed:e4:55:d8:18:
+ cb:4f:0e:c3:c4:5d:13:fc:fd:d7:b1:1c:c5:58:81:
+ cf:e9:56:78:67:78:aa:fe:06:29:9e:34:3e:4b:fe:
+ 7e:ec:22:16:15:d6:2b:c3:6e:17:23:42:1b:28:2e:
+ 21:13:31:8b:8a:33:23:a2:67:f6:23:bc:f2:68:9b:
+ 71:92:92:7f:23:09:53:96:67:3c:fe:c2:81:88:9f:
+ 00:55:93:4d:b3:e7:02:01:13:48:4b:34:12:45:6e:
+ 48:6a:88:21:33:ff:5a:03:49:56:a2:69:64:97:a4:
+ 53:0e:90:73:84:c6:b8:28:b0:5b:c0:67:85:fd:9a:
+ 25:f2:cf:0e:79:24:78:20:80:f0:2c:ae:46:8e:c5:
+ cf:29:be:7f:f5:7d:73:6d:aa:0b:10:59:4f:d6:46:
+ f1:bf
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 9D:44:AA:2B:9B:4C:66:4C:20:C5:32:B2:EA:08:13:13:69:17:49:B1
+ X509v3 Authority Key Identifier:
+ keyid:FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Root.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Root.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ Signature Algorithm: sha256WithRSAEncryption
+ c4:88:91:87:65:61:eb:c1:19:a7:69:2b:c6:d9:82:d3:a3:14:
+ 65:e1:5b:fd:a4:cf:63:6c:1a:a0:ad:52:13:d6:88:69:33:6f:
+ be:91:df:34:e4:c1:2e:b0:27:b3:56:e1:4a:5a:50:34:68:4a:
+ d7:bd:fb:b8:c1:3d:1e:05:71:c6:c5:4f:79:40:6e:73:ee:5d:
+ 11:81:d4:0c:c3:ac:ba:32:ea:bf:cf:34:6b:6c:e7:c9:40:c0:
+ e0:e9:9d:33:2c:d7:dd:15:b2:67:9d:9c:8f:7d:8a:54:a6:a3:
+ d0:3d:54:76:61:ef:98:e8:f9:3f:ce:4d:9c:29:4a:44:ca:91:
+ f0:b6:18:2c:72:d3:12:b3:7e:e8:c2:93:d5:8c:7a:1e:7c:b2:
+ 08:ae:21:92:91:8e:1f:de:57:55:27:7d:a3:b8:e0:bd:4d:6b:
+ a5:a3:f4:35:5d:b7:05:74:b2:9c:bc:e0:46:0c:c8:7f:45:db:
+ 73:03:d4:f7:93:9e:12:f4:25:4b:9f:b6:c8:85:3d:38:9d:da:
+ 36:69:d2:ce:4f:dd:4b:f2:a8:49:f5:74:b4:27:5d:a1:29:32:
+ 7d:0e:7f:5e:05:5d:bb:f1:04:6b:77:6f:70:b0:9a:50:62:6b:
+ b5:6d:21:d8:3c:48:83:f4:cd:7f:39:f8:a3:67:ee:c2:22:96:
+ 15:49:3a:44
+-----BEGIN CERTIFICATE-----
+MIIDbjCCAlagAwIBAgIBBjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowGDEWMAkGA1UECgwCTzEw
+CQYDVQQKDAJPMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANWsgBS5
+0nitQ8hRaT6Yf72oV6NlKBltROVqXffCMe1OZqnx0p02trmYP9hU0ul3Ovuf1cn5
+yd9et9o0QvbL42bgt1qCm3cgD7EXHipwYtJnm6BU8huknwa3u69ab1Wxfvggy+3k
+VdgYy08Ow8RdE/z917EcxViBz+lWeGd4qv4GKZ40Pkv+fuwiFhXWK8NuFyNCGygu
+IRMxi4ozI6Jn9iO88mibcZKSfyMJU5ZnPP7CgYifAFWTTbPnAgETSEs0EkVuSGqI
+ITP/WgNJVqJpZJekUw6Qc4TGuCiwW8Bnhf2aJfLPDnkkeCCA8CyuRo7Fzym+f/V9
+c22qCxBZT9ZG8b8CAwEAAaOByzCByDAdBgNVHQ4EFgQUnUSqK5tMZkwgxTKy6ggT
+E2kXSbEwHwYDVR0jBBgwFoAU/4v8pWk2L2I71BvtWC/pdz0pgYMwNwYIKwYBBQUH
+AQEEKzApMCcGCCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIw
+LAYDVR0fBCUwIzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4G
+A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IB
+AQDEiJGHZWHrwRmnaSvG2YLToxRl4Vv9pM9jbBqgrVIT1ohpM2++kd805MEusCez
+VuFKWlA0aErXvfu4wT0eBXHGxU95QG5z7l0RgdQMw6y6Muq/zzRrbOfJQMDg6Z0z
+LNfdFbJnnZyPfYpUpqPQPVR2Ye+Y6Pk/zk2cKUpEypHwthgsctMSs37owpPVjHoe
+fLIIriGSkY4f3ldVJ32juOC9TWulo/Q1XbcFdLKcvOBGDMh/RdtzA9T3k54S9CVL
+n7bIhT04ndo2adLOT91L8qhJ9XS0J12hKTJ9Dn9eBV278QRrd29wsJpQYmu1bSHY
+PEiD9M1/OfijZ+7CIpYVSTpE
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ov_name_constraints/int-o2-o1.pem b/chromium/net/data/ov_name_constraints/int-o2-o1.pem
new file mode 100644
index 00000000000..8ac802f3f15
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/int-o2-o1.pem
@@ -0,0 +1,88 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 3 (0x3)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2021 GMT
+ Subject: O=O2, O=O1
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d5:ac:80:14:b9:d2:78:ad:43:c8:51:69:3e:98:
+ 7f:bd:a8:57:a3:65:28:19:6d:44:e5:6a:5d:f7:c2:
+ 31:ed:4e:66:a9:f1:d2:9d:36:b6:b9:98:3f:d8:54:
+ d2:e9:77:3a:fb:9f:d5:c9:f9:c9:df:5e:b7:da:34:
+ 42:f6:cb:e3:66:e0:b7:5a:82:9b:77:20:0f:b1:17:
+ 1e:2a:70:62:d2:67:9b:a0:54:f2:1b:a4:9f:06:b7:
+ bb:af:5a:6f:55:b1:7e:f8:20:cb:ed:e4:55:d8:18:
+ cb:4f:0e:c3:c4:5d:13:fc:fd:d7:b1:1c:c5:58:81:
+ cf:e9:56:78:67:78:aa:fe:06:29:9e:34:3e:4b:fe:
+ 7e:ec:22:16:15:d6:2b:c3:6e:17:23:42:1b:28:2e:
+ 21:13:31:8b:8a:33:23:a2:67:f6:23:bc:f2:68:9b:
+ 71:92:92:7f:23:09:53:96:67:3c:fe:c2:81:88:9f:
+ 00:55:93:4d:b3:e7:02:01:13:48:4b:34:12:45:6e:
+ 48:6a:88:21:33:ff:5a:03:49:56:a2:69:64:97:a4:
+ 53:0e:90:73:84:c6:b8:28:b0:5b:c0:67:85:fd:9a:
+ 25:f2:cf:0e:79:24:78:20:80:f0:2c:ae:46:8e:c5:
+ cf:29:be:7f:f5:7d:73:6d:aa:0b:10:59:4f:d6:46:
+ f1:bf
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 9D:44:AA:2B:9B:4C:66:4C:20:C5:32:B2:EA:08:13:13:69:17:49:B1
+ X509v3 Authority Key Identifier:
+ keyid:FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Root.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Root.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ Signature Algorithm: sha256WithRSAEncryption
+ 1c:2a:00:f3:dc:1e:f2:14:2e:6c:5d:73:fe:64:8b:33:da:74:
+ 60:cc:aa:5a:86:a3:a1:35:53:f1:f1:66:47:50:db:42:30:cf:
+ 08:6f:fe:8f:f7:d9:f0:38:66:72:fa:b3:b0:a2:d7:00:11:03:
+ b8:2e:fe:8d:6c:fa:7e:f3:d8:a7:d2:b3:74:b0:18:72:94:08:
+ 82:b5:c5:71:5b:89:92:6d:36:fe:60:c2:7a:dd:1e:dc:80:2a:
+ 8d:4a:e0:ad:6e:d7:a3:dd:37:40:49:6e:61:7e:ac:9e:43:bd:
+ 43:f5:8d:6c:9d:97:a7:68:97:85:dd:72:71:90:17:d3:ca:24:
+ 64:d0:12:ed:5f:e2:2f:20:7c:c7:13:6f:99:e6:d3:e5:a0:06:
+ 04:a7:bc:6e:86:88:aa:3e:84:02:a9:09:69:b2:ac:d3:8b:8a:
+ 44:30:a1:89:99:92:23:e5:32:d4:ec:7b:2d:3b:87:55:6c:84:
+ e6:40:81:0f:3c:65:59:29:e0:b2:94:55:c2:81:41:21:fe:c3:
+ 4e:4c:76:22:29:75:02:9a:a1:f1:95:c4:3e:a3:36:e3:7a:c4:
+ 4d:6f:d3:38:a1:c6:b6:60:c7:4e:f1:dc:ec:9d:ab:af:d2:87:
+ cd:5f:06:a6:3d:e0:1a:fa:3d:fb:68:48:3b:2f:c6:43:d6:81:
+ e8:65:2c:c0
+-----BEGIN CERTIFICATE-----
+MIIDcDCCAligAwIBAgIBAzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowGjELMAkGA1UECgwCTzIx
+CzAJBgNVBAoMAk8xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1ayA
+FLnSeK1DyFFpPph/vahXo2UoGW1E5Wpd98Ix7U5mqfHSnTa2uZg/2FTS6Xc6+5/V
+yfnJ31632jRC9svjZuC3WoKbdyAPsRceKnBi0meboFTyG6SfBre7r1pvVbF++CDL
+7eRV2BjLTw7DxF0T/P3XsRzFWIHP6VZ4Z3iq/gYpnjQ+S/5+7CIWFdYrw24XI0Ib
+KC4hEzGLijMjomf2I7zyaJtxkpJ/IwlTlmc8/sKBiJ8AVZNNs+cCARNISzQSRW5I
+aoghM/9aA0lWomlkl6RTDpBzhMa4KLBbwGeF/Zol8s8OeSR4IIDwLK5GjsXPKb5/
+9X1zbaoLEFlP1kbxvwIDAQABo4HLMIHIMB0GA1UdDgQWBBSdRKorm0xmTCDFMrLq
+CBMTaRdJsTAfBgNVHSMEGDAWgBT/i/ylaTYvYjvUG+1YL+l3PSmBgzA3BggrBgEF
+BQcBAQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNl
+cjAsBgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmww
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD
+ggEBABwqAPPcHvIULmxdc/5kizPadGDMqlqGo6E1U/HxZkdQ20Iwzwhv/o/32fA4
+ZnL6s7Ci1wARA7gu/o1s+n7z2KfSs3SwGHKUCIK1xXFbiZJtNv5gwnrdHtyAKo1K
+4K1u16PdN0BJbmF+rJ5DvUP1jWydl6dol4XdcnGQF9PKJGTQEu1f4i8gfMcTb5nm
+0+WgBgSnvG6GiKo+hAKpCWmyrNOLikQwoYmZkiPlMtTsey07h1VshOZAgQ88ZVkp
+4LKUVcKBQSH+w05MdiIpdQKaofGVxD6jNuN6xE1v0zihxrZgx07x3Oydq6/Sh81f
+BqY94Br6PftoSDsvxkPWgehlLMA=
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ov_name_constraints/int-o3.pem b/chromium/net/data/ov_name_constraints/int-o3.pem
new file mode 100644
index 00000000000..23723f86f50
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/int-o3.pem
@@ -0,0 +1,88 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 4 (0x4)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2021 GMT
+ Subject: O=O3
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d5:ac:80:14:b9:d2:78:ad:43:c8:51:69:3e:98:
+ 7f:bd:a8:57:a3:65:28:19:6d:44:e5:6a:5d:f7:c2:
+ 31:ed:4e:66:a9:f1:d2:9d:36:b6:b9:98:3f:d8:54:
+ d2:e9:77:3a:fb:9f:d5:c9:f9:c9:df:5e:b7:da:34:
+ 42:f6:cb:e3:66:e0:b7:5a:82:9b:77:20:0f:b1:17:
+ 1e:2a:70:62:d2:67:9b:a0:54:f2:1b:a4:9f:06:b7:
+ bb:af:5a:6f:55:b1:7e:f8:20:cb:ed:e4:55:d8:18:
+ cb:4f:0e:c3:c4:5d:13:fc:fd:d7:b1:1c:c5:58:81:
+ cf:e9:56:78:67:78:aa:fe:06:29:9e:34:3e:4b:fe:
+ 7e:ec:22:16:15:d6:2b:c3:6e:17:23:42:1b:28:2e:
+ 21:13:31:8b:8a:33:23:a2:67:f6:23:bc:f2:68:9b:
+ 71:92:92:7f:23:09:53:96:67:3c:fe:c2:81:88:9f:
+ 00:55:93:4d:b3:e7:02:01:13:48:4b:34:12:45:6e:
+ 48:6a:88:21:33:ff:5a:03:49:56:a2:69:64:97:a4:
+ 53:0e:90:73:84:c6:b8:28:b0:5b:c0:67:85:fd:9a:
+ 25:f2:cf:0e:79:24:78:20:80:f0:2c:ae:46:8e:c5:
+ cf:29:be:7f:f5:7d:73:6d:aa:0b:10:59:4f:d6:46:
+ f1:bf
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 9D:44:AA:2B:9B:4C:66:4C:20:C5:32:B2:EA:08:13:13:69:17:49:B1
+ X509v3 Authority Key Identifier:
+ keyid:FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Root.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Root.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ Signature Algorithm: sha256WithRSAEncryption
+ 16:e4:f6:fc:13:d4:16:dc:42:5f:c4:9d:88:d6:c8:69:f4:86:
+ f3:4e:de:f5:ff:e4:05:46:22:a4:eb:b1:ce:1d:d7:6f:46:04:
+ d3:6c:e2:83:f7:be:a4:3e:c2:cc:51:ba:71:2e:6d:cd:8d:12:
+ 4e:be:36:60:5a:25:05:e9:d2:c6:8f:64:91:7a:b3:50:7c:dd:
+ c4:b7:5f:c4:c5:6f:58:3f:fb:fd:33:07:b6:4e:a6:25:0e:7e:
+ 48:9b:2a:a8:05:54:e0:6a:27:cb:ea:3e:40:42:9f:3f:a8:5b:
+ d2:62:17:f0:80:90:c2:dd:07:ff:5c:8f:08:37:c0:c5:41:78:
+ dc:be:7c:50:55:9b:42:f7:da:aa:b0:17:f4:e9:ed:58:e3:28:
+ a9:66:a8:df:72:cd:00:bc:8a:ff:a0:96:91:33:f3:72:28:ab:
+ 5e:72:e4:45:33:b8:c0:46:22:3d:96:be:3c:e5:2e:bf:72:0f:
+ a2:30:d2:b2:15:8c:c7:69:8b:16:dc:f9:17:fe:a1:fb:8b:7c:
+ 0c:94:24:54:78:b6:e8:a1:e9:2d:4b:d4:13:6b:01:42:ea:bc:
+ bc:ea:d1:5e:1b:c4:0b:a6:3c:df:2d:17:8b:2e:c6:44:ac:46:
+ 45:4e:28:c6:68:f4:34:a6:8b:a6:88:86:f5:e4:26:50:01:a0:
+ 1e:5e:72:66
+-----BEGIN CERTIFICATE-----
+MIIDYzCCAkugAwIBAgIBBDANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowDTELMAkGA1UECgwCTzMw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVrIAUudJ4rUPIUWk+mH+9
+qFejZSgZbUTlal33wjHtTmap8dKdNra5mD/YVNLpdzr7n9XJ+cnfXrfaNEL2y+Nm
+4Ldagpt3IA+xFx4qcGLSZ5ugVPIbpJ8Gt7uvWm9VsX74IMvt5FXYGMtPDsPEXRP8
+/dexHMVYgc/pVnhneKr+BimeND5L/n7sIhYV1ivDbhcjQhsoLiETMYuKMyOiZ/Yj
+vPJom3GSkn8jCVOWZzz+woGInwBVk02z5wIBE0hLNBJFbkhqiCEz/1oDSVaiaWSX
+pFMOkHOExrgosFvAZ4X9miXyzw55JHgggPAsrkaOxc8pvn/1fXNtqgsQWU/WRvG/
+AgMBAAGjgcswgcgwHQYDVR0OBBYEFJ1EqiubTGZMIMUysuoIExNpF0mxMB8GA1Ud
+IwQYMBaAFP+L/KVpNi9iO9Qb7Vgv6Xc9KYGDMDcGCCsGAQUFBwEBBCswKTAnBggr
+BgEFBQcwAoYbaHR0cDovL3VybC1mb3ItYWlhL1Jvb3QuY2VyMCwGA1UdHwQlMCMw
+IaAfoB2GG2h0dHA6Ly91cmwtZm9yLWNybC9Sb290LmNybDAOBgNVHQ8BAf8EBAMC
+AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAFuT2/BPUFtxC
+X8SdiNbIafSG807e9f/kBUYipOuxzh3Xb0YE02zig/e+pD7CzFG6cS5tzY0STr42
+YFolBenSxo9kkXqzUHzdxLdfxMVvWD/7/TMHtk6mJQ5+SJsqqAVU4Gony+o+QEKf
+P6hb0mIX8ICQwt0H/1yPCDfAxUF43L58UFWbQvfaqrAX9OntWOMoqWao33LNALyK
+/6CWkTPzciirXnLkRTO4wEYiPZa+POUuv3IPojDSshWMx2mLFtz5F/6h+4t8DJQk
+VHi26KHpLUvUE2sBQuq8vOrRXhvEC6Y83y0Xiy7GRKxGRU4oxmj0NKaLpoiG9eQm
+UAGgHl5yZg==
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ov_name_constraints/keys/i.key b/chromium/net/data/ov_name_constraints/keys/i.key
new file mode 100644
index 00000000000..32718ea4971
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/keys/i.key
@@ -0,0 +1,28 @@
+openssl genrsa 2048
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA1ayAFLnSeK1DyFFpPph/vahXo2UoGW1E5Wpd98Ix7U5mqfHS
+nTa2uZg/2FTS6Xc6+5/VyfnJ31632jRC9svjZuC3WoKbdyAPsRceKnBi0meboFTy
+G6SfBre7r1pvVbF++CDL7eRV2BjLTw7DxF0T/P3XsRzFWIHP6VZ4Z3iq/gYpnjQ+
+S/5+7CIWFdYrw24XI0IbKC4hEzGLijMjomf2I7zyaJtxkpJ/IwlTlmc8/sKBiJ8A
+VZNNs+cCARNISzQSRW5IaoghM/9aA0lWomlkl6RTDpBzhMa4KLBbwGeF/Zol8s8O
+eSR4IIDwLK5GjsXPKb5/9X1zbaoLEFlP1kbxvwIDAQABAoIBAGCftPuqXCb+ExzO
+08zeoUVejuLwp4V4CCPGSd/0DSfGwF4xYJB/YXnkA1sMYKP6qs2GpeLD9inwZyth
+XrbD1H19OOzRCwR/lxj530ZJtCZ5e8KxJxqhAtjC1TiiqJ4Tudry2cUl8DvcWnPR
+tW1iuds53wPUgtlXOnHGDISd6JUd2KzFF96C8ebK4FTrvlPQ8BJVqXsT3pocq4xM
+T1y2loa5wV3Dkh2kT9+aJS8ApZPxjMh5hhnLCSrAAHhjinHvvaE5lDmUSRBuW1YA
+t7VhP7/uJEpypSbsf8ycGG85L6Km5rjR+aeZbuYcmC2f+swfUG0zXrFb1kmi+AzR
+WGaU3AECgYEA8QTCALsGH5ewid3nthOPN+bJrgPwtWbWX9T3v9RqmdDZ+vEy7jK2
+PoFxOgc/K0kcV2nltO4kCxLJMWBxfcp153oXIUzuQ5c0fm9C7Lk5J10KoT7jvWLV
+LYPZY623vHFN0aep4lPv5VPQ4kmIasWzqs3PBNp5hw3sWBhbSUePbj8CgYEA4vSd
+fqqwBAbmnpFRfm6+zuYte8A7ra+lGVFOo3noDFuXZj8CpzrDtQFJjhhZVgyo9P7G
+/VsOEqer3gfOTggirzEAPZUCpAqssgIkxUjJgS8CSIZCdzu9coRB701yVABoThOU
+IkjEkSUcs8ohZcmbAAFf/Ccwxo+NCNVte0+unIECgYAtdmJJ1P1gtDI+rzbn52Sa
+fNQKGQAsl4tUZE2fR6gb/4M+jIS43aP2wl/jPD60IYRREM6dhFYUKKT+xVxjB++Z
+jDQUufgvk7P5LW+IS5/2RtycccpvjNb9UOOOo9QGnbC6HVA0OvUDYv4B0TEEQuqT
+C2NDXRqTWRL9wwplFjR97QKBgQDUHPDxiI93RAfYXVLACrsUXfZWeYSNQOLZ9a68
+hNwGaLfoXK2bJAXzLp/TSRh9ntluGIxcD/ToJIMxwTPkpB/egrqJ07GjJULgH7bE
+F9IUhZ3psGmATHo0BD4nbMeUkMjrZ8sD++STDw9zTU/HdRQDfkV6QhqJCXMztV1c
+aU11gQKBgE2dQAYlanGGg21mjFki+8jCTbT2eqistyW0jzvFAZW/Gpn7DUcr8M8k
+9pg/IY+LGKAXIOGqiOXxgMT6kU2qcy5/hhLCQny27FwJ9JpTB82fmOKJkLK4mIjU
+i7n3HTy/jd8BM+4aOtn4aNqVtyA2NbzSsL14or8Vn4eSbb9UWWvJ
+-----END RSA PRIVATE KEY-----
diff --git a/chromium/net/data/ov_name_constraints/keys/leaf.key b/chromium/net/data/ov_name_constraints/keys/leaf.key
new file mode 100644
index 00000000000..cee893e7902
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/keys/leaf.key
@@ -0,0 +1,28 @@
+openssl genrsa 2048
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA75Hruw8NqjWTbe3EZ70P017Q2ox6gzDlkq/6KoRml/Etk5ZA
+SbJquMOM6iGLxWrZkekFbOIuSFaEM++kH+Iy7NGaYVbkZh/171EJoYXmz9XOLmSh
+Aqm/UH6grPxqcWphSwgDNKZcCikDpyNMHpAVrsuXrUcbGIrEcTum9DT/1KJUZ8Lt
+Z4Up6N5KQdJJV+kYQ+zZF0f0cWj+XKyPVRLdgGCPtubaNPr7UlcXrUkmdlrwwHoK
+owXKdGj6mXfKWZgoCyt2HFEOHNHTSwZeA/e21jygvHPs4HWuBD+vJFdqrX51ZZhz
+jZwUhhfQJ1/rO43zKJ9J5CoY+6VSTpdG0ZVvlwIDAQABAoIBAHOYDww1GTzVmQtj
+vG7ptKciitfJDJwcjckXjDfTpsUNpBYgW2iz4/a+tFGMWiqpgc17iBifkgFpbWS5
+7pFLzZKjGEB7cr0sErike2cqetIxsciE2YO1cBBg6RpOuPV8hPF1LkbLNoHYhGCz
+EVl14GB07/y14IcY/ew9AjO3FvH7ann11OgR1HBKo/7DSuG06xubTggVK3tWPB6P
+duyIUrNAcVNJTwvjND8VU7jMG0O5gD0fz8YfSlteUfFwZeq7yIFGgJ68DLF97N6n
+cfEHUNqQ2AiL2+2Y+GVhTWVW52O5y/qdzILFuV61Iw49q1yFTfW2cyOvtNjHMz6/
+FxZPF8ECgYEA/geu5WgxKXEkAlIGPt5abyPqiGMVEq/W08kjCL76lcP31P2NmRy0
+TvHjf1CvGU27mZ1G3k2Qzcmt3FgDvOJ6dTiMiKA3rWrRR33K0MSEF/sYUTe6gl5Z
+NXM8JvTBhZ3iYkz1VvCSn0fFkcxVIrpPiODGlX+vzJHkhnq6CuX5onECgYEA8W2H
+20MAax5X2h3A659VRbC0/R0HBfSoHCCVJ7zpUMpTB0dK0z5fQCbtbYjrK0q/Vai2
+ba6phhOpN1qk6CbHBEW7hbR4v7WXchn6BVnNA2/ktN1Oul4xFR3tw7+SbIc0c/Ly
+GYx0h5WrQ9l5SrJ+ArJp/4TSLin1jBEc7owUJocCgYA35NDiwS4wBCj8KbgeFSao
+1apBICv+1JncN6FxxzOzyE67mp6RVfOGe0qnNMWSN7xTbHuvZjm6TennVaZc5Sg0
+qqChXz9g9OPfaxo5HURDUohjNnPfQ4s1a4mMuMXr9HVfU7eXzY81ZMFf9ym0XnIp
+l+uZ8WJpDKDPxikxRLDMwQKBgQDuga59RivbpxZTPKGiJL4xIukqRMrzb0fEwcuY
+fmBgmAB+aEfbePrQfaSBWYo6MpXjIdFXef2vnyzEqp/PWL+z0M/4vtmrStJavp7p
+OlX210uyAhAMvZDvs6l4gIE/BjMjeRcDdmaIq6uOVAIncT5bm7Zr3+NkB7+0qBNU
+9r3RcQKBgQD9dGzk5SUd0BEcr564DBoFVHljj8u18j+dus5skjNrWxIBZL5lzXIY
+04l6ENOiPvlarQzGVoOcnHEa/PSJDIq5ovpH+Yf/QodxLbZ9UrSiLs6acaZY0i2i
+C1pOlKOeVOg0abNPF+CT8hJKzgkxnWNT/s3h6UV3GM4WlZAD40i7Sw==
+-----END RSA PRIVATE KEY-----
diff --git a/chromium/net/data/ov_name_constraints/keys/root.key b/chromium/net/data/ov_name_constraints/keys/root.key
new file mode 100644
index 00000000000..51341dfaf23
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/keys/root.key
@@ -0,0 +1,28 @@
+openssl genrsa 2048
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA1lgp/GlENDmlkQY1rN4xKvdv8BrHIW6Dy9JdBsGfUk3uRgc1
+ECi1XGgphyKOxvd97YkFKJzRaoDGRPtcvAkMN/Eltzz5AYRyA907AlrLX2UAJ4zs
+JYsrsIubYD+2ubpTaIg8MEYy+tmpzqpVtco+UeeYXtEbDHXRoH4fRP+0YsS009ld
+bXGywQpZtPxgdE+j32R9Zl5LKp5O4BbFqqMMuWCjOHCTzM5DS24rYLUfwf/uhb5i
+22NHh+E+oktX1s5u+M5904/b4S0KVzkP3W7dTIoFe8mX5J4K/5nCQSl6Brk88QL+
+O4W170quhYx1ZmJyDze0qoDVIUNwBOQ+APSvOQIDAQABAoIBAD5GdURpzTAjQ5Bk
+LnogQEbMh1BKZ2q2MkKoxvBslv6Rt9XOyEL+oNrNRKuHhdYXGBZIhiArl8iKy5BF
+O8dCFbO3M48OfwZK1dl7kGZ5vLbloGrdTcsGqVXs6eLIAC3sDcnEM0CPVMZ/MQ/j
+e22K6hpf4GxD8sjm/lXT7v/cDyvWlKB8/1XfvtYEYONnox6bEzOnZdX143tf369r
+HHS5uqeGxXeDWnAWWNyCmO+3eFiTqIMRMAe6cqnVPtXUBVDL2Nd/SgbluUwCUzEH
+LeZf8TZh/+M8X7Y/VyPgg0XkKsDeZUlHTANZXnk+n3QT/lSHdcMz97qZSw0BZpgJ
+DRaAwlECgYEA9/eFnHP/I0xAf/dTWrFMxcnameQLPQ0hA+Et2sfsMp1WJnggUTvY
+i2GwPlO/XG+/hrK1gPokfrN2EIX9EaGG/oMaOc7ufdJWbE7iVh649dS9zp3A1m1J
+AROu8qeHrqxDs/gGkcoCSX2S2kMHJAy+6Lf9cwTGi0r0XwlzLVZd5P0CgYEA3UnM
+edOxmzk2Vj3Oy4QkLCynyHePF9UIA6eFryBQtSxwD9h2aqpwvOO2Z4cBWffc7V+8
+uvxNjg8vwlZLaJogF3OQkCOp+5sxPsJGCqyoD8wv47V31hhpfw/i6rndzX2WiiWM
+GldwY2oiTTLde4FwF99KkNQxMqQdI2HQbS9lxe0CgYBVR2hJHU+SySepmtqs5ysb
+Hseyg04mKfy/w9KsWnNuGNRHGKsspONdVDRzywOV+8ynu5BWkjC47mldV2doh9/Q
+ajA7z2IQHaWhTCPlMF22FftNMs3eMOmZmDZjt6AfP5ltLJC91PaiZbB6pfCvwj5p
+9NUSmILb5uRSRwK4hep21QKBgQCBmE+85UJ1gosU9LugKrI4gKp+V66gqW05HqnH
+ByjdAbpbPU0UaN7/cGiJtuIOu39SMShJZatR0AkLShh9mQ3ETjTShWBubtPnSkVU
+yQrfvZgqRkN5SfC2rioZh2KjjrJUE2s6ngy+3BBcn7ZgN0zbXjTAHtT1MHG0H/u9
+he2XfQKBgCKhD1/Z/oAyPOvvOXZMBx0ZRJg8jbnp83Q/R/0mDhxoz/mr1d+TRdPH
+WM2V38hfWmRKeSd6F/t8hdKB1GIGT/LuEI4drue0TFMKgY2nT8jFhLlVLVNA/m21
+/UCY7/pAy3DoY+VgiuMHW16Ud2pTjioAsdKHeVX4peqpYnc25BKw
+-----END RSA PRIVATE KEY-----
diff --git a/chromium/net/data/ov_name_constraints/leaf-no-o.pem b/chromium/net/data/ov_name_constraints/leaf-no-o.pem
new file mode 100644
index 00000000000..ee8127c5d4b
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/leaf-no-o.pem
@@ -0,0 +1,88 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 14 (0xe)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2021 GMT
+ Subject: CN=O1
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:ef:91:eb:bb:0f:0d:aa:35:93:6d:ed:c4:67:bd:
+ 0f:d3:5e:d0:da:8c:7a:83:30:e5:92:af:fa:2a:84:
+ 66:97:f1:2d:93:96:40:49:b2:6a:b8:c3:8c:ea:21:
+ 8b:c5:6a:d9:91:e9:05:6c:e2:2e:48:56:84:33:ef:
+ a4:1f:e2:32:ec:d1:9a:61:56:e4:66:1f:f5:ef:51:
+ 09:a1:85:e6:cf:d5:ce:2e:64:a1:02:a9:bf:50:7e:
+ a0:ac:fc:6a:71:6a:61:4b:08:03:34:a6:5c:0a:29:
+ 03:a7:23:4c:1e:90:15:ae:cb:97:ad:47:1b:18:8a:
+ c4:71:3b:a6:f4:34:ff:d4:a2:54:67:c2:ed:67:85:
+ 29:e8:de:4a:41:d2:49:57:e9:18:43:ec:d9:17:47:
+ f4:71:68:fe:5c:ac:8f:55:12:dd:80:60:8f:b6:e6:
+ da:34:fa:fb:52:57:17:ad:49:26:76:5a:f0:c0:7a:
+ 0a:a3:05:ca:74:68:fa:99:77:ca:59:98:28:0b:2b:
+ 76:1c:51:0e:1c:d1:d3:4b:06:5e:03:f7:b6:d6:3c:
+ a0:bc:73:ec:e0:75:ae:04:3f:af:24:57:6a:ad:7e:
+ 75:65:98:73:8d:9c:14:86:17:d0:27:5f:eb:3b:8d:
+ f3:28:9f:49:e4:2a:18:fb:a5:52:4e:97:46:d1:95:
+ 6f:97
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 54:7C:D9:94:2E:53:89:05:22:9C:6D:7C:CB:79:32:C4:33:1D:89:67
+ X509v3 Authority Key Identifier:
+ keyid:FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Root.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Root.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 3e:68:af:96:f2:72:37:b0:3e:19:5e:f7:e7:58:19:cf:e8:35:
+ 0c:52:8e:95:81:99:46:d2:99:52:ea:48:11:2c:e0:77:28:91:
+ 43:3b:fa:d0:2d:48:33:e0:9f:63:29:74:72:a5:3a:f3:df:ec:
+ 69:22:3f:3e:01:da:42:89:40:d3:2c:1e:eb:e7:77:85:ea:9d:
+ cd:c8:37:f7:47:a6:01:3c:7d:de:c0:df:c5:31:93:df:5c:48:
+ 90:ae:0e:ee:fe:42:a4:53:94:3b:ce:e7:a8:79:ac:68:4d:d7:
+ 25:e1:4c:b5:cf:79:73:59:5f:88:92:61:63:91:97:6f:55:fe:
+ d1:e4:84:8e:9f:89:c4:2b:f8:c2:e3:54:ac:60:24:55:d4:c2:
+ 75:53:50:71:7e:44:ba:ba:75:8f:4b:14:4c:c5:e8:97:33:3f:
+ e7:29:19:cb:d8:a6:05:64:32:94:25:e3:ba:3c:93:a6:fb:3a:
+ d6:48:06:94:b4:88:5e:03:32:b6:3c:18:b4:ce:47:ff:6f:2a:
+ bc:c8:4b:a1:e7:e5:09:f7:e7:e5:48:7a:94:c1:43:a1:d3:80:
+ 8d:13:bd:7d:36:f9:81:b6:8e:23:19:e9:4b:1e:87:7a:9c:76:
+ df:2e:4b:03:94:b1:11:15:8a:78:c0:f9:8e:8e:7d:df:db:20:
+ b4:d0:cb:a4
+-----BEGIN CERTIFICATE-----
+MIIDcTCCAlmgAwIBAgIBDjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowDTELMAkGA1UEAwwCTzEw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvkeu7Dw2qNZNt7cRnvQ/T
+XtDajHqDMOWSr/oqhGaX8S2TlkBJsmq4w4zqIYvFatmR6QVs4i5IVoQz76Qf4jLs
+0ZphVuRmH/XvUQmhhebP1c4uZKECqb9QfqCs/GpxamFLCAM0plwKKQOnI0wekBWu
+y5etRxsYisRxO6b0NP/UolRnwu1nhSno3kpB0klX6RhD7NkXR/RxaP5crI9VEt2A
+YI+25to0+vtSVxetSSZ2WvDAegqjBcp0aPqZd8pZmCgLK3YcUQ4c0dNLBl4D97bW
+PKC8c+zgda4EP68kV2qtfnVlmHONnBSGF9AnX+s7jfMon0nkKhj7pVJOl0bRlW+X
+AgMBAAGjgdkwgdYwHQYDVR0OBBYEFFR82ZQuU4kFIpxtfMt5MsQzHYlnMB8GA1Ud
+IwQYMBaAFP+L/KVpNi9iO9Qb7Vgv6Xc9KYGDMDcGCCsGAQUFBwEBBCswKTAnBggr
+BgEFBQcwAoYbaHR0cDovL3VybC1mb3ItYWlhL1Jvb3QuY2VyMCwGA1UdHwQlMCMw
+IaAfoB2GG2h0dHA6Ly91cmwtZm9yLWNybC9Sb290LmNybDAOBgNVHQ8BAf8EBAMC
+BaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUA
+A4IBAQA+aK+W8nI3sD4ZXvfnWBnP6DUMUo6VgZlG0plS6kgRLOB3KJFDO/rQLUgz
+4J9jKXRypTrz3+xpIj8+AdpCiUDTLB7r53eF6p3NyDf3R6YBPH3ewN/FMZPfXEiQ
+rg7u/kKkU5Q7zueoeaxoTdcl4Uy1z3lzWV+IkmFjkZdvVf7R5ISOn4nEK/jC41Ss
+YCRV1MJ1U1BxfkS6unWPSxRMxeiXMz/nKRnL2KYFZDKUJeO6PJOm+zrWSAaUtIhe
+AzK2PBi0zkf/byq8yEuh5+UJ9+flSHqUwUOh04CNE719NvmBto4jGelLHod6nHbf
+LksDlLERFYp4wPmOjn3f2yC00Muk
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ov_name_constraints/leaf-o1-o2.pem b/chromium/net/data/ov_name_constraints/leaf-o1-o2.pem
new file mode 100644
index 00000000000..eb718427dde
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/leaf-o1-o2.pem
@@ -0,0 +1,89 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 15 (0xf)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2021 GMT
+ Subject: O=O1, O=O2, CN=Leaf
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:ef:91:eb:bb:0f:0d:aa:35:93:6d:ed:c4:67:bd:
+ 0f:d3:5e:d0:da:8c:7a:83:30:e5:92:af:fa:2a:84:
+ 66:97:f1:2d:93:96:40:49:b2:6a:b8:c3:8c:ea:21:
+ 8b:c5:6a:d9:91:e9:05:6c:e2:2e:48:56:84:33:ef:
+ a4:1f:e2:32:ec:d1:9a:61:56:e4:66:1f:f5:ef:51:
+ 09:a1:85:e6:cf:d5:ce:2e:64:a1:02:a9:bf:50:7e:
+ a0:ac:fc:6a:71:6a:61:4b:08:03:34:a6:5c:0a:29:
+ 03:a7:23:4c:1e:90:15:ae:cb:97:ad:47:1b:18:8a:
+ c4:71:3b:a6:f4:34:ff:d4:a2:54:67:c2:ed:67:85:
+ 29:e8:de:4a:41:d2:49:57:e9:18:43:ec:d9:17:47:
+ f4:71:68:fe:5c:ac:8f:55:12:dd:80:60:8f:b6:e6:
+ da:34:fa:fb:52:57:17:ad:49:26:76:5a:f0:c0:7a:
+ 0a:a3:05:ca:74:68:fa:99:77:ca:59:98:28:0b:2b:
+ 76:1c:51:0e:1c:d1:d3:4b:06:5e:03:f7:b6:d6:3c:
+ a0:bc:73:ec:e0:75:ae:04:3f:af:24:57:6a:ad:7e:
+ 75:65:98:73:8d:9c:14:86:17:d0:27:5f:eb:3b:8d:
+ f3:28:9f:49:e4:2a:18:fb:a5:52:4e:97:46:d1:95:
+ 6f:97
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 54:7C:D9:94:2E:53:89:05:22:9C:6D:7C:CB:79:32:C4:33:1D:89:67
+ X509v3 Authority Key Identifier:
+ keyid:FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Root.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Root.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ 72:41:d4:00:ae:2e:da:b0:1d:a1:f2:5e:91:6c:66:f1:ec:40:
+ 89:6c:99:fe:90:c6:31:62:e0:ae:8f:36:84:ed:ec:e1:8f:18:
+ bd:bb:bc:f1:ed:63:0f:18:a4:1b:e2:37:13:1d:8d:7c:6d:71:
+ 8d:51:e9:13:3f:1c:7d:69:9c:e5:e4:37:5c:fe:b6:b8:90:b6:
+ 15:08:82:cb:6d:f6:88:b8:ce:f7:93:35:dd:ef:38:64:9b:cd:
+ 71:37:10:be:3b:63:22:58:26:9a:04:e2:4e:b7:b5:3f:87:f5:
+ 89:3e:b8:b8:52:3f:1f:69:24:4d:d2:7f:ba:b8:1a:23:82:92:
+ c2:ad:5c:5b:80:91:9a:28:a2:1f:aa:db:21:2f:66:cf:83:6f:
+ 46:17:81:0c:53:0a:e7:f8:3b:7f:b7:92:3c:0c:ca:b8:56:bd:
+ 97:ba:de:8a:84:84:d3:35:4a:17:22:15:43:5c:4b:6f:9f:41:
+ cc:b5:a4:2d:63:2e:b6:14:66:04:d5:a4:d5:e6:2d:a2:68:f5:
+ 95:df:f3:8c:91:6f:43:0c:03:6c:67:38:d7:53:4e:5f:fd:cf:
+ d4:06:eb:0c:8f:d7:5c:f6:b0:9f:56:93:82:92:21:ae:88:1c:
+ 5a:8a:0c:43:66:be:50:39:5d:85:9a:45:58:cf:05:1a:49:03:
+ b6:e7:f9:45
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBDzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowKTELMAkGA1UECgwCTzEx
+CzAJBgNVBAoMAk8yMQ0wCwYDVQQDDARMZWFmMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEA75Hruw8NqjWTbe3EZ70P017Q2ox6gzDlkq/6KoRml/Etk5ZA
+SbJquMOM6iGLxWrZkekFbOIuSFaEM++kH+Iy7NGaYVbkZh/171EJoYXmz9XOLmSh
+Aqm/UH6grPxqcWphSwgDNKZcCikDpyNMHpAVrsuXrUcbGIrEcTum9DT/1KJUZ8Lt
+Z4Up6N5KQdJJV+kYQ+zZF0f0cWj+XKyPVRLdgGCPtubaNPr7UlcXrUkmdlrwwHoK
+owXKdGj6mXfKWZgoCyt2HFEOHNHTSwZeA/e21jygvHPs4HWuBD+vJFdqrX51ZZhz
+jZwUhhfQJ1/rO43zKJ9J5CoY+6VSTpdG0ZVvlwIDAQABo4HZMIHWMB0GA1UdDgQW
+BBRUfNmULlOJBSKcbXzLeTLEMx2JZzAfBgNVHSMEGDAWgBT/i/ylaTYvYjvUG+1Y
+L+l3PSmBgzA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwt
+Zm9yLWFpYS9Sb290LmNlcjAsBgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZv
+ci1jcmwvUm9vdC5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
+BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAckHUAK4u2rAdofJekWxm
+8exAiWyZ/pDGMWLgro82hO3s4Y8Yvbu88e1jDxikG+I3Ex2NfG1xjVHpEz8cfWmc
+5eQ3XP62uJC2FQiCy232iLjO95M13e84ZJvNcTcQvjtjIlgmmgTiTre1P4f1iT64
+uFI/H2kkTdJ/urgaI4KSwq1cW4CRmiiiH6rbIS9mz4NvRheBDFMK5/g7f7eSPAzK
+uFa9l7reioSE0zVKFyIVQ1xLb59BzLWkLWMuthRmBNWk1eYtomj1ld/zjJFvQwwD
+bGc411NOX/3P1AbrDI/XXPawn1aTgpIhrogcWooMQ2a+UDldhZpFWM8FGkkDtuf5
+RQ==
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ov_name_constraints/leaf-o1.pem b/chromium/net/data/ov_name_constraints/leaf-o1.pem
new file mode 100644
index 00000000000..b1dbe7a740a
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/leaf-o1.pem
@@ -0,0 +1,88 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 16 (0x10)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2021 GMT
+ Subject: O=O1, CN=Leaf
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:ef:91:eb:bb:0f:0d:aa:35:93:6d:ed:c4:67:bd:
+ 0f:d3:5e:d0:da:8c:7a:83:30:e5:92:af:fa:2a:84:
+ 66:97:f1:2d:93:96:40:49:b2:6a:b8:c3:8c:ea:21:
+ 8b:c5:6a:d9:91:e9:05:6c:e2:2e:48:56:84:33:ef:
+ a4:1f:e2:32:ec:d1:9a:61:56:e4:66:1f:f5:ef:51:
+ 09:a1:85:e6:cf:d5:ce:2e:64:a1:02:a9:bf:50:7e:
+ a0:ac:fc:6a:71:6a:61:4b:08:03:34:a6:5c:0a:29:
+ 03:a7:23:4c:1e:90:15:ae:cb:97:ad:47:1b:18:8a:
+ c4:71:3b:a6:f4:34:ff:d4:a2:54:67:c2:ed:67:85:
+ 29:e8:de:4a:41:d2:49:57:e9:18:43:ec:d9:17:47:
+ f4:71:68:fe:5c:ac:8f:55:12:dd:80:60:8f:b6:e6:
+ da:34:fa:fb:52:57:17:ad:49:26:76:5a:f0:c0:7a:
+ 0a:a3:05:ca:74:68:fa:99:77:ca:59:98:28:0b:2b:
+ 76:1c:51:0e:1c:d1:d3:4b:06:5e:03:f7:b6:d6:3c:
+ a0:bc:73:ec:e0:75:ae:04:3f:af:24:57:6a:ad:7e:
+ 75:65:98:73:8d:9c:14:86:17:d0:27:5f:eb:3b:8d:
+ f3:28:9f:49:e4:2a:18:fb:a5:52:4e:97:46:d1:95:
+ 6f:97
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 54:7C:D9:94:2E:53:89:05:22:9C:6D:7C:CB:79:32:C4:33:1D:89:67
+ X509v3 Authority Key Identifier:
+ keyid:FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Root.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Root.crl
+
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ Signature Algorithm: sha256WithRSAEncryption
+ ca:ec:a3:62:ed:be:98:20:61:0c:43:a7:25:5d:80:e6:7b:02:
+ c9:31:7b:ba:3f:5e:c1:d0:2a:d5:09:3c:68:a8:c7:ab:77:9c:
+ f5:3d:7c:3d:3a:f3:22:ab:07:31:3d:08:10:6d:6b:5a:2d:74:
+ a2:64:bb:b6:1b:c4:69:e8:5a:f7:35:20:86:a9:c5:53:ba:24:
+ 91:a2:06:13:bf:ea:88:c0:58:7d:5f:22:e7:aa:5f:a5:61:79:
+ 48:ac:6c:c3:f2:d1:cb:26:25:f8:5a:02:50:e4:49:3a:50:dc:
+ 97:eb:6d:f5:4d:1f:a8:52:78:56:00:96:8d:5b:3d:3e:4a:2c:
+ c3:6a:eb:7e:93:34:c8:e1:6b:a5:13:44:1a:db:82:85:e5:22:
+ d7:24:98:b9:2b:b6:1a:6b:59:8c:1f:cc:de:81:9c:54:48:85:
+ 4d:0b:68:00:bb:4c:69:32:eb:46:b2:cd:08:b6:90:17:4c:c6:
+ d2:be:17:9c:1e:c2:c8:72:38:82:35:f4:ec:e5:56:8a:ce:17:
+ 0f:e7:56:26:76:32:43:cd:f7:5f:0e:f1:72:bf:1b:ab:4d:39:
+ 15:fe:b6:85:7f:71:29:4b:f6:c6:ff:6b:39:c1:b0:51:d9:07:
+ e7:20:17:b8:de:69:83:8d:98:30:37:eb:fd:f7:25:26:f7:78:
+ f7:da:9c:56
+-----BEGIN CERTIFICATE-----
+MIIDgDCCAmigAwIBAgIBEDANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowHDELMAkGA1UECgwCTzEx
+DTALBgNVBAMMBExlYWYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDv
+keu7Dw2qNZNt7cRnvQ/TXtDajHqDMOWSr/oqhGaX8S2TlkBJsmq4w4zqIYvFatmR
+6QVs4i5IVoQz76Qf4jLs0ZphVuRmH/XvUQmhhebP1c4uZKECqb9QfqCs/GpxamFL
+CAM0plwKKQOnI0wekBWuy5etRxsYisRxO6b0NP/UolRnwu1nhSno3kpB0klX6RhD
+7NkXR/RxaP5crI9VEt2AYI+25to0+vtSVxetSSZ2WvDAegqjBcp0aPqZd8pZmCgL
+K3YcUQ4c0dNLBl4D97bWPKC8c+zgda4EP68kV2qtfnVlmHONnBSGF9AnX+s7jfMo
+n0nkKhj7pVJOl0bRlW+XAgMBAAGjgdkwgdYwHQYDVR0OBBYEFFR82ZQuU4kFIpxt
+fMt5MsQzHYlnMB8GA1UdIwQYMBaAFP+L/KVpNi9iO9Qb7Vgv6Xc9KYGDMDcGCCsG
+AQUFBwEBBCswKTAnBggrBgEFBQcwAoYbaHR0cDovL3VybC1mb3ItYWlhL1Jvb3Qu
+Y2VyMCwGA1UdHwQlMCMwIaAfoB2GG2h0dHA6Ly91cmwtZm9yLWNybC9Sb290LmNy
+bDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC
+MA0GCSqGSIb3DQEBCwUAA4IBAQDK7KNi7b6YIGEMQ6clXYDmewLJMXu6P17B0CrV
+CTxoqMerd5z1PXw9OvMiqwcxPQgQbWtaLXSiZLu2G8Rp6Fr3NSCGqcVTuiSRogYT
+v+qIwFh9XyLnql+lYXlIrGzD8tHLJiX4WgJQ5Ek6UNyX6231TR+oUnhWAJaNWz0+
+SizDaut+kzTI4WulE0Qa24KF5SLXJJi5K7Yaa1mMH8zegZxUSIVNC2gAu0xpMutG
+ss0ItpAXTMbSvhecHsLIcjiCNfTs5VaKzhcP51YmdjJDzfdfDvFyvxurTTkV/raF
+f3EpS/bG/2s5wbBR2QfnIBe43mmDjZgwN+v99yUm93j32pxW
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ov_name_constraints/nc-int-exclude-o1.pem b/chromium/net/data/ov_name_constraints/nc-int-exclude-o1.pem
new file mode 100644
index 00000000000..fcee045a043
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/nc-int-exclude-o1.pem
@@ -0,0 +1,92 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 11 (0xb)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2021 GMT
+ Subject: CN=NC4
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d5:ac:80:14:b9:d2:78:ad:43:c8:51:69:3e:98:
+ 7f:bd:a8:57:a3:65:28:19:6d:44:e5:6a:5d:f7:c2:
+ 31:ed:4e:66:a9:f1:d2:9d:36:b6:b9:98:3f:d8:54:
+ d2:e9:77:3a:fb:9f:d5:c9:f9:c9:df:5e:b7:da:34:
+ 42:f6:cb:e3:66:e0:b7:5a:82:9b:77:20:0f:b1:17:
+ 1e:2a:70:62:d2:67:9b:a0:54:f2:1b:a4:9f:06:b7:
+ bb:af:5a:6f:55:b1:7e:f8:20:cb:ed:e4:55:d8:18:
+ cb:4f:0e:c3:c4:5d:13:fc:fd:d7:b1:1c:c5:58:81:
+ cf:e9:56:78:67:78:aa:fe:06:29:9e:34:3e:4b:fe:
+ 7e:ec:22:16:15:d6:2b:c3:6e:17:23:42:1b:28:2e:
+ 21:13:31:8b:8a:33:23:a2:67:f6:23:bc:f2:68:9b:
+ 71:92:92:7f:23:09:53:96:67:3c:fe:c2:81:88:9f:
+ 00:55:93:4d:b3:e7:02:01:13:48:4b:34:12:45:6e:
+ 48:6a:88:21:33:ff:5a:03:49:56:a2:69:64:97:a4:
+ 53:0e:90:73:84:c6:b8:28:b0:5b:c0:67:85:fd:9a:
+ 25:f2:cf:0e:79:24:78:20:80:f0:2c:ae:46:8e:c5:
+ cf:29:be:7f:f5:7d:73:6d:aa:0b:10:59:4f:d6:46:
+ f1:bf
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 9D:44:AA:2B:9B:4C:66:4C:20:C5:32:B2:EA:08:13:13:69:17:49:B1
+ X509v3 Authority Key Identifier:
+ keyid:FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Root.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Root.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Name Constraints: critical
+ Excluded:
+ DirName:O = O1
+
+ Signature Algorithm: sha256WithRSAEncryption
+ b1:27:e9:b5:87:73:ef:2f:ec:e6:f5:2c:dc:9b:b7:27:b1:e8:
+ 66:f9:36:83:e6:b2:10:62:68:8d:17:6f:95:3b:db:03:4e:e0:
+ 2f:70:ce:27:17:c7:64:e4:fb:36:c6:3b:e8:a3:53:86:45:4f:
+ 76:ae:3b:65:1e:19:aa:c4:70:9c:31:9e:21:b7:ba:44:8c:70:
+ 2d:9e:a9:f3:07:9d:1b:21:53:fb:d8:08:91:ca:6b:28:12:32:
+ cb:e2:fa:81:b2:72:da:78:a5:40:56:d4:7a:aa:3c:5c:9e:92:
+ f4:af:a5:2f:fa:5e:b0:34:4f:73:39:ed:02:b3:cc:c7:13:0b:
+ d9:d4:c2:dc:d1:3c:bf:05:b9:d1:59:e1:fd:c1:de:15:31:48:
+ 26:4e:93:26:bb:6f:d5:11:fc:3b:30:91:90:7f:97:fe:48:0a:
+ 57:65:b2:c4:ae:20:ee:ba:b1:19:25:f0:a7:99:ae:0d:c6:15:
+ bf:2c:74:58:5e:b1:6b:8c:50:98:80:dc:d0:bb:e9:cb:2a:59:
+ ef:11:f1:50:e3:a8:54:80:15:a4:de:22:f6:69:24:47:fb:2e:
+ ee:56:c0:e2:80:7f:7a:bb:86:30:0f:a7:2e:f0:36:cc:f8:e8:
+ d0:56:98:28:3a:94:d4:59:75:fd:8a:85:a5:e6:44:ff:3c:c3:
+ c9:1f:a8:a4
+-----BEGIN CERTIFICATE-----
+MIIDhzCCAm+gAwIBAgIBCzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowDjEMMAoGA1UEAwwDTkM0
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1ayAFLnSeK1DyFFpPph/
+vahXo2UoGW1E5Wpd98Ix7U5mqfHSnTa2uZg/2FTS6Xc6+5/VyfnJ31632jRC9svj
+ZuC3WoKbdyAPsRceKnBi0meboFTyG6SfBre7r1pvVbF++CDL7eRV2BjLTw7DxF0T
+/P3XsRzFWIHP6VZ4Z3iq/gYpnjQ+S/5+7CIWFdYrw24XI0IbKC4hEzGLijMjomf2
+I7zyaJtxkpJ/IwlTlmc8/sKBiJ8AVZNNs+cCARNISzQSRW5IaoghM/9aA0lWomlk
+l6RTDpBzhMa4KLBbwGeF/Zol8s8OeSR4IIDwLK5GjsXPKb5/9X1zbaoLEFlP1kbx
+vwIDAQABo4HuMIHrMB0GA1UdDgQWBBSdRKorm0xmTCDFMrLqCBMTaRdJsTAfBgNV
+HSMEGDAWgBT/i/ylaTYvYjvUG+1YL+l3PSmBgzA3BggrBgEFBQcBAQQrMCkwJwYI
+KwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAsBgNVHR8EJTAj
+MCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYDVR0PAQH/BAQD
+AgEGMA8GA1UdEwEB/wQFMAMBAf8wIQYDVR0eAQH/BBcwFaETMBGkDzANMQswCQYD
+VQQKDAJPMTANBgkqhkiG9w0BAQsFAAOCAQEAsSfptYdz7y/s5vUs3Ju3J7HoZvk2
+g+ayEGJojRdvlTvbA07gL3DOJxfHZOT7NsY76KNThkVPdq47ZR4ZqsRwnDGeIbe6
+RIxwLZ6p8wedGyFT+9gIkcprKBIyy+L6gbJy2nilQFbUeqo8XJ6S9K+lL/pesDRP
+czntArPMxxML2dTC3NE8vwW50Vnh/cHeFTFIJk6TJrtv1RH8OzCRkH+X/kgKV2Wy
+xK4g7rqxGSXwp5muDcYVvyx0WF6xa4xQmIDc0LvpyypZ7xHxUOOoVIAVpN4i9mkk
+R/su7lbA4oB/eruGMA+nLvA2zPjo0FaYKDqU1Fl1/YqFpeZE/zzDyR+opA==
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ov_name_constraints/nc-int-permit-bmp-o1.pem b/chromium/net/data/ov_name_constraints/nc-int-permit-bmp-o1.pem
new file mode 100644
index 00000000000..4c2b75f5d22
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/nc-int-permit-bmp-o1.pem
@@ -0,0 +1,88 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 9 (0x9)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2021 GMT
+ Subject: CN=\x00N\x00C\x002
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d5:ac:80:14:b9:d2:78:ad:43:c8:51:69:3e:98:
+ 7f:bd:a8:57:a3:65:28:19:6d:44:e5:6a:5d:f7:c2:
+ 31:ed:4e:66:a9:f1:d2:9d:36:b6:b9:98:3f:d8:54:
+ d2:e9:77:3a:fb:9f:d5:c9:f9:c9:df:5e:b7:da:34:
+ 42:f6:cb:e3:66:e0:b7:5a:82:9b:77:20:0f:b1:17:
+ 1e:2a:70:62:d2:67:9b:a0:54:f2:1b:a4:9f:06:b7:
+ bb:af:5a:6f:55:b1:7e:f8:20:cb:ed:e4:55:d8:18:
+ cb:4f:0e:c3:c4:5d:13:fc:fd:d7:b1:1c:c5:58:81:
+ cf:e9:56:78:67:78:aa:fe:06:29:9e:34:3e:4b:fe:
+ 7e:ec:22:16:15:d6:2b:c3:6e:17:23:42:1b:28:2e:
+ 21:13:31:8b:8a:33:23:a2:67:f6:23:bc:f2:68:9b:
+ 71:92:92:7f:23:09:53:96:67:3c:fe:c2:81:88:9f:
+ 00:55:93:4d:b3:e7:02:01:13:48:4b:34:12:45:6e:
+ 48:6a:88:21:33:ff:5a:03:49:56:a2:69:64:97:a4:
+ 53:0e:90:73:84:c6:b8:28:b0:5b:c0:67:85:fd:9a:
+ 25:f2:cf:0e:79:24:78:20:80:f0:2c:ae:46:8e:c5:
+ cf:29:be:7f:f5:7d:73:6d:aa:0b:10:59:4f:d6:46:
+ f1:bf
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 9D:44:AA:2B:9B:4C:66:4C:20:C5:32:B2:EA:08:13:13:69:17:49:B1
+ X509v3 Authority Key Identifier:
+ keyid:FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Root.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Root.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ Signature Algorithm: sha256WithRSAEncryption
+ 8e:89:ad:c4:4d:31:16:ee:46:80:dc:1d:f9:24:15:dc:a5:91:
+ 14:90:17:cb:db:28:cc:86:b6:16:0d:80:10:f5:f7:06:bd:60:
+ 64:76:57:cf:da:c4:b0:51:79:2c:c3:d5:9c:ed:af:ad:90:5d:
+ 38:4d:aa:10:31:08:2f:b2:dc:fa:22:e6:50:b9:1d:18:d0:b7:
+ fb:c7:fe:4e:84:56:95:64:88:ac:ed:5f:40:73:2e:ff:5d:74:
+ a3:c5:93:cc:72:59:12:b6:0f:29:95:3f:0c:f1:86:6e:27:8c:
+ 52:cc:aa:4d:29:80:1d:1b:50:2c:39:af:e9:7b:8b:87:a5:bd:
+ 6f:6a:a4:a6:46:c2:da:28:45:66:4e:dc:b7:91:00:0e:76:b2:
+ 86:68:0e:c0:47:e4:bb:fc:19:38:4b:2c:7e:95:bb:41:4c:6d:
+ 55:ca:3e:fb:44:c0:8a:2f:b4:36:0b:ef:4e:ed:94:a1:45:d1:
+ d0:1b:35:e7:aa:cf:4e:99:0e:b3:54:d6:a0:c2:b9:1c:2c:dc:
+ 42:e5:5c:cb:f5:e4:91:eb:73:11:af:55:78:1f:1a:fa:19:a4:
+ 8c:16:1c:c9:72:ea:1a:07:f1:1c:a8:db:1f:3c:03:13:0b:89:
+ e6:80:22:70:25:d4:31:14:e5:28:32:bf:8f:9b:04:21:ea:d5:
+ 52:57:81:b4
+-----BEGIN CERTIFICATE-----
+MIIDZzCCAk+gAwIBAgIBCTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowETEPMA0GA1UEAx4GAE4A
+QwAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1ayAFLnSeK1DyFFp
+Pph/vahXo2UoGW1E5Wpd98Ix7U5mqfHSnTa2uZg/2FTS6Xc6+5/VyfnJ31632jRC
+9svjZuC3WoKbdyAPsRceKnBi0meboFTyG6SfBre7r1pvVbF++CDL7eRV2BjLTw7D
+xF0T/P3XsRzFWIHP6VZ4Z3iq/gYpnjQ+S/5+7CIWFdYrw24XI0IbKC4hEzGLijMj
+omf2I7zyaJtxkpJ/IwlTlmc8/sKBiJ8AVZNNs+cCARNISzQSRW5IaoghM/9aA0lW
+omlkl6RTDpBzhMa4KLBbwGeF/Zol8s8OeSR4IIDwLK5GjsXPKb5/9X1zbaoLEFlP
+1kbxvwIDAQABo4HLMIHIMB0GA1UdDgQWBBSdRKorm0xmTCDFMrLqCBMTaRdJsTAf
+BgNVHSMEGDAWgBT/i/ylaTYvYjvUG+1YL+l3PSmBgzA3BggrBgEFBQcBAQQrMCkw
+JwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAsBgNVHR8E
+JTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYDVR0PAQH/
+BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAI6JrcRN
+MRbuRoDcHfkkFdylkRSQF8vbKMyGthYNgBD19wa9YGR2V8/axLBReSzD1Zztr62Q
+XThNqhAxCC+y3Poi5lC5HRjQt/vH/k6EVpVkiKztX0BzLv9ddKPFk8xyWRK2DymV
+Pwzxhm4njFLMqk0pgB0bUCw5r+l7i4elvW9qpKZGwtooRWZO3LeRAA52soZoDsBH
+5Lv8GThLLH6Vu0FMbVXKPvtEwIovtDYL707tlKFF0dAbNeeqz06ZDrNU1qDCuRws
+3ELlXMv15JHrcxGvVXgfGvoZpIwWHMly6hoH8Ryo2x88AxMLieaAInAl1DEU5Sgy
+v4+bBCHq1VJXgbQ=
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ov_name_constraints/nc-int-permit-cn.pem b/chromium/net/data/ov_name_constraints/nc-int-permit-cn.pem
new file mode 100644
index 00000000000..92dce1dadf2
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/nc-int-permit-cn.pem
@@ -0,0 +1,92 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 10 (0xa)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2021 GMT
+ Subject: CN=NC3
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d5:ac:80:14:b9:d2:78:ad:43:c8:51:69:3e:98:
+ 7f:bd:a8:57:a3:65:28:19:6d:44:e5:6a:5d:f7:c2:
+ 31:ed:4e:66:a9:f1:d2:9d:36:b6:b9:98:3f:d8:54:
+ d2:e9:77:3a:fb:9f:d5:c9:f9:c9:df:5e:b7:da:34:
+ 42:f6:cb:e3:66:e0:b7:5a:82:9b:77:20:0f:b1:17:
+ 1e:2a:70:62:d2:67:9b:a0:54:f2:1b:a4:9f:06:b7:
+ bb:af:5a:6f:55:b1:7e:f8:20:cb:ed:e4:55:d8:18:
+ cb:4f:0e:c3:c4:5d:13:fc:fd:d7:b1:1c:c5:58:81:
+ cf:e9:56:78:67:78:aa:fe:06:29:9e:34:3e:4b:fe:
+ 7e:ec:22:16:15:d6:2b:c3:6e:17:23:42:1b:28:2e:
+ 21:13:31:8b:8a:33:23:a2:67:f6:23:bc:f2:68:9b:
+ 71:92:92:7f:23:09:53:96:67:3c:fe:c2:81:88:9f:
+ 00:55:93:4d:b3:e7:02:01:13:48:4b:34:12:45:6e:
+ 48:6a:88:21:33:ff:5a:03:49:56:a2:69:64:97:a4:
+ 53:0e:90:73:84:c6:b8:28:b0:5b:c0:67:85:fd:9a:
+ 25:f2:cf:0e:79:24:78:20:80:f0:2c:ae:46:8e:c5:
+ cf:29:be:7f:f5:7d:73:6d:aa:0b:10:59:4f:d6:46:
+ f1:bf
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 9D:44:AA:2B:9B:4C:66:4C:20:C5:32:B2:EA:08:13:13:69:17:49:B1
+ X509v3 Authority Key Identifier:
+ keyid:FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Root.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Root.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Name Constraints: critical
+ Permitted:
+ DirName:CN = O1
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 75:fc:1b:72:ca:48:55:b8:e5:a0:fd:e6:3a:4a:e3:da:2b:df:
+ 69:94:30:4a:41:db:5a:fc:d2:35:38:4c:b6:09:e0:29:d0:b8:
+ 88:47:90:e8:fb:01:2d:2d:22:53:9a:f5:a3:63:8c:15:c9:ef:
+ 73:e6:b0:9a:e7:53:c9:a6:7d:f2:af:19:ef:11:a6:46:fa:ed:
+ e4:93:18:71:ff:be:97:cd:22:f8:7a:44:65:de:2a:6b:c0:f4:
+ 81:d9:22:8f:a5:0c:54:22:5b:8c:9f:b8:ec:15:71:44:3d:0b:
+ e3:11:1c:8c:5e:3b:13:4c:06:97:25:10:49:dc:30:a3:da:4c:
+ 22:ab:66:e2:54:a9:2d:4c:3c:9a:db:1b:2a:d0:13:e4:36:e0:
+ 6f:2a:be:e9:ae:9f:d0:48:72:14:2e:f4:bf:d3:04:f5:7e:23:
+ b2:5b:62:a6:05:83:00:8d:b9:ae:dc:58:51:56:a5:36:13:14:
+ 98:ce:63:9e:65:4d:ac:12:15:50:a1:d2:92:99:bf:11:7f:54:
+ b1:10:db:94:b5:78:7d:01:3d:11:4e:a8:4b:e5:c8:a7:ab:6b:
+ b4:7e:3e:33:f9:dd:5c:43:1d:80:a5:58:e4:c5:38:ac:e7:98:
+ 1e:b6:46:6a:e1:04:9e:6c:17:f6:5c:15:1c:af:5f:5d:8a:3a:
+ 09:9d:8f:8c
+-----BEGIN CERTIFICATE-----
+MIIDhzCCAm+gAwIBAgIBCjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowDjEMMAoGA1UEAwwDTkMz
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1ayAFLnSeK1DyFFpPph/
+vahXo2UoGW1E5Wpd98Ix7U5mqfHSnTa2uZg/2FTS6Xc6+5/VyfnJ31632jRC9svj
+ZuC3WoKbdyAPsRceKnBi0meboFTyG6SfBre7r1pvVbF++CDL7eRV2BjLTw7DxF0T
+/P3XsRzFWIHP6VZ4Z3iq/gYpnjQ+S/5+7CIWFdYrw24XI0IbKC4hEzGLijMjomf2
+I7zyaJtxkpJ/IwlTlmc8/sKBiJ8AVZNNs+cCARNISzQSRW5IaoghM/9aA0lWomlk
+l6RTDpBzhMa4KLBbwGeF/Zol8s8OeSR4IIDwLK5GjsXPKb5/9X1zbaoLEFlP1kbx
+vwIDAQABo4HuMIHrMB0GA1UdDgQWBBSdRKorm0xmTCDFMrLqCBMTaRdJsTAfBgNV
+HSMEGDAWgBT/i/ylaTYvYjvUG+1YL+l3PSmBgzA3BggrBgEFBQcBAQQrMCkwJwYI
+KwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAsBgNVHR8EJTAj
+MCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYDVR0PAQH/BAQD
+AgEGMA8GA1UdEwEB/wQFMAMBAf8wIQYDVR0eAQH/BBcwFaATMBGkDzANMQswCQYD
+VQQDDAJPMTANBgkqhkiG9w0BAQsFAAOCAQEAdfwbcspIVbjloP3mOkrj2ivfaZQw
+SkHbWvzSNThMtgngKdC4iEeQ6PsBLS0iU5r1o2OMFcnvc+awmudTyaZ98q8Z7xGm
+Rvrt5JMYcf++l80i+HpEZd4qa8D0gdkij6UMVCJbjJ+47BVxRD0L4xEcjF47E0wG
+lyUQSdwwo9pMIqtm4lSpLUw8mtsbKtAT5Dbgbyq+6a6f0EhyFC70v9ME9X4jslti
+pgWDAI25rtxYUValNhMUmM5jnmVNrBIVUKHSkpm/EX9UsRDblLV4fQE9EU6oS+XI
+p6trtH4+M/ndXEMdgKVY5MU4rOeYHrZGauEEnmwX9lwVHK9fXYo6CZ2PjA==
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ov_name_constraints/nc-int-permit-dns.pem b/chromium/net/data/ov_name_constraints/nc-int-permit-dns.pem
new file mode 100644
index 00000000000..3322fcc8241
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/nc-int-permit-dns.pem
@@ -0,0 +1,92 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 12 (0xc)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2021 GMT
+ Subject: CN=NC5
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d5:ac:80:14:b9:d2:78:ad:43:c8:51:69:3e:98:
+ 7f:bd:a8:57:a3:65:28:19:6d:44:e5:6a:5d:f7:c2:
+ 31:ed:4e:66:a9:f1:d2:9d:36:b6:b9:98:3f:d8:54:
+ d2:e9:77:3a:fb:9f:d5:c9:f9:c9:df:5e:b7:da:34:
+ 42:f6:cb:e3:66:e0:b7:5a:82:9b:77:20:0f:b1:17:
+ 1e:2a:70:62:d2:67:9b:a0:54:f2:1b:a4:9f:06:b7:
+ bb:af:5a:6f:55:b1:7e:f8:20:cb:ed:e4:55:d8:18:
+ cb:4f:0e:c3:c4:5d:13:fc:fd:d7:b1:1c:c5:58:81:
+ cf:e9:56:78:67:78:aa:fe:06:29:9e:34:3e:4b:fe:
+ 7e:ec:22:16:15:d6:2b:c3:6e:17:23:42:1b:28:2e:
+ 21:13:31:8b:8a:33:23:a2:67:f6:23:bc:f2:68:9b:
+ 71:92:92:7f:23:09:53:96:67:3c:fe:c2:81:88:9f:
+ 00:55:93:4d:b3:e7:02:01:13:48:4b:34:12:45:6e:
+ 48:6a:88:21:33:ff:5a:03:49:56:a2:69:64:97:a4:
+ 53:0e:90:73:84:c6:b8:28:b0:5b:c0:67:85:fd:9a:
+ 25:f2:cf:0e:79:24:78:20:80:f0:2c:ae:46:8e:c5:
+ cf:29:be:7f:f5:7d:73:6d:aa:0b:10:59:4f:d6:46:
+ f1:bf
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 9D:44:AA:2B:9B:4C:66:4C:20:C5:32:B2:EA:08:13:13:69:17:49:B1
+ X509v3 Authority Key Identifier:
+ keyid:FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Root.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Root.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Name Constraints: critical
+ Permitted:
+ DNS:test.invalid
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 9e:89:c0:a4:72:98:ff:88:93:3e:16:d7:e0:0a:dc:95:d3:35:
+ 8e:4b:f8:f3:25:9a:64:6b:82:0a:47:ac:10:76:44:bb:ac:28:
+ 61:e0:28:67:58:d6:36:0e:66:da:19:d6:bd:2d:3b:f2:74:78:
+ e2:a8:f4:4d:3d:f4:16:74:09:62:55:29:e8:d7:96:a0:b7:36:
+ 53:ba:a8:74:bb:13:74:5c:a9:90:b9:f4:06:56:57:ab:be:55:
+ af:12:0a:1c:eb:13:4a:cc:37:d2:91:15:48:f9:70:0d:a4:c2:
+ 19:de:55:ec:8b:d3:be:84:38:5b:f4:01:e1:07:1e:44:c8:3d:
+ 74:d5:b0:9a:b8:70:e8:a7:33:6b:c6:2c:1b:f2:12:e3:c7:7f:
+ 26:e5:11:56:f2:04:c0:6d:e9:b7:a0:ac:3a:3d:fa:77:7b:ed:
+ e7:fa:ef:99:de:a6:3c:8c:6c:da:96:56:9b:62:bc:11:5d:31:
+ 91:93:4a:43:9e:d1:89:c1:dc:62:7a:dd:24:18:91:b3:cd:28:
+ 74:e7:68:e5:54:15:9a:7a:9f:ef:2e:72:c7:e9:8c:71:5f:ed:
+ b3:51:c0:29:49:4c:e1:0d:f5:73:fe:d2:14:2f:c9:07:df:7b:
+ 39:16:91:1a:3b:63:fd:f9:18:a9:69:f4:99:35:c9:4a:7b:ef:
+ 17:40:d2:d5
+-----BEGIN CERTIFICATE-----
+MIIDhDCCAmygAwIBAgIBDDANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowDjEMMAoGA1UEAwwDTkM1
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1ayAFLnSeK1DyFFpPph/
+vahXo2UoGW1E5Wpd98Ix7U5mqfHSnTa2uZg/2FTS6Xc6+5/VyfnJ31632jRC9svj
+ZuC3WoKbdyAPsRceKnBi0meboFTyG6SfBre7r1pvVbF++CDL7eRV2BjLTw7DxF0T
+/P3XsRzFWIHP6VZ4Z3iq/gYpnjQ+S/5+7CIWFdYrw24XI0IbKC4hEzGLijMjomf2
+I7zyaJtxkpJ/IwlTlmc8/sKBiJ8AVZNNs+cCARNISzQSRW5IaoghM/9aA0lWomlk
+l6RTDpBzhMa4KLBbwGeF/Zol8s8OeSR4IIDwLK5GjsXPKb5/9X1zbaoLEFlP1kbx
+vwIDAQABo4HrMIHoMB0GA1UdDgQWBBSdRKorm0xmTCDFMrLqCBMTaRdJsTAfBgNV
+HSMEGDAWgBT/i/ylaTYvYjvUG+1YL+l3PSmBgzA3BggrBgEFBQcBAQQrMCkwJwYI
+KwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAsBgNVHR8EJTAj
+MCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYDVR0PAQH/BAQD
+AgEGMA8GA1UdEwEB/wQFMAMBAf8wHgYDVR0eAQH/BBQwEqAQMA6CDHRlc3QuaW52
+YWxpZDANBgkqhkiG9w0BAQsFAAOCAQEAnonApHKY/4iTPhbX4ArcldM1jkv48yWa
+ZGuCCkesEHZEu6woYeAoZ1jWNg5m2hnWvS078nR44qj0TT30FnQJYlUp6NeWoLc2
+U7qodLsTdFypkLn0BlZXq75VrxIKHOsTSsw30pEVSPlwDaTCGd5V7IvTvoQ4W/QB
+4QceRMg9dNWwmrhw6Kcza8YsG/IS48d/JuURVvIEwG3pt6CsOj36d3vt5/rvmd6m
+PIxs2pZWm2K8EV0xkZNKQ57RicHcYnrdJBiRs80odOdo5VQVmnqf7y5yx+mMcV/t
+s1HAKUlM4Q31c/7SFC/JB997ORaRGjtj/fkYqWn0mTXJSnvvF0DS1Q==
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ov_name_constraints/nc-int-permit-o1.pem b/chromium/net/data/ov_name_constraints/nc-int-permit-o1.pem
new file mode 100644
index 00000000000..ea587e723d9
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/nc-int-permit-o1.pem
@@ -0,0 +1,92 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 8 (0x8)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2021 GMT
+ Subject: CN=NC1
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d5:ac:80:14:b9:d2:78:ad:43:c8:51:69:3e:98:
+ 7f:bd:a8:57:a3:65:28:19:6d:44:e5:6a:5d:f7:c2:
+ 31:ed:4e:66:a9:f1:d2:9d:36:b6:b9:98:3f:d8:54:
+ d2:e9:77:3a:fb:9f:d5:c9:f9:c9:df:5e:b7:da:34:
+ 42:f6:cb:e3:66:e0:b7:5a:82:9b:77:20:0f:b1:17:
+ 1e:2a:70:62:d2:67:9b:a0:54:f2:1b:a4:9f:06:b7:
+ bb:af:5a:6f:55:b1:7e:f8:20:cb:ed:e4:55:d8:18:
+ cb:4f:0e:c3:c4:5d:13:fc:fd:d7:b1:1c:c5:58:81:
+ cf:e9:56:78:67:78:aa:fe:06:29:9e:34:3e:4b:fe:
+ 7e:ec:22:16:15:d6:2b:c3:6e:17:23:42:1b:28:2e:
+ 21:13:31:8b:8a:33:23:a2:67:f6:23:bc:f2:68:9b:
+ 71:92:92:7f:23:09:53:96:67:3c:fe:c2:81:88:9f:
+ 00:55:93:4d:b3:e7:02:01:13:48:4b:34:12:45:6e:
+ 48:6a:88:21:33:ff:5a:03:49:56:a2:69:64:97:a4:
+ 53:0e:90:73:84:c6:b8:28:b0:5b:c0:67:85:fd:9a:
+ 25:f2:cf:0e:79:24:78:20:80:f0:2c:ae:46:8e:c5:
+ cf:29:be:7f:f5:7d:73:6d:aa:0b:10:59:4f:d6:46:
+ f1:bf
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 9D:44:AA:2B:9B:4C:66:4C:20:C5:32:B2:EA:08:13:13:69:17:49:B1
+ X509v3 Authority Key Identifier:
+ keyid:FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Root.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Root.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Name Constraints: critical
+ Permitted:
+ DirName:O = O1
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 54:86:68:b2:45:d5:99:30:3f:5b:5c:f6:97:d3:26:0c:f1:4f:
+ 46:39:37:85:be:cf:3a:b8:57:b4:7d:30:51:28:56:81:cc:3f:
+ d6:17:ba:5a:00:1a:23:03:e4:67:7c:38:72:f9:7d:9d:e2:7b:
+ 73:a2:e8:36:39:84:89:1a:67:ff:a7:96:94:7f:4d:01:53:64:
+ ef:04:31:88:82:eb:40:87:63:70:99:80:d2:07:72:a6:4d:c5:
+ 3a:64:2a:4a:c7:40:9e:1f:7c:75:17:78:51:d9:f5:2f:66:8e:
+ 83:f2:d7:2c:f5:46:01:9d:a3:c9:f2:29:91:2f:47:43:1e:7d:
+ fd:83:f2:53:a6:de:b6:f0:9d:c1:26:c5:53:aa:d6:a9:47:13:
+ 71:e1:7b:ed:bd:7a:fc:98:1c:66:47:48:2d:7c:36:4d:f6:9f:
+ 11:f8:f2:fd:fe:5b:c4:c9:34:07:cc:15:5f:ca:26:e8:8f:eb:
+ be:53:20:e9:c1:5f:b1:4e:36:87:fa:b8:c8:b9:f7:cf:16:16:
+ 88:a6:27:a8:54:0b:ba:10:6b:b7:03:ff:e1:e5:26:e1:87:f4:
+ 90:19:d6:ed:92:25:f4:9e:16:bd:c9:97:d5:fe:82:d8:29:8b:
+ 47:1c:71:97:84:39:a6:7b:25:e4:f9:9f:1b:c1:da:39:db:0b:
+ e1:6e:3f:ce
+-----BEGIN CERTIFICATE-----
+MIIDhzCCAm+gAwIBAgIBCDANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowDjEMMAoGA1UEAwwDTkMx
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1ayAFLnSeK1DyFFpPph/
+vahXo2UoGW1E5Wpd98Ix7U5mqfHSnTa2uZg/2FTS6Xc6+5/VyfnJ31632jRC9svj
+ZuC3WoKbdyAPsRceKnBi0meboFTyG6SfBre7r1pvVbF++CDL7eRV2BjLTw7DxF0T
+/P3XsRzFWIHP6VZ4Z3iq/gYpnjQ+S/5+7CIWFdYrw24XI0IbKC4hEzGLijMjomf2
+I7zyaJtxkpJ/IwlTlmc8/sKBiJ8AVZNNs+cCARNISzQSRW5IaoghM/9aA0lWomlk
+l6RTDpBzhMa4KLBbwGeF/Zol8s8OeSR4IIDwLK5GjsXPKb5/9X1zbaoLEFlP1kbx
+vwIDAQABo4HuMIHrMB0GA1UdDgQWBBSdRKorm0xmTCDFMrLqCBMTaRdJsTAfBgNV
+HSMEGDAWgBT/i/ylaTYvYjvUG+1YL+l3PSmBgzA3BggrBgEFBQcBAQQrMCkwJwYI
+KwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAsBgNVHR8EJTAj
+MCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYDVR0PAQH/BAQD
+AgEGMA8GA1UdEwEB/wQFMAMBAf8wIQYDVR0eAQH/BBcwFaATMBGkDzANMQswCQYD
+VQQKDAJPMTANBgkqhkiG9w0BAQsFAAOCAQEAVIZoskXVmTA/W1z2l9MmDPFPRjk3
+hb7POrhXtH0wUShWgcw/1he6WgAaIwPkZ3w4cvl9neJ7c6LoNjmEiRpn/6eWlH9N
+AVNk7wQxiILrQIdjcJmA0gdypk3FOmQqSsdAnh98dRd4Udn1L2aOg/LXLPVGAZ2j
+yfIpkS9HQx59/YPyU6betvCdwSbFU6rWqUcTceF77b16/JgcZkdILXw2TfafEfjy
+/f5bxMk0B8wVX8om6I/rvlMg6cFfsU42h/q4yLn3zxYWiKYnqFQLuhBrtwP/4eUm
+4Yf0kBnW7ZIl9J4WvcmX1f6C2CmLRxxxl4Q5pnsl5PmfG8HaOdsL4W4/zg==
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ov_name_constraints/nc-int-permit-o2-o1-o3.pem b/chromium/net/data/ov_name_constraints/nc-int-permit-o2-o1-o3.pem
new file mode 100644
index 00000000000..664a9147ba7
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/nc-int-permit-o2-o1-o3.pem
@@ -0,0 +1,95 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 13 (0xd)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2021 GMT
+ Subject: CN=NC6
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d5:ac:80:14:b9:d2:78:ad:43:c8:51:69:3e:98:
+ 7f:bd:a8:57:a3:65:28:19:6d:44:e5:6a:5d:f7:c2:
+ 31:ed:4e:66:a9:f1:d2:9d:36:b6:b9:98:3f:d8:54:
+ d2:e9:77:3a:fb:9f:d5:c9:f9:c9:df:5e:b7:da:34:
+ 42:f6:cb:e3:66:e0:b7:5a:82:9b:77:20:0f:b1:17:
+ 1e:2a:70:62:d2:67:9b:a0:54:f2:1b:a4:9f:06:b7:
+ bb:af:5a:6f:55:b1:7e:f8:20:cb:ed:e4:55:d8:18:
+ cb:4f:0e:c3:c4:5d:13:fc:fd:d7:b1:1c:c5:58:81:
+ cf:e9:56:78:67:78:aa:fe:06:29:9e:34:3e:4b:fe:
+ 7e:ec:22:16:15:d6:2b:c3:6e:17:23:42:1b:28:2e:
+ 21:13:31:8b:8a:33:23:a2:67:f6:23:bc:f2:68:9b:
+ 71:92:92:7f:23:09:53:96:67:3c:fe:c2:81:88:9f:
+ 00:55:93:4d:b3:e7:02:01:13:48:4b:34:12:45:6e:
+ 48:6a:88:21:33:ff:5a:03:49:56:a2:69:64:97:a4:
+ 53:0e:90:73:84:c6:b8:28:b0:5b:c0:67:85:fd:9a:
+ 25:f2:cf:0e:79:24:78:20:80:f0:2c:ae:46:8e:c5:
+ cf:29:be:7f:f5:7d:73:6d:aa:0b:10:59:4f:d6:46:
+ f1:bf
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ 9D:44:AA:2B:9B:4C:66:4C:20:C5:32:B2:EA:08:13:13:69:17:49:B1
+ X509v3 Authority Key Identifier:
+ keyid:FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Root.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Root.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Name Constraints: critical
+ Permitted:
+ DirName:O = O2
+ DirName:O = O1
+ DirName:O = O3
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 7d:73:3b:2d:62:e6:69:68:ef:6a:1d:e4:2c:7a:89:49:4d:a7:
+ af:9f:5b:12:53:a6:58:4e:86:63:0d:fc:a2:2f:04:e9:c1:48:
+ 51:d2:67:04:10:80:80:24:96:4d:9b:ec:48:4a:17:89:61:44:
+ 2d:02:73:bd:ed:54:82:ad:50:f2:5b:ea:49:87:4b:7e:52:5c:
+ 0e:c3:33:b1:58:c4:7c:8f:26:32:cc:2e:97:d4:9e:59:5f:84:
+ fd:53:84:70:95:cc:e4:62:32:ad:5b:79:6d:9e:6b:40:c7:dc:
+ f2:25:87:63:cd:26:8d:32:e8:32:37:6a:38:04:84:7d:42:9e:
+ 37:9f:08:97:5e:c8:35:55:1f:5d:93:87:8d:ee:27:6a:19:dc:
+ 61:dd:b9:eb:83:48:96:6c:ba:27:48:31:d3:e8:df:68:95:de:
+ a1:05:db:be:79:37:f2:23:e1:93:06:9d:ec:08:93:c6:e3:d7:
+ 86:10:27:68:c2:23:82:82:a2:5a:84:90:54:a9:a7:ac:38:db:
+ ca:42:05:f5:04:2d:7c:f8:99:9c:06:2f:f2:23:2e:2b:f2:29:
+ 19:72:96:7a:74:d5:c6:09:c1:a0:e4:e5:88:6d:68:05:3a:72:
+ ff:3c:cc:8c:63:91:61:56:3e:7f:6b:7f:fc:9b:73:9c:d0:38:
+ 7a:87:d0:06
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIBDTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowDjEMMAoGA1UEAwwDTkM2
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1ayAFLnSeK1DyFFpPph/
+vahXo2UoGW1E5Wpd98Ix7U5mqfHSnTa2uZg/2FTS6Xc6+5/VyfnJ31632jRC9svj
+ZuC3WoKbdyAPsRceKnBi0meboFTyG6SfBre7r1pvVbF++CDL7eRV2BjLTw7DxF0T
+/P3XsRzFWIHP6VZ4Z3iq/gYpnjQ+S/5+7CIWFdYrw24XI0IbKC4hEzGLijMjomf2
+I7zyaJtxkpJ/IwlTlmc8/sKBiJ8AVZNNs+cCARNISzQSRW5IaoghM/9aA0lWomlk
+l6RTDpBzhMa4KLBbwGeF/Zol8s8OeSR4IIDwLK5GjsXPKb5/9X1zbaoLEFlP1kbx
+vwIDAQABo4IBFTCCAREwHQYDVR0OBBYEFJ1EqiubTGZMIMUysuoIExNpF0mxMB8G
+A1UdIwQYMBaAFP+L/KVpNi9iO9Qb7Vgv6Xc9KYGDMDcGCCsGAQUFBwEBBCswKTAn
+BggrBgEFBQcwAoYbaHR0cDovL3VybC1mb3ItYWlhL1Jvb3QuY2VyMCwGA1UdHwQl
+MCMwIaAfoB2GG2h0dHA6Ly91cmwtZm9yLWNybC9Sb290LmNybDAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBHBgNVHR4BAf8EPTA7oDkwEaQPMA0xCzAJ
+BgNVBAoMAk8yMBGkDzANMQswCQYDVQQKDAJPMTARpA8wDTELMAkGA1UECgwCTzMw
+DQYJKoZIhvcNAQELBQADggEBAH1zOy1i5mlo72od5Cx6iUlNp6+fWxJTplhOhmMN
+/KIvBOnBSFHSZwQQgIAklk2b7EhKF4lhRC0Cc73tVIKtUPJb6kmHS35SXA7DM7FY
+xHyPJjLMLpfUnllfhP1ThHCVzORiMq1beW2ea0DH3PIlh2PNJo0y6DI3ajgEhH1C
+njefCJdeyDVVH12Th43uJ2oZ3GHdueuDSJZsuidIMdPo32iV3qEF2755N/Ij4ZMG
+newIk8bj14YQJ2jCI4KColqEkFSpp6w428pCBfUELXz4mZwGL/IjLivyKRlylnp0
+1cYJwaDk5YhtaAU6cv88zIxjkWFWPn9rf/ybc5zQOHqH0AY=
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ov_name_constraints/root.pem b/chromium/net/data/ov_name_constraints/root.pem
new file mode 100644
index 00000000000..3b230921434
--- /dev/null
+++ b/chromium/net/data/ov_name_constraints/root.pem
@@ -0,0 +1,88 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=Root
+ Validity
+ Not Before: Jan 1 12:00:00 2015 GMT
+ Not After : Jan 1 12:00:00 2021 GMT
+ Subject: CN=Root
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:d6:58:29:fc:69:44:34:39:a5:91:06:35:ac:de:
+ 31:2a:f7:6f:f0:1a:c7:21:6e:83:cb:d2:5d:06:c1:
+ 9f:52:4d:ee:46:07:35:10:28:b5:5c:68:29:87:22:
+ 8e:c6:f7:7d:ed:89:05:28:9c:d1:6a:80:c6:44:fb:
+ 5c:bc:09:0c:37:f1:25:b7:3c:f9:01:84:72:03:dd:
+ 3b:02:5a:cb:5f:65:00:27:8c:ec:25:8b:2b:b0:8b:
+ 9b:60:3f:b6:b9:ba:53:68:88:3c:30:46:32:fa:d9:
+ a9:ce:aa:55:b5:ca:3e:51:e7:98:5e:d1:1b:0c:75:
+ d1:a0:7e:1f:44:ff:b4:62:c4:b4:d3:d9:5d:6d:71:
+ b2:c1:0a:59:b4:fc:60:74:4f:a3:df:64:7d:66:5e:
+ 4b:2a:9e:4e:e0:16:c5:aa:a3:0c:b9:60:a3:38:70:
+ 93:cc:ce:43:4b:6e:2b:60:b5:1f:c1:ff:ee:85:be:
+ 62:db:63:47:87:e1:3e:a2:4b:57:d6:ce:6e:f8:ce:
+ 7d:d3:8f:db:e1:2d:0a:57:39:0f:dd:6e:dd:4c:8a:
+ 05:7b:c9:97:e4:9e:0a:ff:99:c2:41:29:7a:06:b9:
+ 3c:f1:02:fe:3b:85:b5:ef:4a:ae:85:8c:75:66:62:
+ 72:0f:37:b4:aa:80:d5:21:43:70:04:e4:3e:00:f4:
+ af:39
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Subject Key Identifier:
+ FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+ X509v3 Authority Key Identifier:
+ keyid:FF:8B:FC:A5:69:36:2F:62:3B:D4:1B:ED:58:2F:E9:77:3D:29:81:83
+
+ Authority Information Access:
+ CA Issuers - URI:http://url-for-aia/Root.cer
+
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://url-for-crl/Root.crl
+
+ X509v3 Key Usage: critical
+ Certificate Sign, CRL Sign
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ Signature Algorithm: sha256WithRSAEncryption
+ 9a:2b:db:bf:99:c1:cc:a9:33:40:8f:5b:c9:a1:a5:6b:77:16:
+ f2:33:37:3a:40:a4:bd:59:cb:1c:b0:f1:a8:83:2b:e9:de:8e:
+ 6d:29:1c:d3:e6:e6:b9:ae:44:5c:0b:4b:84:9b:43:9f:23:6b:
+ 90:11:56:09:76:8a:3f:55:f5:21:31:c0:cd:f6:f3:97:e6:d1:
+ d7:d2:e7:8b:d4:df:94:0d:95:3e:63:95:99:d9:b6:e8:87:af:
+ 84:11:05:46:52:04:4b:b1:a7:e1:a5:b4:a0:ad:0f:2f:96:b4:
+ 01:12:8e:c9:ba:40:ff:3b:6f:a6:43:bf:0b:ab:a0:9e:c7:fc:
+ c6:f9:0b:c0:a6:4d:cc:f7:5f:d2:cd:09:17:82:5d:c9:c6:d7:
+ d7:f4:19:1a:dd:8f:66:2c:92:19:98:b4:49:f7:54:01:5c:29:
+ 21:91:d3:a8:4b:c4:95:0d:4f:db:a4:09:e0:99:0b:9f:c4:ef:
+ dd:fa:45:7a:13:a4:26:19:71:91:c7:61:e9:30:c8:0f:6a:de:
+ a1:9d:c8:fe:1d:ee:bc:27:03:bc:c2:39:fb:f2:fa:c8:55:dc:
+ dd:e9:c5:a8:2c:15:c0:5e:7d:42:b7:a0:01:80:30:7a:55:fe:
+ 77:9b:94:52:05:10:5b:df:60:88:2f:38:21:8a:d5:b0:1e:21:
+ 30:c4:29:8f
+-----BEGIN CERTIFICATE-----
+MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
+MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZYKfxpRDQ5pZEGNaze
+MSr3b/AaxyFug8vSXQbBn1JN7kYHNRAotVxoKYcijsb3fe2JBSic0WqAxkT7XLwJ
+DDfxJbc8+QGEcgPdOwJay19lACeM7CWLK7CLm2A/trm6U2iIPDBGMvrZqc6qVbXK
+PlHnmF7RGwx10aB+H0T/tGLEtNPZXW1xssEKWbT8YHRPo99kfWZeSyqeTuAWxaqj
+DLlgozhwk8zOQ0tuK2C1H8H/7oW+YttjR4fhPqJLV9bObvjOfdOP2+EtClc5D91u
+3UyKBXvJl+SeCv+ZwkEpega5PPEC/juFte9KroWMdWZicg83tKqA1SFDcATkPgD0
+rzkCAwEAAaOByzCByDAdBgNVHQ4EFgQU/4v8pWk2L2I71BvtWC/pdz0pgYMwHwYD
+VR0jBBgwFoAU/4v8pWk2L2I71BvtWC/pdz0pgYMwNwYIKwYBBQUHAQEEKzApMCcG
+CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
+IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCaK9u/mcHM
+qTNAj1vJoaVrdxbyMzc6QKS9WcscsPGogyvp3o5tKRzT5ua5rkRcC0uEm0OfI2uQ
+EVYJdoo/VfUhMcDN9vOX5tHX0ueL1N+UDZU+Y5WZ2bboh6+EEQVGUgRLsafhpbSg
+rQ8vlrQBEo7JukD/O2+mQ78Lq6Cex/zG+QvApk3M91/SzQkXgl3JxtfX9Bka3Y9m
+LJIZmLRJ91QBXCkhkdOoS8SVDU/bpAngmQufxO/d+kV6E6QmGXGRx2HpMMgPat6h
+ncj+He68JwO8wjn78vrIVdzd6cWoLBXAXn1Ct6ABgDB6Vf53m5RSBRBb32CILzgh
+itWwHiEwxCmP
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/39_months_based_on_last_day.pem b/chromium/net/data/ssl/certificates/39_months_based_on_last_day.pem
new file mode 100644
index 00000000000..80096963130
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/39_months_based_on_last_day.pem
@@ -0,0 +1,84 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 30 (0x1e)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, ST=California, L=Mountain View, O=Test CA, CN=Test Root CA
+ Validity
+ Not Before: Feb 28 00:00:00 2017 GMT
+ Not After : May 30 00:00:00 2020 GMT
+ Subject: C=US, ST=California, L=Mountain View, O=Test CA, CN=127.0.0.1
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:e0:95:35:0d:8e:3b:c4:7c:1d:ea:d6:1a:41:a9:
+ 4c:14:6e:3c:12:a3:01:55:fc:b5:ee:d5:7a:d3:4d:
+ b5:f4:9b:0e:57:50:cc:28:17:4f:68:93:5f:14:e2:
+ ac:c7:eb:1d:e1:13:82:b6:14:eb:9d:42:26:1e:3c:
+ 37:c7:73:e2:93:0f:d9:5b:e7:2f:46:60:54:e6:a4:
+ 1c:89:ac:9c:30:1f:29:bf:36:e2:88:8a:e5:ac:14:
+ 67:df:d7:93:38:85:d8:71:5a:5c:ae:80:d1:f9:ef:
+ 12:82:91:08:be:de:07:70:25:be:50:3c:c6:5e:e1:
+ 15:82:9d:1d:cb:2b:4c:b1:ea:2d:e4:6f:db:33:d8:
+ d3:27:d0:c1:8f:52:db:91:1a:b6:03:9e:fb:3b:49:
+ 7e:ef:4a:fd:38:b2:c6:26:ea:63:85:be:0f:50:c3:
+ 24:4c:36:dc:96:7b:ae:59:1f:c5:44:2a:14:76:71:
+ 39:ab:ac:0e:ad:bb:ca:32:94:9c:d4:5b:7d:71:6b:
+ c9:e8:4b:80:8f:e4:b8:07:bf:70:05:2f:52:b7:86:
+ 7c:ca:de:b3:b3:38:56:5f:35:96:15:94:c3:0d:fd:
+ 45:2b:38:ee:ca:ee:77:34:62:5d:85:57:d1:e3:30:
+ 24:0e:b1:5c:21:80:5b:24:82:01:67:25:12:a7:8b:
+ 3c:11
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ 39:50:0A:32:04:A7:EC:70:F4:1B:1E:68:F3:B3:40:57:A7:55:4D:8A
+ X509v3 Authority Key Identifier:
+ keyid:9B:26:0B:8A:98:A9:BB:1D:B9:1F:1C:E3:1A:40:33:ED:8E:17:88:AB
+
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ X509v3 Subject Alternative Name:
+ IP Address:127.0.0.1
+ Signature Algorithm: sha256WithRSAEncryption
+ 83:f0:0b:fc:3c:6e:40:6b:00:58:de:43:2a:d4:ea:08:8c:88:
+ 9c:02:76:7d:9f:55:08:fc:da:c0:fe:9a:07:84:c2:5d:85:06:
+ ec:ee:e4:8a:c4:c1:f2:6e:6e:a8:bc:8f:de:d2:b4:39:43:c8:
+ 99:56:57:b8:f7:2e:8c:90:a5:fd:7d:1f:79:8d:e1:2a:59:65:
+ e6:9b:2b:5d:62:7b:b0:e5:66:45:5e:fe:a3:44:52:34:40:90:
+ f6:35:dd:51:7d:38:07:0b:cd:84:ec:68:19:c5:c8:b4:0e:19:
+ 7f:f0:a8:92:33:59:8c:24:a8:7d:f0:b3:4b:3c:20:09:5d:b6:
+ 78:a2:b3:1e:86:e3:88:ff:94:00:74:97:d0:41:91:45:f5:1d:
+ 32:e2:3f:fa:cc:90:2a:fd:8d:e2:84:e5:1b:16:83:13:3e:1c:
+ 6b:9f:55:0a:b9:00:16:b7:3f:07:68:1b:60:cf:46:56:ba:54:
+ 05:06:90:6b:40:16:cd:4c:67:46:87:f1:05:35:c6:ca:07:fb:
+ e2:ca:c1:ed:37:1e:a5:ec:87:ca:4f:bf:98:e6:07:8e:66:76:
+ 26:67:b9:28:5f:95:ef:83:35:09:94:ba:2b:48:53:51:0d:85:
+ 62:7e:b3:a3:d0:f7:44:62:14:21:bf:b8:99:2b:b6:0b:be:b8:
+ c9:ee:96:56
+-----BEGIN CERTIFICATE-----
+MIIDvzCCAqegAwIBAgIBHjANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
+A1UECgwHVGVzdCBDQTEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTE3MDIyODAw
+MDAwMFoXDTIwMDUzMDAwMDAwMFowYDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
+bGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB1Rlc3Qg
+Q0ExEjAQBgNVBAMMCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAOCVNQ2OO8R8HerWGkGpTBRuPBKjAVX8te7VetNNtfSbDldQzCgXT2iT
+XxTirMfrHeETgrYU651CJh48N8dz4pMP2VvnL0ZgVOakHImsnDAfKb824oiK5awU
+Z9/XkziF2HFaXK6A0fnvEoKRCL7eB3AlvlA8xl7hFYKdHcsrTLHqLeRv2zPY0yfQ
+wY9S25EatgOe+ztJfu9K/TiyxibqY4W+D1DDJEw23JZ7rlkfxUQqFHZxOausDq27
+yjKUnNRbfXFryehLgI/kuAe/cAUvUreGfMres7M4Vl81lhWUww39RSs47srudzRi
+XYVX0eMwJA6xXCGAWySCAWclEqeLPBECAwEAAaOBgDB+MAwGA1UdEwEB/wQCMAAw
+HQYDVR0OBBYEFDlQCjIEp+xw9BseaPOzQFenVU2KMB8GA1UdIwQYMBaAFJsmC4qY
+qbsduR8c4xpAM+2OF4irMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAP
+BgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQCD8Av8PG5AawBY3kMq
+1OoIjIicAnZ9n1UI/NrA/poHhMJdhQbs7uSKxMHybm6ovI/e0rQ5Q8iZVle49y6M
+kKX9fR95jeEqWWXmmytdYnuw5WZFXv6jRFI0QJD2Nd1RfTgHC82E7GgZxci0Dhl/
+8KiSM1mMJKh98LNLPCAJXbZ4orMehuOI/5QAdJfQQZFF9R0y4j/6zJAq/Y3ihOUb
+FoMTPhxrn1UKuQAWtz8HaBtgz0ZWulQFBpBrQBbNTGdGh/EFNcbKB/viysHtNx6l
+7IfKT7+Y5geOZnYmZ7koX5XvgzUJlLorSFNRDYVifrOj0PdEYhQhv7iZK7YLvrjJ
+7pZW
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/certificates/README b/chromium/net/data/ssl/certificates/README
index b7b18e3cac8..8f27c1549de 100644
--- a/chromium/net/data/ssl/certificates/README
+++ b/chromium/net/data/ssl/certificates/README
@@ -44,6 +44,10 @@ unit tests.
This is an X.509 v1 certificate that omits the version field. Used to
test that the certificate version gets the default value v1.
+- comodo.pem : A certificate chain for comodo.com which contains signed
+ certificate timestamps that conform to Chrome's Certificate Transparency
+ policy as of December 2017.
+
- ct-test-embedded-cert.pem
- ct-test-embedded-with-intermediate-chain.pem
- ct-test-embedded-with-intermediate-preca-chain.pem
diff --git a/chromium/net/data/ssl/certificates/comodo-chain.pem b/chromium/net/data/ssl/certificates/comodo-chain.pem
new file mode 100644
index 00000000000..5c4c5d5bc57
--- /dev/null
+++ b/chromium/net/data/ssl/certificates/comodo-chain.pem
@@ -0,0 +1,117 @@
+ 0 s:/serialNumber=3830138/jurisdictionC=US/jurisdictionST=Delaware/businessCategory=Private Organization/C=US/postalCode=07013/ST=NJ/L=Clifton/street=Suite 100/street=1255 Broad St./O=Comodo Group Inc./OU=COMODO EV SSL/OU=COMODO EV SGC SSL/CN=www.comodo.com
+ i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Extended Validation Secure Server CA
+-----BEGIN CERTIFICATE-----
+MIIHvzCCBqegAwIBAgIRANSYNM/GMmLagfa+3OOk63swDQYJKoZIhvcNAQELBQAw
+gZIxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
+BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTgwNgYD
+VQQDEy9DT01PRE8gUlNBIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZl
+ciBDQTAeFw0xNTEyMDEwMDAwMDBaFw0xODAyMjUyMzU5NTlaMIIBMzEQMA4GA1UE
+BRMHMzgzMDEzODETMBEGCysGAQQBgjc8AgEDEwJVUzEZMBcGCysGAQQBgjc8AgEC
+EwhEZWxhd2FyZTEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24xCzAJBgNV
+BAYTAlVTMQ4wDAYDVQQREwUwNzAxMzELMAkGA1UECBMCTkoxEDAOBgNVBAcTB0Ns
+aWZ0b24xEjAQBgNVBAkTCVN1aXRlIDEwMDEXMBUGA1UECRMOMTI1NSBCcm9hZCBT
+dC4xGjAYBgNVBAoTEUNvbW9kbyBHcm91cCBJbmMuMRYwFAYDVQQLEw1DT01PRE8g
+RVYgU1NMMRowGAYDVQQLExFDT01PRE8gRVYgU0dDIFNTTDEXMBUGA1UEAxMOd3d3
+LmNvbW9kby5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5S2RD
+XGjch2spb10rLVCA4TgeB/TiNLHPczeKMJzIY9qKUGQfcYCTwfWe2E1xBer/i0OX
+IUca+/Br3HTK2qkNoc/nuFkJJ3ej17A9Kv1EYhsN+2gHobKEy+sMTJyGmFVo98nu
+V9mmiEWM7Bi0Y6YRVYCOey4K2yUwSK1MOgc10RzbwDsk+P2mvTzvPi8QZzd4I36/
+xlFFhk39VKY94PorJCzF/6qifmNnIjxMkrmSKJKKQaZu8vgbshqlj3+TkeCtIjdR
+77OcZuROMFdnKsp8JKAq9bzXmDkwlDmUzxAzgYmAvqCwQvNWtJrm0SeiEkNsoK5F
+xadrfw6OO7BCGXiNAgMBAAGjggNqMIIDZjAfBgNVHSMEGDAWgBQ52v/KKBSKqHQT
+CLnkDqnS+n6daTAdBgNVHQ4EFgQURD5zMOsLG6ennQ/aeZZNGofpnSEwDgYDVR0P
+AQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwNAYDVR0lBC0wKwYIKwYBBQUHAwEGCCsG
+AQUFBwMCBgorBgEEAYI3CgMDBglghkgBhvhCBAEwRgYDVR0gBD8wPTA7BgwrBgEE
+AbIxAQIBBQEwKzApBggrBgEFBQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNv
+bS9DUFMwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5jb21vZG9jYS5jb20v
+Q09NT0RPUlNBRXh0ZW5kZWRWYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3JsMIGH
+BggrBgEFBQcBAQR7MHkwUQYIKwYBBQUHMAKGRWh0dHA6Ly9jcnQuY29tb2RvY2Eu
+Y29tL0NPTU9ET1JTQUV4dGVuZGVkVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNy
+dDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMCUGA1UdEQQe
+MByCDnd3dy5jb21vZG8uY29tggpjb21vZG8uY29tMIIBfQYKKwYBBAHWeQIEAgSC
+AW0EggFpAWcAdQBo9pj4H2SCvjqM7rkoHUz8cVFdZ5PURNEKZ6y7T0/7xAAAAVFd
+vZuJAAAEAwBGMEQCIFgtCr54QYrnialeZiHFahZ53zOFitPzHXGvdTD7zE5FAiBB
+nIm4gBmHRmwcOpULvvSYddTKSZf9JS7jeLU2MCAmTQB2AFYUBpov18Ls0/XhvUSy
+PsdGdrm8mRFcwO+UmFXWidDdAAABUV29mSgAAAQDAEcwRQIgeWjpcDhaY/OmsZcO
+ftDFcRt2BssJY0ge4SDzp+8qTnQCIQCOt7vthV2FG1RePMXs8hOcCdEKAcJZX3wx
+GaGd4RfHHwB2AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABUV29
+m5wAAAQDAEcwRQIgKwZCD9lxvSFCpfnFVYPSneWhjbY9pnOJQjKckQ87anQCIQCG
+7hD5EOZ7F2XZLTdTSjvwrgPkIXY376+0RC4r9VzGkTANBgkqhkiG9w0BAQsFAAOC
+AQEAHVZgKwtIKcxJg6k5THIICJ63vZyaPJN21HVYPAN/heDUcbYzOqP0F+v+ahj5
+yNiRhSji/xxcOf5bWT158dHQoMtC1Ld1dI3lttVAvDTgXOApbmc8N0Xpjvapag3r
+b0IYW5SJio0qn1VxgeSsf0UCBTyw0N8lgbaIr3FHw2SP2rUS8PUixFRK52MYnyEp
+6Imz730Adl0RgUvp7mzRcWVDK4i6sPRqV6my68XsyaBcQr2qKALQK0Js+mE/0850
+47USqZ1XjbUke47OPxdlF85uUtIUSGquHTWnxrqy7FLMPIu9HL8XGo3vVlTYCCsb
+d6V/RWexyzZiHDGA1ToA0Y16Aw==
+-----END CERTIFICATE-----
+ 1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Extended Validation Secure Server CA
+ i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
+-----BEGIN CERTIFICATE-----
+MIIGDjCCA/agAwIBAgIQBqdDgNTr/tQ1taP34Wq92DANBgkqhkiG9w0BAQwFADCB
+hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
+BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTIwMjEy
+MDAwMDAwWhcNMjcwMjExMjM1OTU5WjCBkjELMAkGA1UEBhMCR0IxGzAZBgNVBAgT
+EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
+Q09NT0RPIENBIExpbWl0ZWQxODA2BgNVBAMTL0NPTU9ETyBSU0EgRXh0ZW5kZWQg
+VmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAlVbeVLTf1QJJe9FbXKKyHo+cK2JMK40SKPMalaPGEP0p3uGf
+CzhAk9HvbpUQ/OGQF3cs7nU+e2PsYZJuTzurgElr3wDqAwB/L3XVKC/sVmePgIOj
+vdwDmZOLlJFWW6G4ajo/Br0OksxgnP214J9mMF/b5pTwlWqvyIqvgNnmiDkBfBzA
+xSr3e5Wg8narbZtyOTDr0VdVAZ1YEZ18bYSPSeidCfw8/QpKdhQhXBZzQCMZdMO6
+WAqmli7eNuWf0MLw4eDBYuPCGEUZUaoXHugjddTI0JYT/8ck0YwLJ66eetw6YWNg
+iJctXQUL5Tvrrs46R3N2qPos3cCHF+msMJn4HwIDAQABo4IBaTCCAWUwHwYDVR0j
+BBgwFoAUu69+Aj36pvE8hI6t7jiY7NkyMtQwHQYDVR0OBBYEFDna/8ooFIqodBMI
+ueQOqdL6fp1pMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMD4G
+A1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5j
+b21vZG8uY29tL0NQUzBMBgNVHR8ERTBDMEGgP6A9hjtodHRwOi8vY3JsLmNvbW9k
+b2NhLmNvbS9DT01PRE9SU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBxBggr
+BgEFBQcBAQRlMGMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29tb2RvY2EuY29t
+L0NPTU9ET1JTQUFkZFRydXN0Q0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
+cC5jb21vZG9jYS5jb20wDQYJKoZIhvcNAQEMBQADggIBAERCnUFRK0iIXZebeV4R
+AUpSGXtBLMeJPNBy3IX6WK/VJeQT+FhlZ58N/1eLqYVeyqZLsKeyLeCMIs37/3mk
+jCuN/gI9JN6pXV/kD0fQ22YlPodHDK4ixVAihNftSlka9pOlk7DgG4HyVsTIEFPk
+1Hax0VtpS3ey4E/EhOfUoFDuPPpE/NBXueEoU/1Tzdy5H3pAvTA/2GzS8+cHnx8i
+teoiccsq8FZ8/qyo0QYPFBRSTP5kKwxpKrgNUG4+BAe/eiCL+O5lCeHHSQgyPQ0o
+fkkdt0rvAucNgBfIXOBhYsvss2B5JdoaZXOcOBCgJjqwyBZ9kzEi7nQLiMBciUEA
+KKlHMd99SUWa9eanRRrSjhMQ34Ovmw2tfn6dNVA0BM7pINae253UqNpktNEvWS5e
+ojZh1CSggjMziqHRbO9haKPl0latxf1eYusVqHQSTC8xjOnB3xBLAer2VBvNfzu9
+XJ/B288ByvK6YBIhMe2pZLiySVgXbVrXzYxtvp5/4gJYp9vDLVj2dAZqmvZh+fYA
+tmnYOosxWd2R5nwnI4fdAw+PKowegwFOAWEMUnNt/AiiuSpm5HZNMaBWm9lTjaK2
+jwLI5jqmBNFI+8NKAnb9L9K8E7bobTQk+p0pisehKxTxlgBzuRPpwLk6R1YCcYAn
+pLwltum95OmYdBbxN4SBB7SC
+-----END CERTIFICATE-----
+ 2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
+ i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
+-----BEGIN CERTIFICATE-----
+MIIFdDCCBFygAwIBAgIQJ2buVutJ846r13Ci/ITeIjANBgkqhkiG9w0BAQwFADBv
+MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk
+ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF
+eHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFow
+gYUxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
+BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMSswKQYD
+VQQDEyJDT01PRE8gUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkq
+hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAkehUktIKVrGsDSTdxc9EZ3SZKzejfSNw
+AHG8U9/E+ioSj0t/EFa9n3Byt2F/yUsPF6c947AEYe7/EZfH9IY+Cvo+XPmT5jR6
+2RRr55yzhaCCenavcZDX7P0N+pxs+t+wgvQUfvm+xKYvT3+Zf7X8Z0NyvQwA1onr
+ayzT7Y+YHBSrfuXjbvzYqOSSJNpDa2K4Vf3qwbxstovzDo2a5JtsaZn4eEgwRdWt
+4Q08RWD8MpZRJ7xnw8outmvqRsfHIKCxH2XeSAi6pE6p8oNGN4Tr6MyBSENnTnIq
+m1y9TBsoilwie7SrmNnu4FGDwwlGTm0+mfqVF9p8M1dBPI1R7Qu2XK8sYxrfV8g/
+vOldxJuvRZnio1oktLqpVj3Pb6r/SVi+8Kj/9Lit6Tf7urj0Czr56ENCHonYhMsT
+8dm74YlguIwoVqwUHZwK53Hrzw7dPamWoUi9PPevtQ0iTMARgexWO/bTouJbt7IE
+IlKVgJNp6I5MZfGRAy1wdALqi2cVKWlSArvX31BqVUa/oKMoYX9w0MOiqiwhqkfO
+KJwGRXa/ghgntNWutMtQ5mv0TIZxMOmm3xaG4Nj/QN370EKIf6MzOi5cHkERgWPO
+GHFrK+ymircxXDpqR+DDeVnWIBqv8mqYqnK8V0rSS527EPywTEHl7R09XiidnMy/
+s1Hap0flhFMCAwEAAaOB9DCB8TAfBgNVHSMEGDAWgBStvZh6NLQm9/rEJlTvA73g
+JMtUGjAdBgNVHQ4EFgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQD
+AgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAGBgRVHSAAMEQGA1UdHwQ9
+MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9BZGRUcnVzdEV4dGVy
+bmFsQ0FSb290LmNybDA1BggrBgEFBQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6
+Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggEBAGS/g/FfmoXQ
+zbihKVcN6Fr30ek+8nYEbvFScLsePP9NDXRqzIGCJdPDoCpdTPW6i6FtxFQJdcfj
+Jw5dhHk3QBN39bSsHNA7qxcS1u80GH4r6XnTq1dFDK8o+tDb5VCViLvfhVdpfZLY
+Uspzgb8c8+a4bmYRBbMelC1/kZWSWfFMzqORcUx8Rww7Cxn2obFshj5cqsQugsv5
+B5a6SE2Q8pTIqXOi6wZ7I53eovNNVZ96YUWYGGjHXkBrI/V5eu+MtWuLt29G9Hvx
+PUsE2JOAWVrgQSQdso8VYFhH2+9uRv0V9dlfmrPb2LjkQLPNlzmuhbsdjrzch5vR
+pu/xO28QOG8=
+-----END CERTIFICATE-----
diff --git a/chromium/net/data/ssl/root_stores/root_stores.json b/chromium/net/data/ssl/root_stores/root_stores.json
index c2d141e1b33..96dc9e1693c 100644
--- a/chromium/net/data/ssl/root_stores/root_stores.json
+++ b/chromium/net/data/ssl/root_stores/root_stores.json
@@ -30,7 +30,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"007e452fd5cf838946696dfe37a2db2ef3991436d27bcbab45922053c15a87a8": [
"windows/080328202117",
@@ -79,7 +80,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"00ab444abd6bdba33da8de569ac4ecde326d1be1a61442d5eec3975a0c243f04": [
"windows/070201011524",
@@ -133,7 +135,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"02ed0eb28c14da45165c566791700d6451d7fb56f0b2ab1d3b8eb070e56edff5": [
"android/kitkat-cts-release",
@@ -148,6 +151,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -159,6 +163,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -167,6 +174,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/130626232015",
"windows/131003230417",
@@ -189,7 +197,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"03458b6abeecc214953d97149af45391691de9f9cdcc2647863a3d67c95c243b": [
"android/kitkat-cts-release",
@@ -242,6 +251,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -253,6 +263,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -262,6 +275,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/100503224537",
"windows/100719231554",
@@ -300,7 +314,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"0378b202ccabba99a12e569a11a077db1edb39482061c75d0073059d9ab5b513": [
"windows/071219233937",
@@ -339,6 +354,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
@@ -385,7 +401,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"04048028bf1f2864d48f9ad4d83294366a828856553f3b14303f90147f5d40ef": [
"android/kitkat-cts-release",
@@ -400,6 +417,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -411,6 +429,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -420,6 +441,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/091029013045",
"windows/100503224537",
@@ -459,7 +481,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"04acfb3b24793f300f67ef87e44dd72cb9b28b204f389a7cd5ae28785c7d42cd": [
"macos/10.10.0",
@@ -473,6 +496,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -519,14 +545,16 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"04f1bec36951bc1454a904ce32890c5da3cde1356b7900f6e62dfa2041ebad51": [
"windows/170228174808",
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"0536801fbb443b3e905fd6d70d8c81eb88551be8061299110d2b4f82e64cade1": [
"windows/100719231554",
@@ -565,7 +593,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"058a40323ec8c46262c3052a5d357b91ac24d3da26351b3ff4407e99f7a4e9b4": [
"windows/070201011524",
@@ -619,7 +648,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"05d38c2a70bfc500ccb0cb509159b46b065c6ac9cb42d2e6f16167841434572a": [
"windows/120223022238",
@@ -648,7 +678,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"063e4afac491dfd332f3089b8542e94617d893d7fe944e10a7937ee29d9693c0": [
"android/kitkat-cts-release",
@@ -663,6 +694,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -674,6 +706,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -682,6 +717,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/090501224247",
"windows/090825180842",
@@ -724,7 +760,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"0687260331a72403d909f105e69bcf0d32e1bd2493ffc6d9206d11bcd6770739": [
"android/kitkat-cts-release",
@@ -739,6 +776,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -750,6 +788,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -759,6 +800,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -812,7 +854,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"06a2c9a3379ab3c156159a27ca9ecdbd4ef75309b409cf70aeca9a12330f380e": [
"macos/10.9.0",
@@ -884,7 +927,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"07453d53793bf41819a5251c69f88e2bb344b59ca828b5a543781599eaf3d602": [
"windows/070109202240",
@@ -926,12 +970,14 @@
],
"0753e940378c1bd5e3836e395daea5cb839e5046f1bd0eae1951cf10fec7c965": [
"mozilla/2.18",
+ "mozilla/2.20",
"windows/161112005943",
"windows/170228174808",
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"075bfcca2d55ae6e35742c32afd0ca8ea4c958feefc23224999541c033d69c8d": [
"windows/120125230451",
@@ -961,7 +1007,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"0771920c8cb874d5c5a4dc0d6a51a2d495d38c4de2cd5b83d2a06faa051935f6": [
"windows/121102212406",
@@ -988,7 +1035,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"0791ca0749b20782aad3c7d7bd0cdfc9485835843eb2d7996009ce43ab6c6927": [
"android/kitkat-cts-release",
@@ -1085,7 +1133,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"0a81ec5a929777f145904af38d5d509f66b5e2c58fcdb531058b0e17f3f0b41b": [
"android/kitkat-cts-release",
@@ -1100,6 +1149,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -1111,6 +1161,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -1120,6 +1173,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/100503224537",
"windows/100719231554",
@@ -1158,7 +1212,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"0b5eed4e846403cf55e065848440ed2a82758bf5b9aa1f253d4613cfa080ff3f": [
"android/kitkat-cts-release",
@@ -1259,7 +1314,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"0c0b6b2bd1edd7b27fead157f8e846b335b784a39f06c47216c8746f64c5ceda": [
"windows/140912180251",
@@ -1278,7 +1334,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"0c258a12a5674aef25f28ba7dcfaeceea348e541e6f5cc4ee63b71b361606ac3": [
"android/kitkat-cts-release",
@@ -1293,6 +1350,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -1304,6 +1362,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -1366,7 +1427,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"0c2cd63df7806fa399ede809116b575bf87989f06518f9808c860503178baf66": [
"android/kitkat-cts-release",
@@ -1381,6 +1443,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -1392,6 +1455,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -1401,6 +1467,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -1438,6 +1505,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -1479,7 +1549,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"0ed3ffab6c149c8b4e71058e8668d429abfda681c2fff508207641f0d751a3e5": [
"macos/10.10.0",
@@ -1493,6 +1564,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5"
@@ -1566,7 +1640,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"0f993c8aef97baaf5687140ed59ad1821bb4afacf0aa9a58b5d57a338a3afbcb": [
"android/kitkat-cts-release",
@@ -1581,6 +1656,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -1592,6 +1668,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -1601,6 +1680,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -1654,7 +1734,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"126bf01c1094d2f0ca2e352380b3c724294546ccc65597bef7f12d8a171f1984": [
"macos/10.10.0",
@@ -1668,6 +1749,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -1691,7 +1775,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"12d480c1a3c664781b99d9df0e9faf3f1cacee1b3c30c3123a337a4a454ffed2": [
"windows/071219233937",
@@ -1741,7 +1826,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"136335439334a7698016a0d324de72284e079d7b5220bb8fbd747816eebebaca": [
"android/kitkat-cts-release",
@@ -1756,6 +1842,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -1767,6 +1854,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -1775,6 +1865,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/090501224247",
"windows/090825180842",
@@ -1817,7 +1908,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"1465fa205397b876faa6f0a9958e5590e40fcc7faa4fb7c2c8677521fb5fb658": [
"android/kitkat-cts-release",
@@ -1832,6 +1924,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -1843,6 +1936,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -1852,6 +1948,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -1905,7 +2002,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"1501f89c5c4dcf36cf588a17c9fd7cfceb9ee01e8729be355e25de80eb6284b4": [
"windows/160414222039",
@@ -1915,16 +2013,22 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"152a402bfcdf2cd548054d2275b39c7fca3ec0978078b0f0ea76e561a6c7433e": [
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/150618202535",
"windows/150723231635",
@@ -1940,7 +2044,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"1594cb5b826c315de3bc932c56895ff23a3a988b5dc1f034d214dfd858d89ee8": [
"windows/070109202240",
@@ -1982,7 +2087,8 @@
],
"15d5b8774619ea7d54ce1ca6d0b0c403e037a917f131e8a04e1e6b7a71babce5": [
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"15f0ba00a3ac7af3ac884c072b1011a077bd77c097f40164b2f8598abd83860c": [
"android/kitkat-cts-release",
@@ -1997,6 +2103,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -2008,6 +2115,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -2017,6 +2127,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -2055,6 +2166,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -2066,6 +2178,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -2075,6 +2190,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -2128,7 +2244,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"1793927a0614549789adce2f8f34f7f0b66d0f3ae3a3b84d21ec15dbba4fadc7": [
"android/kitkat-cts-release",
@@ -2143,14 +2260,19 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/081103235012",
"windows/090203164005",
@@ -2195,7 +2317,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"179fbc148a3dd00fd24ea13458cc43bfa7f59c8182d783a513f6ebec100c8924": [
"android/lollipop-mr1-cts-release",
@@ -2206,6 +2329,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -2217,6 +2341,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -2225,6 +2352,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/130626232015",
"windows/131003230417",
@@ -2247,14 +2375,20 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"18ce6cfe7bf14e60b2e347b8dfe868cb31d02ebb3ada271569f50343b46db3a4": [
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"windows/160113232859",
"windows/160123000836",
"windows/160128175153",
@@ -2265,7 +2399,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"18f1fc7f205df8adddeb7fe007dd57e3af375a9c4d8d73546bf4f1fed1e18d35": [
"android/kitkat-cts-release",
@@ -2280,6 +2415,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -2291,6 +2427,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -2300,6 +2439,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -2353,12 +2493,14 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"19abcdff3a74402fa8f0ca206bf7fab0dffff3ae2bbd719584d21090a4353207": [
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"1a0d20445de5ba1862d19ef880858cbce50102b36e8f0a040c3c69e74522fe6e": [
"windows/110919210309",
@@ -2390,7 +2532,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"1a2512cda6744abea11432a2fdc9f8c088db5a98c89e13352574cde4d9e80cdd": [
"windows/140912180251",
@@ -2409,7 +2552,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"1aa980c8c0d316f25029978982f033cbb3a3f4188d669f2de6a8d84ee00a1575": [
"windows/080328202117",
@@ -2458,14 +2602,20 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"1ba5b2aa8c65401a82960118f80bec4f62304d83cec4713a19c39c011ea46db4": [
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"windows/160113232859",
"windows/160123000836",
"windows/160128175153",
@@ -2476,7 +2626,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"1ba622b36325544ae922afc22ef9d367943794f6e16874f368a733c65c9d5279": [
"windows/111018233154",
@@ -2507,7 +2658,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"1c01c6f4dbb2fefc22558b2bca32563f49844acfc32b7be4b0ff599f9e8c7af7": [
"android/kitkat-cts-release",
@@ -2566,7 +2718,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"1d4f0596fca2611d09f84c78f2ea565ef2eab9cfc272a1718bd336e6e0ae021a": [
"windows/070109202240",
@@ -2634,7 +2787,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"1e49ac5dc69e86d0565da2c1305c419330b0b781bfec50e54a1b35af7fddd501": [
"macos/10.11.0",
@@ -2645,6 +2799,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"windows/100927165108",
"windows/110125205412",
"windows/110218005058",
@@ -2680,7 +2837,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"1e51942b84fd467bf77d1c89da241c04254dc8f3ef4c22451fe7a89978bdcd4f": [
"windows/160916174005",
@@ -2689,7 +2847,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"1e910b40c08184c0ca20468e824502ff2485163f77b03bb73296823f03885621": [
"windows/111018233154",
@@ -2720,21 +2879,24 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"209e956af04df3996507c887d356230d6eb49fdbdd2d8a058ff50b8f80f690aa": [
"windows/170228174808",
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"2193cfea381211a1aeaa2de984e630643a87160b1208118145eafb8e1bc69958": [
"windows/170228174808",
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"21db20123660bb2ed418205da11ee7a85a65e2bc6e55b5af7e7899c8a266d92e": [
"android/kitkat-cts-release",
@@ -2760,6 +2922,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -2820,7 +2985,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"229ccc196d32c98421cc119e78486eebef603aecd525c6b88b47abb740692b96": [
"windows/150618202535",
@@ -2837,17 +3003,20 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"22a2c1f7bded704cc1e701b5f408c310880fe956b5de2a4a44f99c873a25a7c8": [
"mozilla/2.18",
+ "mozilla/2.20",
"windows/160916174005",
"windows/161112005943",
"windows/170228174808",
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"22e0d11dc9207e16c92b2ee18cfdb2c2e940626847921fc528cedd2f7932f714": [
"windows/070109202240",
@@ -2897,6 +3066,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -2947,7 +3119,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"2399561127a57125de8cefea610ddf2fa078b5c8067f4e828290bfb860e84b3c": [
"android/kitkat-cts-release",
@@ -2962,6 +3135,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -2973,6 +3147,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -2981,6 +3158,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/090825180842",
"windows/091013033632",
@@ -3022,7 +3200,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"248302a977f40f7dd6a2b770586adfaac3eb1e85fd1a102dbd7863c72b8f8ef2": [
"macos/10.10.0",
@@ -3036,7 +3215,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"2530cc8e98321502bad96f9b1fba1b099e2d299e0f4548bb914f363bc0d4531f": [
"android/kitkat-cts-release",
@@ -3051,6 +3231,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -3062,6 +3243,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -3070,6 +3254,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9"
],
"2602d21e81277a83f6048128f61d794a06f474e1f75e49740a817c2666f62211": [
@@ -3122,6 +3307,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -3154,16 +3342,22 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"27995829fe6a7515c1bfe848f9c4761db16c225929257bf40d0894f29ea8baf2": [
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/150618202535",
"windows/150723231635",
@@ -3179,7 +3373,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"2834991cf677466d22baac3b0055e5b911d9a9e55f5b85ba02dc566782c30e8a": [
"macos/10.10.0",
@@ -3265,7 +3460,8 @@
],
"2a575471e31340bc21581cbd2cf13e158463203ece94bcf9d3cc196bf09a5472": [
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"2a8da2f8d23e0cd3b5871ecfb0f42276ca73230667f474eede71c5ee32cc3ec6": [
"windows/160414222039",
@@ -3275,7 +3471,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"2a99f5bc1174b73cbb1d620884e01c34e51ccb3978da125f0e33268883bf4158": [
"android/marshmallow-cts-release",
@@ -3285,6 +3482,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -3296,6 +3494,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.4",
"macos/10.9.5",
"mozilla/2.10",
@@ -3303,6 +3504,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/140912180251",
"windows/150122021939",
@@ -3321,11 +3523,13 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"2cabeafe37d06ca22aba7391c0033d25982952c453647349763a3ab5ad6ccf69": [
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"2ce1cb0bf9d2f9e102993fbe215152c3b2dd0cabde1c68e5319b839154dbb7f5": [
"android/kitkat-cts-release",
@@ -3340,6 +3544,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -3351,6 +3556,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -3360,6 +3568,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/100503224537",
"windows/100719231554",
@@ -3398,7 +3607,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"2d47437de17951215a12f3c58e51c729a58026ef1fcc0a5fb3d9dc012f600d19": [
"android/kitkat-cts-release",
@@ -3476,7 +3686,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"2d66a702ae81ba03af8cff55ab318afa919039d9f31b4d64388680f81311b65a": [
"windows/110919210309",
@@ -3508,7 +3719,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"2dc62c3f6c0cc9020bba77e1c511511024b943ee598856da5a22e222b7277a20": [
"macos/10.9.0",
@@ -3577,7 +3789,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"2dfcbacadf22a6ff107a51fd3e8b9e17858028879b13f7c3b57b3e1bd2315809": [
"windows/070109202240",
@@ -3619,8 +3832,10 @@
],
"2e7bf16cc22485a7bbe2aa8696750761b0ae39be3b2fe9d0cc6d4ef73491425c": [
"mozilla/2.18",
+ "mozilla/2.20",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"2f1062f8bf84e7eb83a0f64c98d891fbe2c811b17ffac0bce1a6dc9c7c3dcbb7": [
"macos/10.9.0",
@@ -3715,6 +3930,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.3",
"macos/10.10.4",
"macos/10.11.0",
@@ -3725,11 +3941,15 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/140912180251",
"windows/150122021939",
@@ -3749,7 +3969,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"31ad6648f8104138c738f39ea4320133393e3a18cc02296ef97c2ac9ef6731d0": [
"android/lollipop-cts-release",
@@ -3761,6 +3982,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -3772,6 +3994,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -3780,6 +4005,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/131003230417",
"windows/140312052931",
@@ -3801,7 +4027,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"31eace9b4c9c71734a185680bc24866ca6cbd82b3cb61bcc8706261b59ce1073": [
"windows/070109202240",
@@ -3962,17 +4189,20 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"3417bb06cc6007da1b961c920b8ab4ce3fad820e4aa30b9acbc4a74ebdcebc65": [
"mozilla/2.18",
+ "mozilla/2.20",
"windows/160916174005",
"windows/161112005943",
"windows/170228174808",
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"341de98b1392abf7f4ab90a960cf25d4bd6ec65b9a51ce6ed067d00ec7ce9b7f": [
"macos/10.10.0",
@@ -4002,7 +4232,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"35ae5bddd8f7ae635cffba5682a8f00b95f48462c7108ee9a0e5292b074aafb2": [
"android/kitkat-cts-release",
@@ -4080,7 +4311,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"363f3c849eab03b0a2a0f636d7b86d04d3ac7fcfe26a0a9121ab9795f6e176df": [
"macos/10.10.0",
@@ -4094,6 +4326,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5"
@@ -4150,7 +4385,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"37d51006c512eaab626421f1ec8c92013fc5f82ae98ee533eb4619b8deb4d06c": [
"android/kitkat-cts-release",
@@ -4165,6 +4401,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -4176,6 +4413,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -4185,6 +4425,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -4238,7 +4479,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"37d8dc8af7867845da3344a6b1bade448d8a80e47b5579f96bf631768f9f30f6": [
"windows/070201011524",
@@ -4433,6 +4675,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -4488,7 +4733,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"3c4fb0b95ab8b30032f432b86f535fe172c185d0fd39865837cf36187fa6f428": [
"android/marshmallow-cts-release",
@@ -4498,6 +4744,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.11.0",
"macos/10.11.1",
"macos/10.11.2",
@@ -4506,11 +4753,15 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/140912180251",
"windows/150122021939",
@@ -4530,7 +4781,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"3c5f81fea5fab82c64bfa2eaecafcde8e077fc8620a7cae537163df36edbf378": [
"android/kitkat-cts-release",
@@ -4545,6 +4797,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -4556,6 +4809,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.4",
"macos/10.9.5",
"mozilla/2.10",
@@ -4563,6 +4819,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/100927165108",
"windows/110125205412",
@@ -4599,7 +4856,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"3ccc3ccfe45496d07b620dbf1328e8a1490018f48633c8a28a995ca60408b0be": [
"windows/070109202240",
@@ -4654,7 +4912,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"3cfc3c14d1f684ff17e38c43ca440c00b967ec933e8bfe064ca1d72c90f2adb0": [
"mozilla/2.10",
@@ -4689,6 +4948,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -4700,6 +4960,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -4708,6 +4971,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/110627203812",
"windows/110830002513",
@@ -4741,7 +5005,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"3e9099b5015e8f486c00bcea9d111ee721faba355a89bcf1df69561e3dc6325c": [
"android/kitkat-cts-release",
@@ -4756,6 +5021,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -4767,6 +5033,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -4776,6 +5045,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -4829,7 +5099,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"3f06e55681d496f5be169eb5389f9f2b8ff61e1708df6881724849cd5d27cb69": [
"android/kitkat-cts-release",
@@ -4980,7 +5251,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"417dcf3180f4ed1a3747acf1179316cd48cb05c5788435168aed98c98cdcb615": [
"windows/121102212406",
@@ -5007,7 +5279,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"41c923866ab4cad6b7ad578081582e020797a6cbdf4fff78ce8396b38937d7f5": [
"android/kitkat-cts-release",
@@ -5022,6 +5295,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -5033,6 +5307,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -5042,6 +5319,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070201011524",
"windows/070522004642",
@@ -5094,7 +5372,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"41d4f6dcf130b9843a3b9a9530953e925fdd84e8b7aeb8f205b8fae39352617d": [
"macos/10.10.0",
@@ -5118,6 +5397,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -5129,6 +5409,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -5138,6 +5421,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -5191,7 +5475,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"4210f199499a9ac33c8de02ba6dbaa14408bdd8a6e324689c1922d069715a332": [
"windows/100503224537",
@@ -5231,7 +5516,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"42143a511a3afcdd80d555debb4191ec6bb285ee66e62ec657ed20adf7d55faa": [
"windows/090825180842",
@@ -5274,7 +5560,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161": [
"android/kitkat-cts-release",
@@ -5289,6 +5576,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -5300,6 +5588,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -5309,6 +5600,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -5362,7 +5654,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"43df5774b03e7fef5fe40d931a7bedf1bb2e6b42738c4e6d3841103d3aa7f339": [
"android/kitkat-cts-release",
@@ -5377,6 +5670,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -5388,6 +5682,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -5396,6 +5693,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/090825180842",
"windows/091013033632",
@@ -5437,7 +5735,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"43f257412d440d627476974f877da8f1fc2444565a367ae60eddc27a412531ae": [
"macos/10.10.0",
@@ -5451,6 +5750,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -5572,11 +5874,13 @@
"44b545aa8a25e65a73ca15dc27fc36d24c1cb9953a066539b11582dc487b4833": [
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/151119231843",
"windows/160113232859",
@@ -5589,7 +5893,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"45140b3247eb9cc8c5b4f0d7b53091f73292089e6e5a63e2749dd3aca9198eda": [
"android/kitkat-cts-release",
@@ -5604,6 +5909,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -5615,6 +5921,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -5624,6 +5933,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/100503224537",
"windows/100719231554",
@@ -5662,7 +5972,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"46273285615d96e52da9fc2ed8c036f10af3d9f6280f8d288706c52b2011b4da": [
"windows/090501224247",
@@ -5706,19 +6017,23 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"46edc3689046d53a453fb3104ab80dcaec658b2660ea1629dd7e867990648716": [
+ "android/oreo-mr1-cts-release",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"windows/160916174005",
"windows/161112005943",
"windows/170228174808",
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"488e134f30c5db56b76473e608086842bf21af8ab3cd7ac67ebdf125d531834e": [
"windows/090825180842",
@@ -5761,7 +6076,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"488fca189eaadf54a3f920ed39e587183ba512232999fae3e4a285fe98e298d1": [
"windows/150122021939",
@@ -5829,11 +6145,13 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/140912180251",
"windows/150122021939",
@@ -5853,7 +6171,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"49c8175a9815e08bef129a929de1bacad04e4db67a8c839293953e5031c81ca0": [
"windows/070109202240",
@@ -5906,6 +6225,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -5917,6 +6237,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -5925,6 +6248,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/120223022238",
"windows/120406192127",
@@ -5952,7 +6276,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"49f74f824f2e059fe99c98af3219ec0d9a004d1b64dd2fd1452616318ab806c0": [
"windows/070109202240",
@@ -6005,6 +6330,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -6016,6 +6342,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -6024,6 +6353,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/090825180842",
"windows/091013033632",
@@ -6065,7 +6395,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"4b22d5a6aec99f3cdb79aa5ec06838479cd5ecba7164f7f22dc1d65f63d85708": [
"android/lollipop-cts-release",
@@ -6100,7 +6431,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"4bdb7418bdf7ffe33ba0884afa7c0c61fd85a153972f65f7d01cb3ec7eb4073c": [
"windows/070109202240",
@@ -6170,7 +6502,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"4d2491414cfe956746ec4cefa6cf6f72e28a1329432f9d8a907ac4cb5dadc15a": [
"android/marshmallow-cts-release",
@@ -6180,6 +6513,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -6191,6 +6525,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.4",
"macos/10.9.5",
"mozilla/2.10",
@@ -6198,6 +6535,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/140912180251",
"windows/150122021939",
@@ -6217,7 +6555,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"4d9ebb28825c9643ab15d54e5f9614f13cb3e95de3cf4eac971301f320f9226e": [
"windows/090825180842",
@@ -6260,7 +6599,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"4dbb0157a691fa7382289d65c0332ddb1dcb640b40ad10f010a43e20f3afed1e": [
"windows/070109202240",
@@ -6347,14 +6687,19 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/100927165108",
"windows/110125205412",
@@ -6391,7 +6736,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"507941c74460a0b47086220d4e9932572ab5d1b5bbcb8980ab1cb17651a844d2": [
"android/kitkat-cts-release",
@@ -6414,6 +6760,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -6469,7 +6818,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"513b2cecb810d4cde5dd85391adfc6c2dd60d87bb736d2b521484aa47a0ebef6": [
"android/kitkat-cts-release",
@@ -6484,6 +6834,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -6495,6 +6846,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -6504,6 +6858,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/091029013045",
"windows/100503224537",
@@ -6543,7 +6898,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"51847c8cbd2e9a72c91e292d2ae247d7de1e3fd270547a20ef7d610f38b8842c": [
"macos/10.10.0",
@@ -6649,14 +7005,19 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/100927165108",
"windows/110125205412",
@@ -6693,7 +7054,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"53dfdfa4e297fcfe07594e8c62d5b8ab06b32c7549f38a163094fd6429d5da43": [
"macos/10.10.0",
@@ -6707,6 +7069,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -6731,21 +7096,25 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"54455f7129c20b1447c418f997168f24c58fc5023bf5da5be2eb6e1dd8902ed5": [
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"windows/160916174005",
"windows/161112005943",
"windows/170228174808",
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"54ae8a683fe2d78ff1ef0e0b3f58425092953ba08c67fe4a95595d1cebcdcb30": [
"windows/140912180251",
@@ -6764,7 +7133,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"54b4fc43d44aa4ca9fc03ca7e9949fbae267a064d02da21852412a381b5d1537": [
"windows/140912180251",
@@ -6785,7 +7155,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"552f7bdcf1a7af9e6ce672017f4f12abf77240c78e761ac203d1d9d20ac89988": [
"android/lollipop-cts-release",
@@ -6797,6 +7168,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -6808,6 +7180,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -6816,6 +7191,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/131003230417",
"windows/140312052931",
@@ -6837,7 +7213,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"5533a0401f612c688ebce5bf53f2ec14a734eb178bfae00e50e85dae6723078a": [
"windows/131003230417",
@@ -6860,7 +7237,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"55926084ec963a64b96e2abe01ce0ba86a64fbfebcc7aab5afc155b37fd76066": [
"android/kitkat-cts-release",
@@ -6874,6 +7252,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -6885,6 +7264,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -6893,6 +7275,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/111018233154",
"windows/120125230451",
@@ -6922,7 +7305,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"5607e260163f49c8ea4175a1c0a53b13195cb7d07845611e943a2ff507036834": [
"windows/070522004642",
@@ -6975,7 +7359,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"568d6905a2c88708a4b3025190edcfedb1974a606a13c6e5290fcb2ae63edab5": [
"android/kitkat-cts-release",
@@ -6990,6 +7375,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -7001,6 +7387,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -7010,6 +7399,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/100503224537",
"windows/100719231554",
@@ -7048,16 +7438,22 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"56c77128d98c18d91b4cfdffbc25ee9103d4758ea2abad826a90f3457d460eb4": [
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/150618202535",
"windows/150723231635",
@@ -7073,7 +7469,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"56ce347cc6df4c35943dfdeaee023f9739a3f1cedeee0cd88dc2386bc8a91eaf": [
"windows/070109202240",
@@ -7187,6 +7584,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -7198,6 +7596,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -7206,6 +7607,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/140912180251",
"windows/150122021939",
@@ -7225,7 +7627,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"59b3829f1ff443344958fae8bff621b684c848cfbf7ead6b63a6ca50f2794f89": [
"macos/10.11.0",
@@ -7236,6 +7639,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"windows/100927165108",
"windows/110125205412",
"windows/110218005058",
@@ -7271,7 +7677,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"5a1b5d6bc65523b40a6deffa45b48e4288ae8dd86dd70a5b858d4a5affc94f71": [
"windows/071219233937",
@@ -7321,10 +7728,12 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"5a885db19c01d912c5759388938cafbbdf031ab2d48e91ee15589b42971d039c": [
"mozilla/2.18",
+ "mozilla/2.20",
"windows/160414222039",
"windows/160916174005",
"windows/161112005943",
@@ -7332,7 +7741,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"5adfa25013bed3710831572de51c4b9a21171c00313249c4cb4719d37fbb8d20": [
"windows/160916174005",
@@ -7341,7 +7751,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"5b1d9d24de0afea8b35ba04a1c3e25d0812cdf7c4625de0a89af9fe4bbd1bb15": [
"windows/110919210309",
@@ -7373,7 +7784,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"5b38bd129e83d5a0cad23921089490d50d4aae370428f8ddfffffa4c1564e184": [
"macos/10.10.0",
@@ -7397,6 +7809,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -7408,6 +7821,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -7417,6 +7833,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/090501224247",
"windows/090825180842",
@@ -7459,7 +7876,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"5cc3d78e4e1d5e45547a04e6873e64f90cf9536d1ccc2ef800f355c4c5fd70fd": [
"android/marshmallow-cts-release",
@@ -7469,14 +7887,19 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/130420010442",
"windows/130626232015",
@@ -7500,7 +7923,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"5d56499be4d2e08bcfcad08a3e38723d50503bde706948e42f55603019e528ae": [
"android/marshmallow-cts-release",
@@ -7510,6 +7934,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.3",
"macos/10.10.4",
"macos/10.11.0",
@@ -7520,11 +7945,15 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/140912180251",
"windows/150122021939",
@@ -7544,7 +7973,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"5e3571f33f45a7df1537a68b5ffb9e036af9d2f5bc4c9717130dc43d7175aac7": [
"windows/070201011524",
@@ -7597,7 +8027,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"5edb7ac43b82a06a8761e8d7be4979ebf2611f7dd79bf91c1c6b566a219ed766": [
"android/kitkat-cts-release",
@@ -7612,6 +8043,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -7623,6 +8055,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -7631,6 +8066,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/090825180842",
"windows/091013033632",
@@ -7672,7 +8108,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"5f0b62eab5e353ea6521651658fbb65359f443280a4afbd104d77d10f9f04c07": [
"android/kitkat-cts-release",
@@ -7737,7 +8174,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"5f960eebd716dbcb4d8a78b996e680ec2547441e69b4e44e98a595502e28a002": [
"android/kitkat-mr1-release",
@@ -7793,7 +8231,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"604d32d036895aed3bfefaeb727c009ec0f2b3cdfa42a1c71730e6a72c3be9d4": [
"windows/150618202535",
@@ -7810,7 +8249,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"606223d9db80df3939601e74b7e828e2800cce4273f76f276aa62db0a8e3b6c1": [
"windows/071219233937",
@@ -7980,7 +8420,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"62dd0be9b9f50a163ea0f8e75c053b1eca57ea55c8688f647c6881f2c8357b95": [
"android/kitkat-cts-release",
@@ -7995,6 +8436,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -8006,6 +8448,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -8015,6 +8460,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070201011524",
"windows/070522004642",
@@ -8067,7 +8513,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"62f240278c564c4dd8bf7d9d4f6f366ea894d22f5f34d989a983acec2fffed50": [
"android/kitkat-cts-release",
@@ -8205,7 +8652,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"63343abfb89a6a03ebb57e9b3f5fa7be7c4f5c756f3017b3a8c488c3653e9179": [
"macos/10.10.0",
@@ -8219,6 +8667,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.4",
"macos/10.9.5"
],
@@ -8249,7 +8700,11 @@
],
"65353833cf234c79562164f90849c0d104dbabf8ee41064d83e8cbe03ba1c5a5": [
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
+ ],
+ "657cfe2fa73faa38462571f332a2363a46fce7020951710702cdfbb6eeda3305": [
+ "windows/180122185731"
],
"6639d13cab85df1ad9a23c443b3a60901e2b138d456fa71183578108884ec6bf": [
"macos/10.10.0",
@@ -8263,6 +8718,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -8281,6 +8739,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -8292,6 +8751,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -8301,6 +8763,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/090203164005",
"windows/090501224247",
@@ -8344,7 +8807,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"67ec2059fbf52d2e6ab51a5a9b3fc2e1dcd658a1ef3a8f31107bc98028b494a2": [
"windows/070109202240",
@@ -8473,6 +8937,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -8484,6 +8949,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -8493,6 +8961,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/090825180842",
"windows/091013033632",
@@ -8534,7 +9003,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"68ad50909b04363c605ef13581a939ff2c96372e3f12325b0a6861e1d59f6603": [
"windows/100927165108",
@@ -8572,7 +9042,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"69ddd7ea90bb57c93e135dc85ea6fcd5480b603239bdc454fc758b2a26cf7f79": [
"android/kitkat-cts-release",
@@ -8587,6 +9058,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -8598,6 +9070,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -8606,6 +9081,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/090825180842",
"windows/091013033632",
@@ -8647,7 +9123,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"69fac9bd55fb0ac78d53bbee5cf1d597989fd0aaab20a25151bdf1733ee7d122": [
"android/kitkat-cts-release",
@@ -8662,6 +9139,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -8673,6 +9151,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -8682,6 +9163,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -8735,22 +9217,28 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"6b9c08e86eb0f767cfad65cd98b62149e5494a67f5845e7bd1ed019f27b86bd6": [
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.11.4",
"macos/10.12.0",
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/160113232859",
"windows/160123000836",
@@ -8762,7 +9250,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"6baf50ae3467eff3c35fefdc76a02a97fab6267723eda91e99f1b3dc2b28f82e": [
"windows/090825180842",
@@ -8805,7 +9294,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"6c61dac3a2def031506be036d2a6fe401994fbd13df9c8d466599274c446ec98": [
"android/kitkat-cts-release",
@@ -8820,6 +9310,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -8831,6 +9322,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -8840,6 +9334,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/090203164005",
"windows/090501224247",
@@ -8883,16 +9378,22 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"6cc05041e6445e74696c4cfbc9f80f543b7eabbb44b4ce6f787c6a9971c42f17": [
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/150618202535",
"windows/150723231635",
@@ -8908,7 +9409,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"6ccfd302fc44bf4599329b9750878ea44e7e8566564bcbd586169762dd10c74e": [
"windows/130626232015",
@@ -8932,7 +9434,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"6cf5f658436d10507eba9df463987480bc8560a8e26ef4691e1d3c9a878a0952": [
"macos/10.10.0",
@@ -8964,6 +9467,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -8975,6 +9479,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -8984,6 +9491,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/091029013045",
"windows/100503224537",
@@ -9023,7 +9531,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"6dea86a1e66620a040c3c5943cb215d2ca87fb6ac09b59707e29d2facbd66b4e": [
"android/kitkat-mr1-release",
@@ -9120,6 +9629,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -9180,7 +9692,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"6ec6614e9a8efd47d6318ffdfd0bf65b493a141f77c38d0b319be1bbbc053dd2": [
"windows/110919210309",
@@ -9212,7 +9725,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"6f2bc4cb632c24eae6782c0f39758932d1e1dc9b3e070f9303073fff38b288e2": [
"macos/10.9.0"
@@ -9232,6 +9746,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -9288,7 +9805,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"6fff78e400a70c11011cd85977c459fb5af96a3df0540820d0f4b8607875e58f": [
"macos/10.10.0",
@@ -9302,6 +9820,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -9320,6 +9841,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -9331,6 +9853,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -9340,6 +9865,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/100503224537",
"windows/100719231554",
@@ -9378,7 +9904,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"70b922bfda0e3f4a342e4ee22d579ae598d071cc5ec9c30f123680340388aea5": [
"macos/10.10.0",
@@ -9392,6 +9919,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -9412,11 +9942,13 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"71cca5391f9e794b04802530b363e121da8a3043bb26662fea4dca7fc951a4bd": [
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"7286ce249fe9e32bd4752257c17cd8f6991a9c1e6f1a3cc73304ed023e6ae4eb": [
"windows/131003230417",
@@ -9439,7 +9971,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"730b619eaa759863c65360b7412e1457eca96844ef2f16d91fcf2efe46a647e9": [
"windows/070109202240",
@@ -9525,7 +10058,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"73c176434f1bc6d5adf45b0e76e727287c8de57616c1e6e6141a2b2cbc7d8e4c": [
"android/kitkat-cts-release",
@@ -9540,6 +10074,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -9551,6 +10086,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -9560,6 +10098,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -9613,7 +10152,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"7431e5f4c3c1ce4690774f0b61e05440883ba9a01ed00ba6abd7806ed3b118cf": [
"android/kitkat-cts-release",
@@ -9628,6 +10168,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -9639,6 +10180,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -9648,6 +10192,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -9701,7 +10246,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"744b1147b4a9a69c32785e9e37c3323241ef29f63e76f1603d6761a783d8a0fe": [
"windows/150122021939",
@@ -9761,7 +10307,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"75c9d4361cb96e993abd9620cf043be9407a4633f202f0f4c0e17851cc6089cd": [
"macos/10.10.0",
@@ -9824,11 +10371,13 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -9882,7 +10431,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"767c955a76412c89af688e90a1c70f556cfd6b6025dbea10416d7eb6831f8c40": [
"android/kitkat-cts-release",
@@ -9897,6 +10447,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -9908,6 +10459,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -9970,7 +10524,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"76ef4762e573206006cbc338b17ca4bc200574a11928d90c3ef31c5e803e6c6f": [
"windows/070109202240",
@@ -10103,7 +10658,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"77e04c9a751c73f23e2a1336112ec8d5153d382a152fed89d7532c3102771f3c": [
"windows/090501224247",
@@ -10147,7 +10703,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"781d64dfa77b00f2c006700b1fda86bf68b865a603c7a656f92e90c042ca2873": [
"windows/080328202117",
@@ -10194,7 +10751,8 @@
"windows/161112005943",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"7908b40314c138100b518d0735807ffbfcf8518a0095337105ba386b153dd927": [
"android/kitkat-cts-release",
@@ -10209,6 +10767,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -10220,6 +10779,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -10229,6 +10791,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -10282,7 +10845,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"793cbf4559b9fde38ab22df16869f69881ae14c4b0139ac788a78a1afcca02fb": [
"android/kitkat-cts-release",
@@ -10422,7 +10986,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"7af6ea9f753a1e709bd64d0beb867c11e8c295a56e24a6e0471459dccdaa1558": [
"macos/10.11.0",
@@ -10433,6 +10998,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"windows/100927165108",
"windows/110125205412",
"windows/110218005058",
@@ -10468,7 +11036,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"7afc9d01a62f03a2de9637936d4afe68090d2de18d03f29c88cfb0b1ba63587f": [
"macos/10.10.0",
@@ -10482,6 +11051,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -10594,6 +11166,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -10605,6 +11178,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -10613,6 +11189,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/131003230417",
"windows/140312052931",
@@ -10634,7 +11211,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"7d2bf3489ebc9ad3448b8b0827715a3cbfe3d523e3b56a9b5fc1d2a2da2f20fe": [
"windows/100503224537",
@@ -10674,7 +11252,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"7d3b465a6014e526c0affcee2127d2311727ad811c26842d006af37306cc80bd": [
"android/kitkat-cts-release",
@@ -10779,7 +11358,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"7e37cb8b4c47090cab36551ba6f45db840680fba166a952db100717f43053fc2": [
"android/lollipop-cts-release",
@@ -10791,6 +11371,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -10802,6 +11383,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -10810,6 +11394,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/131003230417",
"windows/140312052931",
@@ -10831,7 +11416,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"7f12cd5f7e5e290ec7d85179d5b72c20a5be7508ffdb5bf81ab9684a7fc9f667": [
"android/kitkat-cts-release",
@@ -10906,7 +11492,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"8095210805db4bbc355e4428d8fd6ec2cde3ab5fb97a9942988eb8f4dcd06016": [
"android/kitkat-cts-release",
@@ -10988,7 +11575,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"81c2568503eb3be5eec366653960e6d1be9448915e4605b793fbeb34ccb2470f": [
"windows/120223022238",
@@ -11017,7 +11605,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"82d42db3d657f1944e65c192b1dd58db8df8417b89165b045f5c6a70c5f8939e": [
"windows/130626232015",
@@ -11047,6 +11636,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -11094,7 +11686,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"83ce3c1229688a593d485f81973c0f9195431eda37cc5e36430e79c7a888638b": [
"android/kitkat-cts-release",
@@ -11159,7 +11752,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"847df6a78497943f27fc72eb93f9a637320a02b561d0a91b09e87a7807ed7c61": [
"windows/110919210309",
@@ -11191,20 +11785,24 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"8560f91c3624daba9570b5fea0dbe36ff11a8323be9486854fb3f34a5571198d": [
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"85666a562ee0be5ce925c1d8890a6f76a87ec16d4d7d5f29ea7419cf20123b69": [
"mozilla/2.18",
+ "mozilla/2.20",
"windows/160916174005",
"windows/161112005943",
"windows/170228174808",
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"85a0dd7dd720adb7ff05f83d542b209dc7ff4528f7d677b18389fea5e5c49e86": [
"android/kitkat-cts-release",
@@ -11219,6 +11817,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -11230,6 +11829,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -11239,6 +11841,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -11291,7 +11894,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"85e0dfae3e55a843195f8b08c8349050e4689372f6e133ad0d199af96e95cc08": [
"windows/070109202240",
@@ -11352,6 +11956,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -11411,7 +12018,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"87c678bfb8b25f38f7e97b336956bbcf144bbacaa53647e61a2325bc1055316b": [
"android/kitkat-cts-release",
@@ -11461,11 +12069,13 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -11519,7 +12129,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"885de64c340e3ea70658f01e1145f957fcda27aabeea1ab9faa9fdb0102d4077": [
"windows/070109202240",
@@ -11574,7 +12185,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"88ef81de202eb018452e43f864725cea5fbd1fc2d9d205730709c5d8b8690f46": [
"android/lollipop-cts-release",
@@ -11586,6 +12198,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.3",
"macos/10.10.4",
"macos/10.11.0",
@@ -11596,11 +12209,15 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/130626232015",
"windows/131003230417",
@@ -11623,7 +12240,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"894ce6ddb012cb3f736954668de63f436080e95f17b7a81bd924eb21bee9e440": [
"windows/071219233937",
@@ -11673,7 +12291,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"894ebc0b23da2a50c0186b7f8f25ef1f6b2935af32a94584ef80aaf877a3a06e": [
"macos/10.10.0",
@@ -11687,6 +12306,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -11725,7 +12347,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"8a866fd1b276b57e578e921c65828a2bed58e9f2f288054134b7f1f4bfc9cc74": [
"android/lollipop-cts-release",
@@ -11737,6 +12360,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.3",
"macos/10.10.4",
"macos/10.11.0",
@@ -11747,11 +12371,15 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/130626232015",
"windows/131003230417",
@@ -11774,7 +12402,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"8a968aadd88b20519672a452a3d6e31eacb71c26bcaf65b32f9793bf2ffa54a9": [
"macos/10.10.0",
@@ -11808,7 +12437,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"8b45da1c06f791eb0cabf26be588f5fb23165c2e614bf885562d0dce50b29b02": [
"android/nougat-cts-release",
@@ -11833,7 +12463,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"8ba1bd9c88efb3947e60ebe21137f81df7f09994cef27f097055018b8194c634": [
"windows/140912180251",
@@ -11852,7 +12483,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"8c4edfd04348f322969e7e29a4cd4dca004655061c16e1b076422ef342ad630e": [
"android/kitkat-cts-release",
@@ -11918,7 +12550,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"8c7209279ac04e275e16d07fd3b775e80154b5968046e31f52dd25766324e9a7": [
"android/kitkat-cts-release",
@@ -11943,6 +12576,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -11965,6 +12601,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -11976,6 +12613,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -11985,6 +12625,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -12038,7 +12679,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"8da084fcf99ce07722f89b3205939806fa5cb811e1c813f6a108c7d336b3408e": [
"android/kitkat-cts-release",
@@ -12143,7 +12785,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"8dbb5a7c06c20ef62dd912a36740992ff6e1e8583d42ede257c3affd7c769399": [
"windows/070109202240",
@@ -12212,7 +12855,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"8e8c6ebf77dc73db3e38e93f4803e62b6b5933beb51ee4152f68d7aa14426b31": [
"windows/090825180842",
@@ -12223,10 +12867,15 @@
],
"8ecde6884f3d87b1125ba31ac3fcb13d7016de7f57cc904fe1cb97c6ae98196e": [
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"windows/160113232859",
"windows/160123000836",
"windows/160128175153",
@@ -12237,7 +12886,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"8f1ecdaf29bcd56eddd6b5d56a07fcac2b74d4bcd179179144a0365c27dcf14b": [
"windows/121102212406",
@@ -12318,7 +12968,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"8f9e2751dcd574e9ba90e744ea92581fd0af640ae86ac1ce2198c90f96b44823": [
"windows/070109202240",
@@ -12414,6 +13065,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.3",
"macos/10.10.4",
"macos/10.11.0",
@@ -12424,11 +13076,15 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/130626232015",
"windows/131003230417",
@@ -12448,7 +13104,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"90f3e05396995ff20922c44592db62d7845e1bf64aef512cca75bc669caa2479": [
"windows/070702210503",
@@ -12500,7 +13157,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"9111240747e1f652f66d1f712a11f698963b491702e312f7513da3d0fc1e5a28": [
"windows/150122021939",
@@ -12524,6 +13182,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -12535,6 +13194,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -12543,6 +13205,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/131003230417",
"windows/140312052931",
@@ -12564,7 +13227,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"92a9d9833fe1944db366e8bfae7a95b6480c2d6c6c2a1be65d4236b608fca1bb": [
"macos/10.10.0",
@@ -12578,6 +13242,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -12647,7 +13314,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"92d8092ee77bc9208f0897dc05271894e63ef27933ae537fb983eef0eae3eec8": [
"macos/10.10.0",
@@ -12661,6 +13329,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5"
@@ -12677,6 +13348,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -12724,7 +13398,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"940ef46536713d8e2eb4b501e80b6abd8eb4e9928dba44784ce7d7e98595dfe8": [
"macos/10.9.0"
@@ -12780,7 +13455,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"959dc5880c457cd92e5447aaa5609db09ed47bd02c17a0edefdc819e756c74e5": [
"macos/10.10.0",
@@ -12804,11 +13480,13 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070201011524",
"windows/070522004642",
@@ -12861,7 +13539,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"9676f287356c89a12683d65234098cb77c4f1c18f23c0e541de0e196725b7ebe": [
"macos/10.10.0",
@@ -12881,14 +13560,19 @@
"96bcec06264976f37460779acf28c5a7cfe8a3c0aae11a8ffcee05c0bddf08c6": [
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9"
],
"978cd966f2faa07ba7aa9500d9c02e9d77f2cdada6ad6ba74af4b91c66593c50": [
@@ -12903,6 +13587,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -12914,6 +13599,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -12966,7 +13654,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"97f654859cbde586fd90311e82ec7902c238cba0d6e529564c9c88f44895ec50": [
"windows/160916174005",
@@ -12975,7 +13664,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"9806ab8509e2f35e192f275f0c308b9409b42512f90c659598c22be613962272": [
"windows/070109202240",
@@ -13018,7 +13708,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"9a114025197c5bb95d94e63d55cd43790847b646b23cdf11ada4a00eff15fb48": [
"android/kitkat-cts-release",
@@ -13033,6 +13724,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -13044,6 +13736,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -13052,6 +13747,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/111018233154",
"windows/120125230451",
@@ -13081,7 +13777,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"9a6ec012e1a7da9dbe34194d478ad7c0db1822fb071df12981496ed104384113": [
"android/kitkat-cts-release",
@@ -13096,11 +13793,13 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/130420010442",
"windows/130626232015",
@@ -13124,7 +13823,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"9a73929a500f1a0bf49dcb046e8039169696557345e9f813f10ff9380db22695": [
"macos/10.10.0",
@@ -13138,6 +13838,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -13156,6 +13859,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -13167,6 +13871,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -13176,6 +13883,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -13229,7 +13937,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"9b14e8f5f6ea167666e76dcd6becc190861d5e8970b99a9470f0231236049704": [
"windows/131003230417",
@@ -13248,7 +13957,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"9cefb0cb7b74e642932532831e0dc8f4d68ad414261fc3f474b795e72a164e57": [
"windows/150618202535",
@@ -13265,7 +13975,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"9d190b2e314566685be8a889e27aa8c7d7ae1d8aaddba3c1ecf9d24863cd34b9": [
"macos/10.10.0",
@@ -13279,6 +13990,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5"
@@ -13394,6 +14108,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -13412,11 +14129,13 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -13470,16 +14189,19 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"a040929a02ce53b4acf4f2ffc6981ce4496f755e6d45fe0b2a692bcd52523f36": [
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/151119231843",
"windows/160113232859",
@@ -13492,7 +14214,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"a0459b9f63b22559f5fa5d4c6db3f9f72ff19342033578f073bf1d1b46cbb912": [
"android/kitkat-cts-release",
@@ -13507,11 +14230,13 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -13565,23 +14290,32 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"a1339d33281a0b56e557d3d32b1ce7f9367eb094bd5fa72a7e5004c8ded7cafe": [
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/170228174808",
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
+ ],
+ "a1a86d04121eb87f027c66f53303c28e5739f943fc84b38ad6af009035dd9457": [
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3"
],
"a1b2dbeb64e706c6169e3c4118b23baa09018a8427666d8bf0e28891ec051950": [
"windows/110919210309",
@@ -13613,7 +14347,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"a1f05ccb80c2d710ec7d479abdcbb879e58d7edb7149fe78a87884e3d0bad0f9": [
"macos/10.10.0",
@@ -13627,6 +14362,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -13674,7 +14412,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"a22dba681e97376e2d397d728aae3a9b6296b9fdba60bc2e11f647f2c675fb37": [
"android/kitkat-cts-release",
@@ -13689,6 +14428,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -13700,6 +14440,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -13759,7 +14502,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"a31f093053bd12c1f5c3c6efd498023fd2914d7758d05d698ce084b50626e0e5": [
"macos/10.10.0",
@@ -13773,6 +14517,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -13823,7 +14570,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"a3cc68595dfe7e86d8ad1772a8b5284add54ace3b8a798df47bccafb1fdb84df": [
"windows/160414222039",
@@ -13833,7 +14581,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"a3d7435a18c46b23b6a4f8929cd59050c9168b03a7fad532626f297cac5356e4": [
"windows/110919210309",
@@ -13865,7 +14614,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"a4310d50af18a6447190372a86afaf8b951ffb431d837f1e5688b45971ed1557": [
"android/kitkat-cts-release",
@@ -13880,6 +14630,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -13891,6 +14642,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -13900,6 +14654,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/090825180842",
"windows/091013033632",
@@ -13941,7 +14696,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"a45ede3bbbf09c8ae15c72efc07268d693a21c996fd51e67ca079460fd6d8873": [
"android/kitkat-cts-release",
@@ -13956,6 +14712,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -13967,6 +14724,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -13976,6 +14736,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -14029,7 +14790,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"a4b6b3996fc2f306b3fd8681bd63413d8c5009cc4fa329c2ccf0e2fa1b140305": [
"android/kitkat-cts-release",
@@ -14139,7 +14901,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"a6c51e0da5ca0a9309d2e4c0e40c2af9107aae8203857fe198e3e769e343085c": [
"android/kitkat-cts-release",
@@ -14280,7 +15043,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"a798a1c70e9b6d50eaa5724a26fac7991848edc61bf48d79816bcafb66972128": [
"windows/070109202240",
@@ -14380,7 +15144,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"aad9ceed5aa6b1cea28596a8e4e1abed9386d6ebc9d4aad9acde0fa36ba069d0": [
"macos/10.10.0",
@@ -14438,7 +15203,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"ab7036365c7154aa29c2c29f5d4191163b162a2225011357d56d07ffa7bc1f72": [
"macos/10.10.0",
@@ -14498,7 +15264,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"ad016f958050e0e7e46fae7dcc50197ed8e3ff0a4b262e5ddcdb3edddc7d6578": [
"windows/100503224537",
@@ -14538,7 +15305,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"ad7539e5cdc985fa95244055a9202d63460ec921467d034cfdbe87ec6d00fedc": [
"windows/130626232015",
@@ -14590,6 +15358,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -14645,7 +15416,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"ae92e90000541a9ebc101b70b6c33a62f5a53a55ba815e81d31abddf03507f5d": [
"windows/070109202240",
@@ -14700,7 +15472,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"af6d08eef3cac4e1584abc63c8a9472ac529af99f3f791319a43776063f58dca": [
"windows/070109202240",
@@ -14755,7 +15528,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"af71a3bca322e5224df546895696ce449a8bd2bd130f7a7ae457767f5c23d8f8": [
"windows/070109202240",
@@ -14919,7 +15693,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"b04d708f1ae0456265dd1b66907a2691a28680b853e031df3df9083af71614d7": [
"windows/070109202240",
@@ -14971,6 +15746,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -15027,7 +15805,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"b0b1730ecbc7ff4505142c49f1295e6eda6bcaed7e2c68c5be91b5a11001f024": [
"macos/10.10.0",
@@ -15041,6 +15820,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -15058,6 +15840,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -15069,6 +15852,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -15077,6 +15863,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/131003230417",
"windows/140312052931",
@@ -15098,7 +15885,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"b2259996fff735ab35014ef63f3d413190079dd03a0962432635a8695f995305": [
"windows/100927165108",
@@ -15157,7 +15945,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"b32396746453442f353e616292bb20bbaa5d23b546450fdb9c54b8386167d529": [
"macos/10.10.0",
@@ -15171,6 +15960,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -15195,7 +15987,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"b3c962d34019fb38ab9fe9c62399742ab26c43c2d18ce3f2b13c14321e52964b": [
"windows/070109202240",
@@ -15349,7 +16142,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"b478b812250df878635c2aa7ec7d155eaa625ee82916e2cd294361886cd1fbd4": [
"android/kitkat-cts-release",
@@ -15364,6 +16158,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -15375,6 +16170,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -15383,6 +16181,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/090825180842",
"windows/091013033632",
@@ -15424,7 +16223,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"b5bd2cb79cbd1907298d6bdf4842e516d8c78fa6fc96d25f71af814e16cc245e": [
"windows/080828200829",
@@ -15471,7 +16271,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"b6191a50d0c3977f7da99bcdaac86a227daeb9679ec70ba3b0c9d92271c170d3": [
"android/kitkat-cts-release",
@@ -15486,6 +16287,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -15497,6 +16299,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -15506,6 +16311,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -15559,7 +16365,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"b644d955fff29b74e3b5687e908ee7c3c9197ba3336cc6328531f6c057d677fd": [
"windows/100927165108",
@@ -15597,21 +16404,27 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"b676f2eddae8775cd36cb0f63cd1d4603961f49e6265ba013a2f0307b6d0b804": [
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.12.0",
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/160916174005",
"windows/161112005943",
@@ -15619,7 +16432,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"b7a7ec419454411761225ecf30d99585f851356077bf83274b11588fd05521b8": [
"macos/10.9.0"
@@ -15682,11 +16496,16 @@
"b7c36231706e81078c367cb896198f1e3208dd926949dd8f5709a410f75b6292": [
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/150618202535",
"windows/150723231635",
@@ -15702,7 +16521,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"b8bbe523bfca3b11d50f73f7f10b3ec8ec958aa1dc86f66d9541907ff1a110ef": [
"windows/090203164005",
@@ -15797,7 +16617,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"ba7f1136389075b8e86c53c095fa14f5c83b6b017a0244ed7637114620d3a3b1": [
"macos/10.9.0",
@@ -15818,6 +16639,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -15829,6 +16651,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -15837,6 +16662,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/130420010442",
"windows/130626232015",
@@ -15860,7 +16686,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"bc23f98a313cb92de3bbfc3a5a9f4461ac39494c4ae15a9e9df131e99b73019a": [
"android/kitkat-cts-release",
@@ -15973,6 +16800,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -15984,6 +16812,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -15993,6 +16824,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/100719231554",
"windows/100927165108",
@@ -16030,7 +16862,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"bd81ce3b4f6591d11a67b5fc7a47fdef25521bf9aa4e18b9e3df2e34a7803be8": [
"android/kitkat-cts-release",
@@ -16073,6 +16906,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -16084,6 +16918,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -16093,6 +16930,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070201011524",
"windows/070522004642",
@@ -16145,7 +16983,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"bebce57dcb85f60a93bfa5019edb1a294bf6d81f82d9b4e71f502f0b15a1fc08": [
"windows/160916174005",
@@ -16154,7 +16993,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"bec94911c2955676db6c0a550986d76e3ba005667c442c9762b4fbb773de228c": [
"android/lollipop-mr1-cts-release",
@@ -16165,6 +17005,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -16176,6 +17017,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -16184,6 +17028,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/130626232015",
"windows/131003230417",
@@ -16206,7 +17051,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"bf0feefb9e3a581ad5f9e9db7589985743d261085c4d314f6f5d7259aa421612": [
"android/kitkat-cts-release",
@@ -16221,6 +17067,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -16230,6 +17077,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/090501224247",
"windows/090825180842",
@@ -16276,6 +17124,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -16287,6 +17136,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -16296,6 +17148,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/090825180842",
"windows/091013033632",
@@ -16337,10 +17190,12 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"bfff8fd04433487d6a8aa60c1a29767a9fc2bbb05e420f713a13b992891d3893": [
"mozilla/2.18",
+ "mozilla/2.20",
"windows/150618202535",
"windows/150723231635",
"windows/150820181119",
@@ -16355,7 +17210,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"c0a6f4dc63a24bfdcf54ef2a6a082a0a72de35803e2ff5ff527ae5d87206dfd5": [
"android/kitkat-cts-release",
@@ -16370,6 +17226,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -16381,6 +17238,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -16390,6 +17250,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/080328202117",
"windows/080612204220",
@@ -16436,7 +17297,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"c0c05a8d8da55eaf27aa9b910b0a6ef0d8bbded346928db872e182c2073e9802": [
"macos/10.10.0",
@@ -16450,6 +17312,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -16513,7 +17378,8 @@
"windows/151119231843"
],
"c1727f3b673e6ae7f12f23d789a7be38b918223ef6911c592da1f583444a547e": [
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"c1b12f480020336e5b04f520bc19c2e2e10ab42c9d9235f05cbec33ffa4d4dea": [
"windows/070109202240",
@@ -16568,7 +17434,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"c1b48299aba5208fe9630ace55ca68a03eda5a519c8802a0d3a673be8f8e557d": [
"android/kitkat-cts-release",
@@ -16582,6 +17449,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -16593,6 +17461,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -16602,6 +17473,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -16655,7 +17527,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"c1cf0b52096435e3f1b71daaec455a2311c8404f5583a9e213c69d857d943305": [
"android/kitkat-mr1-release",
@@ -16701,7 +17574,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"c2157309d9aee17bf34f4df5e88dbaeba57e0361eb814cbc239f4d54d329a38d": [
"windows/140912180251",
@@ -16722,7 +17596,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"c2959db8339e8dbcf6409ca92a66c49fd2e32494940a901143bd7eb72827dec2": [
"windows/070109202240",
@@ -16774,6 +17649,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.4",
"macos/10.9.5"
],
@@ -16796,7 +17674,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"c34c5df53080078ffe45b21a7f600469917204f4f0293f1d7209393e5265c04f": [
"windows/150723231635",
@@ -16812,7 +17691,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"c3846bf24b9e93ca64274c0ec67c1ecc5e024ffcacd2d74019350e81fe546ae4": [
"android/kitkat-cts-release",
@@ -16827,6 +17707,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -16838,6 +17719,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -16847,6 +17731,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -16900,7 +17785,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"c38dcb38959393358691ea4d4f3ce495ce748996e64ed1891d897a0fc4dd55c6": [
"android/kitkat-mr1-release",
@@ -16968,7 +17854,8 @@
],
"c45d7bb08e6d67e62e4235110b564e5f78fd92ef058c840aea4e6455d7585c60": [
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"c470cf547e2302b977fb29dd71a89a7b6c1f60777b0329f56017f328bf4f6be6": [
"android/kitkat-cts-release",
@@ -17086,6 +17973,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -17139,7 +18029,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"c57bacf238f9336c3dfba62d12bcf5823603e5842c44e62f5448cc7e5f4cad59": [
"macos/10.9.0"
@@ -17168,6 +18059,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -17217,7 +18111,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"c795ff8ff20c966688f064a1e091421d3110a3456c17ec2404b998738741f622": [
"windows/150618202535",
@@ -17234,7 +18129,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"c7ba6567de93a798ae1faa791e712d378fae1f93c4397fea441bb7cbe6fd5995": [
"android/kitkat-cts-release",
@@ -17260,6 +18156,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -17289,7 +18188,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"ca2d82a08677072f8ab6764ff035676cfe3e5e325e012172df3f92096db79b85": [
"android/kitkat-cts-release",
@@ -17360,7 +18260,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"ca42dd41745fd0b81eb902362cf9d8bf719da1bd1b1efc946f5b4c99f42c1b9e": [
"android/kitkat-cts-release",
@@ -17375,6 +18276,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -17386,6 +18288,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -17395,6 +18300,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070201011524",
"windows/070522004642",
@@ -17447,7 +18353,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"ca7a5e68c53d2c51f72f6b465d3ed753f5903ec7901c8d0f55d868337c81975a": [
"windows/110125205412",
@@ -17484,7 +18391,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"cb3ccbb76031e5e0138f8dd39a23f9de47ffc35e43c1144cea27d46a5ab1cb5f": [
"android/lollipop-cts-release",
@@ -17496,6 +18404,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -17507,6 +18416,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -17515,6 +18427,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/131003230417",
"windows/140312052931",
@@ -17536,7 +18449,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"cb627d18b58ad56dde331a30456bc65c601a4e9b18dedcea08e7daaa07815ff0": [
"macos/10.10.0",
@@ -17550,6 +18464,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5"
@@ -17576,6 +18493,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -17587,6 +18505,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -17596,6 +18517,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/100503224537",
"windows/100719231554",
@@ -17634,7 +18556,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"cbb5af185e942a2402f9eacbc0ed5bb876eea3c1223623d00447e4f3ba554b65": [
"macos/10.10.0",
@@ -17648,6 +18571,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -17692,7 +18618,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"ccc89489371bad111c90619bea240a2e6dadd99f9f6e1d4d41e58ed6de3d0285": [
"windows/070109202240",
@@ -17747,7 +18674,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"cd0b3b2aa174b55f18c7502f3c3a76f2198175ce45637370cf4f48b9c2ce4fbf": [
"windows/090825180842",
@@ -17790,7 +18718,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"cd201256fe5ced0bfff8df595fff36b1416d5313a999f532ef4a9915df96dee0": [
"windows/090825180842",
@@ -17833,7 +18762,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"cd808284cf746ff2fd6eb58aa1d59c4ad4b3ca56fdc6274a8926a7835f32313d": [
"macos/10.10.0",
@@ -17904,7 +18834,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"cecddc905099d8dadfc5b1d209b737cbe2c18cfb2c10c0ff0bcf0d3286fc1aa2": [
"android/kitkat-cts-release",
@@ -17919,6 +18850,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -17930,6 +18862,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -17939,6 +18874,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -17992,7 +18928,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"cf56ff46a4a186109dd96584b5eeb58a510c4275b0e5f94f40bbae865e19f673": [
"android/kitkat-cts-release",
@@ -18056,7 +18993,8 @@
"d1a0319098034e3aec729a0b5c3111229d9d26e3e623e8c5e6843fa06ee8e2e4": [
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"d1c339ea2784eb870f934fc5634e4aa9ad5505016401f26465d37a574663359f": [
"macos/10.10.0",
@@ -18070,6 +19008,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -18102,17 +19043,20 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"d40e9c86cd8fe468c1776959f49ea774fa548684b6c406f3909261f4dce2575c": [
"mozilla/2.18",
+ "mozilla/2.20",
"windows/160414222039",
"windows/160916174005",
"windows/170228174808",
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"d41d829e8c1659822af93fce62bffcde264fc84e8b950c5ff275d052354695a3": [
"android/kitkat-cts-release",
@@ -18186,7 +19130,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"d43af9b35473755c9684fc06d7d8cb70ee5c28e773fb294eb41ee71722924d24": [
"windows/161112005943",
@@ -18194,7 +19139,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"d487a56f83b07482e85e963394c1ecc2c9e51d0903ee946b02c301581ed99e16": [
"android/nougat-cts-release",
@@ -18219,7 +19165,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"d48d3d23eedb50a459e55197601c27774b9d7b18c94d5a059511a10250b93168": [
"windows/160414222039",
@@ -18229,7 +19176,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"d68f7730b1ec2b3fb698c96d76540c9997415a25737dcd61d44960db77d2723d": [
"macos/10.9.0"
@@ -18267,7 +19215,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"d7a7a0fb5d7e2731d771e9484ebcdef71d5f0c3e0a2948782bc83ee0ea699ef4": [
"android/kitkat-cts-release",
@@ -18282,6 +19231,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -18293,6 +19243,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -18302,6 +19255,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -18355,11 +19309,13 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"d7ba3f4ff8ad05633451470dda3378a3491b90005e5c687d2b68d53647cfdd66": [
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"d80fef910ae3f104723b045cec2d019f441ce6213adf156791e70c1790110a31": [
"windows/150618202535",
@@ -18375,7 +19331,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"d8e0febc1db2e38d00940f37d27d41344d993e734b99d5656d9778d4d8143624": [
"android/kitkat-cts-release",
@@ -18390,6 +19347,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -18401,6 +19359,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -18462,7 +19423,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"d95fea3ca4eedce74cd76e75fc6d1ff62c441f0fa8bc77f034b19e5db258015d": [
"android/kitkat-cts-release",
@@ -18487,6 +19449,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -18515,7 +19480,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"da98f640194df128c7888bc8e3479a9dd31795ff087c649052fbafb02eaef184": [
"macos/10.10.0",
@@ -18538,6 +19504,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -18549,6 +19516,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -18557,6 +19527,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/100503224537",
"windows/100719231554",
@@ -18595,14 +19566,16 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"ddbf149733bc2bf8a09d7f012b01a6dea11d7bae26713783ef6407a2495bf189": [
"windows/170228174808",
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"ddff53ecd7743b60bb7b2795ff5732fa785f9a14df1120fb40a38cf84ca2a566": [
"windows/070201011524",
@@ -18656,7 +19629,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"df545bf919a2439c36983b54cdfc903dfa4f37d3996d8d84b4c31eec6f3c163e": [
"windows/100719231554",
@@ -18695,7 +19669,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"e0e17aea06cf9ce12aae8190345a2c59720130a7d8ff72f3745ad75dbaa365b6": [
"windows/140912180251",
@@ -18716,7 +19691,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"e17890ee09a3fbf4f48b9c414a17d637b7a50647e9bc752322727fcc1742a911": [
"android/kitkat-cts-release",
@@ -18741,6 +19717,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -18763,6 +19742,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -18774,6 +19754,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -18782,6 +19765,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/131003230417",
"windows/140312052931",
@@ -18803,7 +19787,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"e28393773da845a679f2080cc7fb44a3b7a1c3792cb7eb7729fdcb6a8d99aea7": [
"android/kitkat-cts-release",
@@ -18867,7 +19852,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"e3268f6106ba8b665a1a962ddea1459d2a46972f1f2440329b390b895749ad45": [
"macos/10.10.3",
@@ -18879,14 +19865,22 @@
"macos/10.12.0",
"macos/10.12.1",
"macos/10.12.2",
- "macos/10.13.0"
+ "macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3"
],
"e35d28419ed02025cfa69038cd623962458da5c695fbdea3c22b0bfb25897092": [
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"windows/160113232859",
"windows/160123000836",
"windows/160128175153",
@@ -18897,7 +19891,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"e389360d0fdbaeb3d250584b4730314e222f39c156a020144e8d960561791506": [
"android/kitkat-cts-release",
@@ -18978,6 +19973,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -18989,6 +19985,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -18998,6 +19997,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/080328202117",
"windows/080612204220",
@@ -19045,7 +20045,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"e3efb6118a92e3b858fd806f690e31d46b95ca1bd756da2b3037fe2f87cc9137": [
"macos/10.9.0",
@@ -19066,6 +20067,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -19077,6 +20079,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -19133,7 +20138,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"e57210ab812c8df308267cb4291b98e956597ca36ec2b95189ef1723396bcac8": [
"windows/070109202240",
@@ -19289,7 +20295,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"e6b8f8766485f807ae7f8dac1670461f07c0a13eef3a1ff717538d7abad391b4": [
"android/kitkat-cts-release",
@@ -19399,14 +20406,16 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"e74fbda55bd564c473a36b441aa799c8a68e077440e8288b9fa1e50e4bbaca11": [
"windows/170228174808",
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"e75e72ed9f560eec6eb4800073a43fc3ad19195a392282017895974a99026b6c": [
"android/kitkat-cts-release",
@@ -19421,6 +20430,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -19432,6 +20442,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -19441,6 +20454,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -19494,7 +20508,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"e7685634efacf69ace939a6b255b7b4fabef42935b50a265acb5cb6027e44e70": [
"macos/10.10.0",
@@ -19554,7 +20569,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"e793c9b02fd8aa13e21c31228accb08119643b749c898964b1746d46c3d4cbd2": [
"android/lollipop-mr1-cts-release",
@@ -19565,14 +20581,19 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/100927165108",
"windows/110125205412",
@@ -19609,7 +20630,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"e873d4082a7b4632934f48a5cc1ee500932f661e56c3467c5c84d31447476b0c": [
"windows/070109202240",
@@ -19814,6 +20836,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -19825,6 +20848,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -19833,6 +20859,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/090203164005",
"windows/090501224247",
@@ -19876,7 +20903,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"eac0220c5c9fecc5121d3720872d06707b5266be25d4ebb56ab804bbbf85fe03": [
"macos/10.10.0",
@@ -19936,7 +20964,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"eb04cf5eb1f39afa762f2bb120f296cba520c1b97db1589565b81cb9a17b7244": [
"android/kitkat-cts-release",
@@ -19951,6 +20980,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -19962,6 +20992,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -19971,6 +21004,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -20024,7 +21058,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"eb7e05aa58e7bd328a282bf8867033f3c035342b516ee85c01673dffffbbfe58": [
"windows/090203164005",
@@ -20069,16 +21104,20 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"ebc5570c29018c4d67b1aa127baf12f703b4611ebc17b7dab5573894179b93fa": [
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"ebd41040e4bb3ec742c9e381d31ef2a41a48b6685c96e7cef3c1df6cd4331c99": [
"android/kitkat-cts-release",
@@ -20093,6 +21132,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -20104,6 +21144,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -20113,6 +21156,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/080328202117",
"windows/080612204220",
@@ -20160,7 +21204,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"ebf3c02a8789b1fb7d511995d663b72906d913ce0d5e10568a8a77e2586167e7": [
"android/kitkat-cts-release",
@@ -20296,7 +21341,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"edf7ebbca27a2a384d387b7d4010c666e2edb4843e4c29b4ae1d5b9332e6b24d": [
"android/kitkat-cts-release",
@@ -20311,6 +21357,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -20322,6 +21369,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -20330,6 +21380,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/111018233154",
"windows/120125230451",
@@ -20359,7 +21410,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"eec5496b988ce98625b934092eec2908bed0b0f316c2d4730c84eaf1f3d34881": [
"android/kitkat-cts-release",
@@ -20374,6 +21426,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -20385,6 +21438,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -20393,6 +21449,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/120223022238",
"windows/120406192127",
@@ -20420,7 +21477,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"eefca888db442cea1f03fac5de5b1af210ae03f5e1658ddb880c645e78624546": [
"windows/091013033632",
@@ -20461,6 +21519,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -20472,6 +21531,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -20533,7 +21595,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"efb5157e9c66caa1dcc63c9fac0127cde83b7a426c4579b7b43a41ba46a56deb": [
"windows/111018233154",
@@ -20564,7 +21627,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"f00355eef101c7df4e46cce6417dffce3db82dbb1369c3b439c4e33bee445c42": [
"windows/070201011524",
@@ -20618,7 +21682,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"f008733ec500dc498763cc9264c6fcea40ec22000e927d053ce9c90bfa046cb2": [
"macos/10.10.0",
@@ -20632,6 +21697,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -20686,7 +21754,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"f09b122c7114f4a09bd4ea4f4a99d558b46e4c25cd81140d29c05613914c3841": [
"android/kitkat-cts-release",
@@ -20712,6 +21781,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -20745,7 +21817,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"f1b13f5c9a326403b0f31bbe7699cd17c7d1c0b981586dd1a7b219c52508fe99": [
"windows/070702210503",
@@ -20797,7 +21870,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"f1c1b50ae5a20dd8030ec9f6bc24823dd367b5255759b4e71b61fce9f7375d73": [
"android/kitkat-cts-release",
@@ -20812,6 +21886,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -20823,6 +21898,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -20832,6 +21910,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -20885,7 +21964,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"f1f3cc207a6d47947b8cb9c30422229de0d71fb867e0b9a3eda08e0e1736bc28": [
"windows/070109202240",
@@ -20942,7 +22022,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"f356bea244b7a91eb35d53ca9ad7864ace018e2d35d5f8f96ddf68a6f41aa474": [
"android/kitkat-cts-release",
@@ -20956,14 +22037,19 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"mozilla/2.10",
"mozilla/2.11",
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/110919210309",
"windows/111018233154",
@@ -20994,7 +22080,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"f375e2f77a108bacc4234894a9af308edeca1acd8fbde0e7aaa9634e9daf7e1c": [
"windows/091029013045",
@@ -21076,7 +22163,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"f4336bc2ac75950beccf1c1f2f9da6dddafd1f41161ca71f59c76889bd474033": [
"windows/110919210309",
@@ -21108,7 +22196,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"f4c149551a3013a35bc7bffe17a7f3449bc1ab5b5a0ae74b06c23b90004c0104": [
"android/kitkat-cts-release",
@@ -21268,6 +22357,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -21279,6 +22369,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -21308,7 +22401,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"f9e67d336c51002ac054c632022d66dda2e7e3fff10ad061ed31d8bbb410cfb2": [
"android/kitkat-cts-release",
@@ -21323,6 +22417,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -21334,6 +22429,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -21343,6 +22441,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -21396,7 +22495,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"fabcf5197cdd7f458ac33832d3284021db2425fd6bea7a2e69b7486e8f51f9cc": [
"macos/10.10.0",
@@ -21410,6 +22510,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -21433,13 +22536,15 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"fad540811afae0dc767cdf6572a088fa3ce8493dd82b3b869a67d10aab4e8124": [
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"fb47d92a9909fd4fa9bec02737543e1f3514ced747407a8d9cfa397b0915067c": [
"windows/120223022238",
@@ -21468,7 +22573,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"fc0a0fe27c9dc13c81238a5913a1daf8184168beb7e5a4512a771fd4f453651d": [
"windows/070109202240",
@@ -21509,7 +22615,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"fcbfe2886206f72b27593c8b070297e12d769ed10ed7930705a8098effc14d17": [
"android/kitkat-cts-release",
@@ -21524,6 +22631,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -21535,6 +22643,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -21578,7 +22689,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"fd73dad31c644ff1b43bef0ccdda96710b9cd9875eca7e31707af3e96d522bbd": [
"android/kitkat-cts-release",
@@ -21593,6 +22705,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -21604,6 +22717,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5",
@@ -21612,6 +22728,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/110919210309",
"windows/111018233154",
@@ -21642,7 +22759,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"fe7114d07a147759891ff37b4f53eb43568296bc3bf89bc12cafb186985ef28d": [
"windows/071219233937",
@@ -21692,7 +22810,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"fe863d0822fe7a2353fa484d5924e875656d3dc9fb58771f6f616f9d571bc592": [
"macos/10.10.0",
@@ -21706,6 +22825,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.2",
"macos/10.9.4",
"macos/10.9.5"
@@ -21723,6 +22845,7 @@
"android/nougat-cts-release",
"android/nougat-mr1-cts-release",
"android/oreo-cts-release",
+ "android/oreo-mr1-cts-release",
"macos/10.10.0",
"macos/10.10.3",
"macos/10.10.4",
@@ -21734,6 +22857,9 @@
"macos/10.12.1",
"macos/10.12.2",
"macos/10.13.0",
+ "macos/10.13.1",
+ "macos/10.13.2",
+ "macos/10.13.3",
"macos/10.9.0",
"macos/10.9.2",
"macos/10.9.4",
@@ -21743,6 +22869,7 @@
"mozilla/2.14",
"mozilla/2.16",
"mozilla/2.18",
+ "mozilla/2.20",
"mozilla/2.9",
"windows/070109202240",
"windows/070201011524",
@@ -21795,7 +22922,8 @@
"windows/170419224008",
"windows/170613190204",
"windows/170922155710",
- "windows/171121202507"
+ "windows/171121202507",
+ "windows/180122185731"
],
"ffcef2224e29b0b36ec8314e686822f3ac0f1c5e0c2d5c0eb2484ce7e2540fd0": [
"windows/070109202240",
@@ -21842,19 +22970,21 @@
"windows/151119231843"
]
},
- "last_spki_id": 490,
+ "last_spki_id": 492,
"spkis": {
"004124ad6037fd5f3319e7a23d4d9c811f5598d66c4754155b0aaa9e8f00621f": {
"fingerprints": [
"ddff53ecd7743b60bb7b2795ff5732fa785f9a14df1120fb40a38cf84ca2a566"
],
- "id": 357
+ "id": 357,
+ "legacy": true
},
"006cb226a772c7182d7772383e373f0f229e7dfe3444810a8d6e50905d20d661": {
"fingerprints": [
"f008733ec500dc498763cc9264c6fcea40ec22000e927d053ce9c90bfa046cb2"
],
- "id": 251
+ "id": 251,
+ "legacy": true
},
"006d7be7555dd82026442c4f1a27a80e89a1989cb87b34448ed2194c18196d5e": {
"fingerprints": [
@@ -21867,32 +22997,37 @@
"fingerprints": [
"6f2bc4cb632c24eae6782c0f39758932d1e1dc9b3e070f9303073fff38b288e2"
],
- "id": 283
+ "id": 283,
+ "legacy": true
},
"0206ead163b10ea2f8620868ebd7a15f64a20250d16cd57d6e87c4fff1a2197c": {
"fingerprints": [
"d80fef910ae3f104723b045cec2d019f441ce6213adf156791e70c1790110a31"
],
- "id": 456
+ "id": 456,
+ "legacy": true
},
"02376d0908ac23041cc7d666d9daf192554f7fc36317aa9cb800908616b28af8": {
"fingerprints": [
"847df6a78497943f27fc72eb93f9a637320a02b561d0a91b09e87a7807ed7c61"
],
- "id": 411
+ "id": 411,
+ "legacy": true
},
"023c81cce8e7c64fa942d3c15048707d35d9bb5b87f4f544c5bf1bc5643af2fa": {
"fingerprints": [
"83ce3c1229688a593d485f81973c0f9195431eda37cc5e36430e79c7a888638b",
"797e51f883e855d021e5c770566692999407895593235def52a011f716f8b6bf"
],
- "id": 69
+ "id": 69,
+ "legacy": true
},
"04a6ea654b23658973c98198c64a3a691c0da72ebebd9aebf75324cde6960eaa": {
"fingerprints": [
"c1cf0b52096435e3f1b71daaec455a2311c8404f5583a9e213c69d857d943305"
],
- "id": 157
+ "id": 157,
+ "legacy": true
},
"051cf9fa95e40e9b83edaeda6961f6168c7879c4660172479cdd51ab03cea62b": {
"fingerprints": [
@@ -21904,7 +23039,8 @@
"fingerprints": [
"8c7209279ac04e275e16d07fd3b775e80154b5968046e31f52dd25766324e9a7"
],
- "id": 136
+ "id": 136,
+ "legacy": true
},
"05570ae6eb0fceb4210e6db79486b7094caf200401e149b6677441b5f25e449b": {
"fingerprints": [
@@ -21922,19 +23058,22 @@
"fingerprints": [
"3ccc3ccfe45496d07b620dbf1328e8a1490018f48633c8a28a995ca60408b0be"
],
- "id": 309
+ "id": 309,
+ "legacy": true
},
"0656f5955204c8d2bc8b1ca475e2a4fa6e124d124512784157c858b55471141a": {
"fingerprints": [
"bc23f98a313cb92de3bbfc3a5a9f4461ac39494c4ae15a9e9df131e99b73019a"
],
- "id": 78
+ "id": 78,
+ "legacy": true
},
"06c7bd9553f710e058eb27b15d47dd62d7fd4352d91da96e1efc50e15354b8d7": {
"fingerprints": [
"1594cb5b826c315de3bc932c56895ff23a3a988b5dc1f034d214dfd858d89ee8"
],
- "id": 302
+ "id": 302,
+ "legacy": true
},
"07e854f26a7cbd389927aa041bfef1b6cd21dd143818ad947dc655a9e587fe88": {
"fingerprints": [
@@ -21947,7 +23086,8 @@
"07453d53793bf41819a5251c69f88e2bb344b59ca828b5a543781599eaf3d602",
"39f6033ca664cedb216744d3c6f2b2e8e3cebd6869f7dff47e0db91a79c416f8"
],
- "id": 338
+ "id": 338,
+ "legacy": true
},
"08b3a6335fce5ef48f8f0e543986c07fd18a3b1226129f61864bbd5bdd1f1cc9": {
"fingerprints": [
@@ -21959,13 +23099,15 @@
"fingerprints": [
"58d017279cd4dc63abddb196a6c9906c30c4e08783eae8c1609954d69355596b"
],
- "id": 114
+ "id": 114,
+ "legacy": true
},
"0999bf900bd5c297865e21e1aade6cf6bb3a94d11ae5ea798442a4e2f813241f": {
"fingerprints": [
"8dbb5a7c06c20ef62dd912a36740992ff6e1e8583d42ede257c3affd7c769399"
],
- "id": 329
+ "id": 329,
+ "legacy": true
},
"0b9fa5a59eed715c26c1020c711b4f6ec42d58b0015e14337a39dad301c5afc3": {
"fingerprints": [
@@ -21978,7 +23120,8 @@
"57014f3cbe1782aa9b7921c5e3a95afd26d5727d9475d0142e6b6d27798133c0",
"5b38bd129e83d5a0cad23921089490d50d4aae370428f8ddfffffa4c1564e184"
],
- "id": 250
+ "id": 250,
+ "legacy": true
},
"0c7acaa710226720bbc940349ee2e6148652a89dbf406a232c895f6dc78ebb9a": {
"fingerprints": [
@@ -21990,25 +23133,29 @@
"fingerprints": [
"af71a3bca322e5224df546895696ce449a8bd2bd130f7a7ae457767f5c23d8f8"
],
- "id": 314
+ "id": 314,
+ "legacy": true
},
"0f9c1299557598cf7521bcc8798420a155cec1bb23a57ac37f5120fc9a2057f8": {
"fingerprints": [
"a73563e859cbcfa173cf3285debf2578ede15d47a3bee385861ab7a4fb6d7b6e"
],
- "id": 433
+ "id": 433,
+ "legacy": true
},
"0fe14c264b17bb6f0d653e7a70eb363dbf54be158039eddae5c25711df48c103": {
"fingerprints": [
"6fff78e400a70c11011cd85977c459fb5af96a3df0540820d0f4b8607875e58f"
],
- "id": 270
+ "id": 270,
+ "legacy": true
},
"1069fa47a0aa4f8cf7111b1caea365eeaed10bfff32660def6e0614bfae70875": {
"fingerprints": [
"a53125188d2110aa964b02c7b7c6da3203170894e5fb71fffb6667d5e6810a36"
],
- "id": 45
+ "id": 45,
+ "legacy": true
},
"10ba3485ca8bb6880ab9531a4063e4001555561c7f2e055165f49b2d74fc5f6b": {
"fingerprints": [
@@ -22020,25 +23167,29 @@
"fingerprints": [
"a9c77af1bcdfaa3739442b0b2734c68eaf2e9833f0d766fbcaa6f2aeb42dec02"
],
- "id": 442
+ "id": 442,
+ "legacy": true
},
"112432e4bb848c45549fcbf0c710c566d0082bbbc4e9b38e6c76ad46448128fc": {
"fingerprints": [
"afe80a97ea11159190e927e08ec2e60c59a40559483a3fee838a85321b3aeaad"
],
- "id": 388
+ "id": 388,
+ "legacy": true
},
"1255cabe8152fa64df942f7a47417e29f96c1ce11bf8c84ecbe2815cc1280810": {
"fingerprints": [
"9bea11c976fe014764c1be56a6f914b5a560317abd9988393382e5161aa0493c"
],
- "id": 469
+ "id": 469,
+ "legacy": true
},
"1462009b2de65d6d4d39be892bd2c186490531ce6590e48fe196070d317b60b0": {
"fingerprints": [
"739710c5245e33ec8a243a1b20048fc9d5f4528599213845c164d004b8b667f9"
],
- "id": 330
+ "id": 330,
+ "legacy": true
},
"149f2ee63b9a5e5803240a770dc991fc2e3445e62831c245a49bc4f1f738ff9c": {
"fingerprints": [
@@ -22050,13 +23201,15 @@
"fingerprints": [
"c7ba6567de93a798ae1faa791e712d378fae1f93c4397fea441bb7cbe6fd5995"
],
- "id": 146
+ "id": 146,
+ "legacy": true
},
"15bb28d9207e13f8bc9557dd785eba773bea944e04d7e08ff8aa55ef3194aa20": {
"fingerprints": [
"4210f199499a9ac33c8de02ba6dbaa14408bdd8a6e324689c1922d069715a332"
],
- "id": 400
+ "id": 400,
+ "legacy": true
},
"15e7e717b428feee3af3afd9150dbad497008d3a3ff016964719907bdb01a645": {
"fingerprints": [
@@ -22080,31 +23233,36 @@
"fingerprints": [
"f773bc65659f1bc59087bf214eead864010d5887cd2cd84e4f1ba7523fe55640"
],
- "id": 300
+ "id": 300,
+ "legacy": true
},
"16a9e012d32329f282b10bbf57c7c0b42ae80f6ac9542eb409bc1c2cde50d322": {
"fingerprints": [
"341de98b1392abf7f4ab90a960cf25d4bd6ec65b9a51ce6ed067d00ec7ce9b7f"
],
- "id": 229
+ "id": 229,
+ "legacy": true
},
"16d82d67a1ed8e89f9ab58f7d0fd3eb0d0017687fcaeecd40475f10083a5b593": {
"fingerprints": [
"5f960eebd716dbcb4d8a78b996e680ec2547441e69b4e44e98a595502e28a002"
],
- "id": 165
+ "id": 165,
+ "legacy": true
},
"17755a5c295f3d2d72e6f031a1f07f400c588b9e582b22f17eae31a1590d1185": {
"fingerprints": [
"ca2d82a08677072f8ab6764ff035676cfe3e5e325e012172df3f92096db79b85"
],
- "id": 52
+ "id": 52,
+ "legacy": true
},
"18cfa64518e916cafe985561513cab7a897a54bd23b8e26874c5c7cbd1249cfc": {
"fingerprints": [
"85e0dfae3e55a843195f8b08c8349050e4689372f6e133ad0d199af96e95cc08"
],
- "id": 317
+ "id": 317,
+ "legacy": true
},
"1906c6124dbb438578d00e066d5054c6c37f0fa6028c05545e0994eddaec8629": {
"fingerprints": [
@@ -22116,19 +23274,22 @@
"fingerprints": [
"2f274e48aba4ac7b765933101775506dc30ee38ef6acd5c04932cfe041234220"
],
- "id": 162
+ "id": 162,
+ "legacy": true
},
"19ad98de02155d7e33e9dd21f0e45610fd11d28044b8318bbebf9f6337888df0": {
"fingerprints": [
"1e910b40c08184c0ca20468e824502ff2485163f77b03bb73296823f03885621"
],
- "id": 417
+ "id": 417,
+ "legacy": true
},
"1a421223e89bd87c403b48fa616948470d0f2c21ce2ac7bdd22755061c62ba92": {
"fingerprints": [
"7b1a15d7e5e130c579e68fca189257f837b5c188f1b2b2a791e967cc88cc6528"
],
- "id": 304
+ "id": 304,
+ "legacy": true
},
"1a7a3a1a68dd2361e3f3bb855f3b26fcd88b197d8dd4de06cf1b362ac89ec13b": {
"fingerprints": [
@@ -22140,13 +23301,15 @@
"fingerprints": [
"1ba622b36325544ae922afc22ef9d367943794f6e16874f368a733c65c9d5279"
],
- "id": 419
+ "id": 419,
+ "legacy": true
},
"1c294bc25243768913ed4ad5ed61cb02bfbae0bce6e6e72e5f9658f346b42496": {
"fingerprints": [
"6d3795731a95f8b8a471b9aae5c4f05691b1c11a140fd4b981ad891c367fafd3"
],
- "id": 244
+ "id": 244,
+ "legacy": true
},
"1d75d0831b9e0885394d32c7a1bfdb3dbc1c28e2b0e8391fb135981dbc5ba936": {
"fingerprints": [
@@ -22165,13 +23328,15 @@
"fingerprints": [
"4be8b5a1c76c6aead0611918fccf9dbd398b67fb12294758bdf994d0f9682f60"
],
- "id": 416
+ "id": 416,
+ "legacy": true
},
"1f4224cec84fc99ced881ff6fcfd3e21f8c519c547aa6a5dd3de247302ce50d1": {
"fingerprints": [
"e28393773da845a679f2080cc7fb44a3b7a1c3792cb7eb7729fdcb6a8d99aea7"
],
- "id": 88
+ "id": 88,
+ "legacy": true
},
"2021917e98263945c859c43f1d73cb4139053c414fa03ca3bc7ee88614298f3b": {
"fingerprints": [
@@ -22183,49 +23348,57 @@
"fingerprints": [
"ad016f958050e0e7e46fae7dcc50197ed8e3ff0a4b262e5ddcdb3edddc7d6578"
],
- "id": 398
+ "id": 398,
+ "legacy": true
},
"20e24a5a3393d6c3adc384faf95152e1f9aa7222774028b53c5a34ed0c6cb399": {
"fingerprints": [
"527b050527df529c0f7ad00cef1e7ba421788182615c326c8b6d1a2061a0bd7c"
],
- "id": 351
+ "id": 351,
+ "legacy": true
},
"21ae412566324725ffefc1dccf88f16f8d6bf4dbbb37fe8caba47e8d66c2cdf9": {
"fingerprints": [
"fad540811afae0dc767cdf6572a088fa3ce8493dd82b3b869a67d10aab4e8124"
],
- "id": 477
+ "id": 477,
+ "legacy": true
},
"22050a92836481c2f3c1f8417d37447a167007ac9ba64ea228cb6a1e14c64b8b": {
"fingerprints": [
"1aa980c8c0d316f25029978982f033cbb3a3f4188d669f2de6a8d84ee00a1575"
],
- "id": 379
+ "id": 379,
+ "legacy": true
},
"22076e5aef44bb9a416a28b7d1c44322d7059f60feffa5caf6c5be8447891303": {
"fingerprints": [
"cbb5af185e942a2402f9eacbc0ed5bb876eea3c1223623d00447e4f3ba554b65"
],
- "id": 226
+ "id": 226,
+ "legacy": true
},
"232cbe2d9e6994c1ceb7fbee23ab1657defb6b3564726f1e78951cef3a2b095d": {
"fingerprints": [
"fc0a0fe27c9dc13c81238a5913a1daf8184168beb7e5a4512a771fd4f453651d"
],
- "id": 339
+ "id": 339,
+ "legacy": true
},
"2364d692dccae13da56ad4a07c1325dc575215ff1a071681dfca5dd6ed7c8452": {
"fingerprints": [
"1e1a6984b4e76bd709aee3e9c9cf3118eac096dab9cc20dc25faab67297e965a"
],
- "id": 422
+ "id": 422,
+ "legacy": true
},
"23849d094923d44a4881b63ab185e9be15aac8ef2c3044d934bc7f26e2d2cd69": {
"fingerprints": [
"77407312c63a153d5bc00b4e51759cdfdac237dc2a33b67946e98e9bfa680ae3"
],
- "id": 115
+ "id": 115,
+ "legacy": true
},
"23f2edff3ede90259a9e30f40af8f912a5e5b3694e6938440341f6060e014ffa": {
"fingerprints": [
@@ -22237,7 +23410,8 @@
"fingerprints": [
"2a8da2f8d23e0cd3b5871ecfb0f42276ca73230667f474eede71c5ee32cc3ec6"
],
- "id": 460
+ "id": 460,
+ "legacy": true
},
"2596904dc4d699ae20c2cef4dce47f285937d77464ac370746f52dea76ba0c28": {
"fingerprints": [
@@ -22249,7 +23423,8 @@
"fingerprints": [
"0b5eed4e846403cf55e065848440ed2a82758bf5b9aa1f253d4613cfa080ff3f"
],
- "id": 61
+ "id": 61,
+ "legacy": true
},
"25b41b506e4930952823a6eb9f1d31def645ea38a5c6c6a96d71957e384df058": {
"fingerprints": [
@@ -22267,43 +23442,50 @@
"fingerprints": [
"cf56ff46a4a186109dd96584b5eeb58a510c4275b0e5f94f40bbae865e19f673"
],
- "id": 140
+ "id": 140,
+ "legacy": true
},
"278a6391d3d36b49aa4080f56a36b3c10fba4e28aa6a9592a82e7535113a12d3": {
"fingerprints": [
"8f62d7736f99dbd33ee00e10c7e329339c988a5b47ef25f408293cf2426b4d44"
],
- "id": 163
+ "id": 163,
+ "legacy": true
},
"282fb5cfbaf01518d9704de7884d7a25ff01cf882e994290d5995d5eb6c44988": {
"fingerprints": [
"c1727f3b673e6ae7f12f23d789a7be38b918223ef6911c592da1f583444a547e"
],
- "id": 489
+ "id": 489,
+ "legacy": true
},
"283310819f5e09204995d8ad9ff6fc10746297b5c0ae06bdd1e1124b10a0d7ad": {
"fingerprints": [
"956057517ff3bb35049342288c1c9dce852daca652b465e9747253b5f93b1f5e"
],
- "id": 343
+ "id": 343,
+ "legacy": true
},
"2896b4ddbe61457183cc7ed27bd78ac50a207f6901c5c52e53dc1676f9bb1e06": {
"fingerprints": [
"b0877aee2d39274df831f66fdeeb7717557c258fc9eb55231a9f8a647a75433f"
],
- "id": 241
+ "id": 241,
+ "legacy": true
},
"29e7fdda489e46ee486efd75acc48f251932dc9da1872b31753cd64719567aa5": {
"fingerprints": [
"9b14e8f5f6ea167666e76dcd6becc190861d5e8970b99a9470f0231236049704"
],
- "id": 441
+ "id": 441,
+ "legacy": true
},
"2a29337c3d6224cc53f0bb5e5d5820c0d8848b04871328f090fee3cd6bf821b4": {
"fingerprints": [
"4404e33b5e140dcf998051fdfc8028c7c81615c5ee737b111b588233a9b535a0"
],
- "id": 83
+ "id": 83,
+ "legacy": true
},
"2a4212605aa3e8aecb0fc19806cf3b40b53b95f1a34dbbd6e3ed27230324abb3": {
"fingerprints": [
@@ -22315,13 +23497,15 @@
"fingerprints": [
"8177d1a82ba501afdd1e9483ad7da912ee1e9fcb2a5a061fa3c479fa804ce6ba"
],
- "id": 359
+ "id": 359,
+ "legacy": true
},
"2a8bed32ae680d2d187b9a7afd171d83fd0b935eaf9e2c1b43e80278d2063e39": {
"fingerprints": [
"3b222e566711e992300dc0b15ab9473dafdef8c84d0cef7d3317b4c1821d1436"
],
- "id": 161
+ "id": 161,
+ "legacy": true
},
"2a8f2d8af0eb123898f74c866ac3fa669054e23c17bc7a95bd0234192dc635d0": {
"fingerprints": [
@@ -22339,7 +23523,8 @@
"fingerprints": [
"56ce347cc6df4c35943dfdeaee023f9739a3f1cedeee0cd88dc2386bc8a91eaf"
],
- "id": 311
+ "id": 311,
+ "legacy": true
},
"2bcee858158cf5465fc9d76f0dfa312fef25a4dca8501da9b46b67d1fbfa1b64": {
"fingerprints": [
@@ -22352,33 +23537,38 @@
"fingerprints": [
"ad7539e5cdc985fa95244055a9202d63460ec921467d034cfdbe87ec6d00fedc"
],
- "id": 438
+ "id": 438,
+ "legacy": true
},
"2da8f9ea3454d21146464a3f9d028dc4c7fbb57b1c52c73c2b0572a2f599a2d3": {
"fingerprints": [
"43f257412d440d627476974f877da8f1fc2444565a367ae60eddc27a412531ae"
],
- "id": 269
+ "id": 269,
+ "legacy": true
},
"2dc9470be63ef4acf1bd828609402bb7b87bd99638a643934e88682d1be8c308": {
"fingerprints": [
"d17cd8ecd586b712238a482ce46fa5293970742f276d8ab6a9e46ee0288f3355",
"51847c8cbd2e9a72c91e292d2ae247d7de1e3fd270547a20ef7d610f38b8842c"
],
- "id": 248
+ "id": 248,
+ "legacy": true
},
"2dee5171596ab8f3cd3c7635fea8e6c3006aa9e31db39d03a7480ddb2428a33e": {
"fingerprints": [
"f5074a8f5b9a5b8142f34abe152f60364d770eae75ee3eeceb45b6b996509788",
"ba7f1136389075b8e86c53c095fa14f5c83b6b017a0244ed7637114620d3a3b1"
],
- "id": 264
+ "id": 264,
+ "legacy": true
},
"2e00915a9f7be06ab2370c7b7c200c0a96d5ac6a50ce1874dbefde4022d4de8e": {
"fingerprints": [
"c57a3acbe8c06ba1988a83485bf326f2448775379849de01ca43571af357e74b"
],
- "id": 272
+ "id": 272,
+ "legacy": true
},
"2fc5667a4b9a2678ed6ac6ad25465fcbf6094bfcd9504097c7a8fa47ade5e888": {
"fingerprints": [
@@ -22391,43 +23581,50 @@
"fingerprints": [
"407c276bead2e4af0661ef6697341dec0a1f9434e4eafb2d3d32a90549d9de4a"
],
- "id": 427
+ "id": 427,
+ "legacy": true
},
"3027a298fa57314dc0e3dd1019411b8f404c43c3f934ce3bdf856512c80aa15c": {
"fingerprints": [
"fe863d0822fe7a2353fa484d5924e875656d3dc9fb58771f6f616f9d571bc592"
],
- "id": 256
+ "id": 256,
+ "legacy": true
},
"309f13d49ea66f523241b55524744464e28cc1b82ef79b64e4d581880dcd771f": {
"fingerprints": [
"6639d13cab85df1ad9a23c443b3a60901e2b138d456fa71183578108884ec6bf"
],
- "id": 237
+ "id": 237,
+ "legacy": true
},
"30ab1bcd7bed1ff2679f71228820420a7063c6cead7ec30d4a016154876dddb5": {
"fingerprints": [
"c57bacf238f9336c3dfba62d12bcf5823603e5842c44e62f5448cc7e5f4cad59"
],
- "id": 280
+ "id": 280,
+ "legacy": true
},
"30b71c4f9122476e761e620eec42bfa5f84c493cd49bbb1834b26e555f60de40": {
"fingerprints": [
"00ab444abd6bdba33da8de569ac4ecde326d1be1a61442d5eec3975a0c243f04"
],
- "id": 360
+ "id": 360,
+ "legacy": true
},
"31512680233f5f2a1f29437f56d4988cf0afc41cc6c5da6275928e9c0beade27": {
"fingerprints": [
"363f3c849eab03b0a2a0f636d7b86d04d3ac7fcfe26a0a9121ab9795f6e176df"
],
- "id": 254
+ "id": 254,
+ "legacy": true
},
"31de0cb19f2adbb0d1cd7b1b31ef8ee3eb59b74459aef94b480beeeeb85c64c9": {
"fingerprints": [
"f4c149551a3013a35bc7bffe17a7f3449bc1ab5b5a0ae74b06c23b90004c0104"
],
- "id": 147
+ "id": 147,
+ "legacy": true
},
"3219b09114ff495a3eb6eb00c2efeab34002ae5f0a56c7679ea087a3fa037e4f": {
"fingerprints": [
@@ -22446,7 +23643,8 @@
"fingerprints": [
"e74fbda55bd564c473a36b441aa799c8a68e077440e8288b9fa1e50e4bbaca11"
],
- "id": 471
+ "id": 471,
+ "legacy": true
},
"3380709af3b096be3cc2a40548142c0a520028db09e2cb77ae2206616ab6cbb4": {
"fingerprints": [
@@ -22458,13 +23656,15 @@
"fingerprints": [
"959dc5880c457cd92e5447aaa5609db09ed47bd02c17a0edefdc819e756c74e5"
],
- "id": 233
+ "id": 233,
+ "legacy": true
},
"33fa5a5300613d466e6f85c8051695bed5d1fad59f25e040acda0472a74f3c20": {
"fingerprints": [
"d3d607a9ff24a19523b6da9d2c649446f8788cb96d9fd130972e120c13677730"
],
- "id": 458
+ "id": 458,
+ "legacy": true
},
"348767cdad3bdd28b2b8dd5351aec30c68cec5cd69d276df3827dbc4f5806464": {
"fingerprints": [
@@ -22476,13 +23676,15 @@
"fingerprints": [
"21db20123660bb2ed418205da11ee7a85a65e2bc6e55b5af7e7899c8a266d92e"
],
- "id": 138
+ "id": 138,
+ "legacy": true
},
"3551de58a7d79cd980283df81790d63a982c1a63b30482ec5821db7661554ef9": {
"fingerprints": [
"35ae5bddd8f7ae635cffba5682a8f00b95f48462c7108ee9a0e5292b074aafb2"
],
- "id": 150
+ "id": 150,
+ "legacy": true
},
"36abc32656acfc645c61b71613c4bf21c787f5cabbee48348d58597803d7abc9": {
"fingerprints": [
@@ -22506,37 +23708,43 @@
"fingerprints": [
"8f9adb6d895dab5adf5c3d3fab83927be0fb64ef82485c62280d584e8bd55d22"
],
- "id": 459
+ "id": 459,
+ "legacy": true
},
"381a3fc7a8b082fa28613a4d07f2c7553f4e1918ee07caa9e8b7cede5a9ca06a": {
"fingerprints": [
"d487a56f83b07482e85e963394c1ecc2c9e51d0903ee946b02c301581ed99e16"
],
- "id": 192
+ "id": 192,
+ "legacy": true
},
"3861d7b6961fcdb2120456ff6fc2eb7704b1a741b4bd933a8376f5e1915ca698": {
"fingerprints": [
"0791ca0749b20782aad3c7d7bd0cdfc9485835843eb2d7996009ce43ab6c6927"
],
- "id": 101
+ "id": 101,
+ "legacy": true
},
"3a0d885cb346d8f01fd300af1546f6355c00690e340ed98f346e77b574be3fd8": {
"fingerprints": [
"6e5e93ae867fd3e3e78304e054d1a6aeaed0295d58c0e3fc4c9ffe310a3488cc"
],
- "id": 303
+ "id": 303,
+ "legacy": true
},
"3a6c24e80f681d8b1047cec051c27594f885ba0887a26379092dfef506160e9b": {
"fingerprints": [
"06a2c9a3379ab3c156159a27ca9ecdbd4ef75309b409cf70aeca9a12330f380e"
],
- "id": 279
+ "id": 279,
+ "legacy": true
},
"3a803e7c0a43a29fd73672e3d0bb2c3653d948ede0b3cb1db4ce75a857e89af1": {
"fingerprints": [
"b7b12b171f821daa990cd0fe5087b128448ba8e5184f84c51e02b5c8fb962b24"
],
- "id": 143
+ "id": 143,
+ "legacy": true
},
"3b0d73b4be4a854adc3e51d7ef9fa48aefbb2cdd824d67bdc7d7d09a2abc2d43": {
"fingerprints": [
@@ -22548,19 +23756,22 @@
"fingerprints": [
"62b9267266212832a8e22dab933d91c7011274acf71703f9cc97833751a6e94f"
],
- "id": 14
+ "id": 14,
+ "legacy": true
},
"3bde97686e3af51d3f572c4888c12bd1d1e097f12f49ec3c92896551e36f0085": {
"fingerprints": [
"6cf5f658436d10507eba9df463987480bc8560a8e26ef4691e1d3c9a878a0952"
],
- "id": 245
+ "id": 245,
+ "legacy": true
},
"3c196f84e2a0c61fec18bacabd31783b574517aad8ebc6ce6d1d7dc82b3c50df": {
"fingerprints": [
"527a42267daea8d8f54e91d282d5c25b615bc0dc73dc63a58f916c4ed5bf59ac"
],
- "id": 318
+ "id": 318,
+ "legacy": true
},
"3c35e164bedd2cf12beb83ecff78b5e80da8158d2830217e4ebffce8928899a6": {
"fingerprints": [
@@ -22572,49 +23783,57 @@
"fingerprints": [
"67ec2059fbf52d2e6ab51a5a9b3fc2e1dcd658a1ef3a8f31107bc98028b494a2"
],
- "id": 315
+ "id": 315,
+ "legacy": true
},
"3d8d061edcf7b3d45995ba4341328d1be7b7eb4e9d14fee70d2f18ad68bea7c5": {
"fingerprints": [
"732ff5bc473c33efaad9b187fb459a732ffbeea59df0fdfb8e2fb5def4032afe"
],
- "id": 436
+ "id": 436,
+ "legacy": true
},
"3ea7b5c045a99a9771e2dea8e8098ba2732d17ceee82279552feee905530f35f": {
"fingerprints": [
"075bfcca2d55ae6e35742c32afd0ca8ea4c958feefc23224999541c033d69c8d"
],
- "id": 420
+ "id": 420,
+ "legacy": true
},
"3ec18dfeb894a9ea20eb2cd40c693e2a29144fe2ec60b4f7b89026040b39aebe": {
"fingerprints": [
"a3cc68595dfe7e86d8ad1772a8b5284add54ace3b8a798df47bccafb1fdb84df"
],
- "id": 461
+ "id": 461,
+ "legacy": true
},
"3ee6b341402851b27e64021a3023aac7c1a0d2def27d5bce5c2dbeb0b22dcc71": {
"fingerprints": [
"65353833cf234c79562164f90849c0d104dbabf8ee41064d83e8cbe03ba1c5a5"
],
- "id": 481
+ "id": 481,
+ "legacy": true
},
"3fab784fc3c9ab9eedc12ecdc0db550f4c3dbfd3e86d78815333c5eba518cb9d": {
"fingerprints": [
"a31f093053bd12c1f5c3c6efd498023fd2914d7758d05d698ce084b50626e0e5"
],
- "id": 225
+ "id": 225,
+ "legacy": true
},
"3fb63c29f47bcc4e6aadb3577ce7ca8543e0bbaba553676b8fd161295bdb9011": {
"fingerprints": [
"0b9f26dfca684c2cfce23e4e4dd567c886ba259e1db267f9806f0c5a099711f2"
],
- "id": 368
+ "id": 368,
+ "legacy": true
},
"4002fcd311d07331567e71bcd971e46048c8dce8d1659711753b3daa2a269afa": {
"fingerprints": [
"85fb2f91dd12275a0145b636534f84024ad68b69b8ee88684ff711375805b348"
],
- "id": 47
+ "id": 47,
+ "legacy": true
},
"40fcfc28875dccbfebcbdf6cd7433312da63c4efcf3bd7b1b505c22020ae0274": {
"fingerprints": [
@@ -22626,7 +23845,8 @@
"fingerprints": [
"15d5b8774619ea7d54ce1ca6d0b0c403e037a917f131e8a04e1e6b7a71babce5"
],
- "id": 485
+ "id": 485,
+ "legacy": true
},
"4223894003a881c5df6bab163db235c221a18d54bf759945820e670da82e3f39": {
"fingerprints": [
@@ -22638,98 +23858,114 @@
"fingerprints": [
"2d66a702ae81ba03af8cff55ab318afa919039d9f31b4d64388680f81311b65a"
],
- "id": 409
+ "id": 409,
+ "legacy": true
},
"42a807cec5ae9c0f03b40ca043ac70468b5219bd75cc5bbea51d921dd100156f": {
"fingerprints": [
"5adfa25013bed3710831572de51c4b9a21171c00313249c4cb4719d37fbb8d20"
],
- "id": 466
+ "id": 466,
+ "legacy": true
},
"431b79fd9355d10dc1b50dbf6a6b62d7a5b6d356541c27605255ca4ca79420c1": {
"fingerprints": [
"f563c5c3e512e63b97b5438f2bd4a9ae78a4f9ead92bcc34fe973bdc7c6d2148"
],
- "id": 340
+ "id": 340,
+ "legacy": true
},
"4376a99396769fd487240ee8b573ad49706a5b9473616acef38409e91586dc1e": {
"fingerprints": [
"c2157309d9aee17bf34f4df5e88dbaeba57e0361eb814cbc239f4d54d329a38d"
],
- "id": 444
+ "id": 444,
+ "legacy": true
},
"439c19ff3edb265ef1a920f74a4802d3dd95ace024e21e5a6ce8e064dc1566cd": {
"fingerprints": [
"34bb34e14faed0d3392f2fc441c0ecd5fd88ad88118df2d1ba76cdec1eea10b8"
],
- "id": 447
+ "id": 447,
+ "legacy": true
},
"43c74262f7492662d2459bcc9899bac54a4ecc01e1a3f5e76558992b40152418": {
"fingerprints": [
"a3d7435a18c46b23b6a4f8929cd59050c9168b03a7fad532626f297cac5356e4"
],
- "id": 414
+ "id": 414,
+ "legacy": true
},
"43cffc359f2e8caa57388ee9f6f1dbe93bf093682a699ac3852e6d1f8579e7f9": {
"fingerprints": [
"39df7b682b7b938f84715481ccde8d60d8f22ec598877d0aaac12b59182b0312"
],
- "id": 56
+ "id": 56,
+ "legacy": true
},
"4462c107c485dd6a5443f5e7a1604416034a374c3f4d10875f1c3715027563af": {
"fingerprints": [
"f38406e540d7a9d90cb4a9479299640ffb6df9e224ecc7a01c0d9558d8dad77d"
],
- "id": 156
+ "id": 156,
+ "legacy": true
},
"44a3d80d3f5348596d80a09842c23a39774439f8b0b919239d2a03dac5ce5213": {
"fingerprints": [
"b2f3c4216af7aff72462466dc13cd2810db8eed853eabb9a063a608efc18fbe8"
],
- "id": 403
+ "id": 403,
+ "legacy": true
},
"44af8afcf1395d2a8e30ef812ce19ceb2e8948dfd21e00fbaa34689f9a24721f": {
"fingerprints": [
"c470cf547e2302b977fb29dd71a89a7b6c1f60777b0329f56017f328bf4f6be6"
],
- "id": 51
+ "id": 51,
+ "legacy": true
},
"463dbb9b0a26ed2616397b643125fbd29b66cf3a46fdb4384b209e78237a1aff": {
"fingerprints": [
"2930bd09a07126bdc17288d4f2ad84645ec948607907a97b5ed0b0b05879ef69"
],
- "id": 353
+ "id": 353,
+ "legacy": true
},
"4691cbfde84a6b6052ddbe152bb0c216ae25a86e5747813dbc0f147f338570be": {
"fingerprints": [
"bd81ce3b4f6591d11a67b5fc7a47fdef25521bf9aa4e18b9e3df2e34a7803be8"
],
- "id": 2
+ "id": 2,
+ "legacy": true
},
"4697a5abea0070a395456fd358e91f72f227d5850933227f1e0bc79ff847bfac": {
"fingerprints": [
"2dfcbacadf22a6ff107a51fd3e8b9e17858028879b13f7c3b57b3e1bd2315809"
],
- "id": 352
+ "id": 352,
+ "legacy": true
},
"479d130bf3fc61dc2f1d508d239a13276ae7b3c9841011a02c1402c7e677bd5f": {
"fingerprints": [
"f59db3f45d57fcec94ccd516e6c8ccb20dd4363feb2c44d8656e95f50fdd8df8",
"2f1062f8bf84e7eb83a0f64c98d891fbe2c811b17ffac0bce1a6dc9c7c3dcbb7"
],
- "id": 263
+ "id": 263,
+ "legacy": true
},
"47c7a149ca82fa7ba940a4d711d010625c6cb0b748b17016c46e25ce7acd2b0c": {
"fingerprints": [
"92d8092ee77bc9208f0897dc05271894e63ef27933ae537fb983eef0eae3eec8"
],
- "id": 266
+ "id": 266,
+ "legacy": true
},
"482f76a2a9346dbb077619bbe1efecd54107e992ff4e8f4d70a39e2405d939d4": {
"fingerprints": [
"e3efb6118a92e3b858fd806f690e31d46b95ca1bd756da2b3037fe2f87cc9137"
],
- "id": 278
+ "id": 278,
+ "legacy": true
},
"4905466623ab4178be92ac5cbd6584f7a1e17f27652d5a85af89504ea239aaaa": {
"fingerprints": [
@@ -22747,25 +23983,29 @@
"fingerprints": [
"9db930a7bced5a599da673d0bb12c4c6c7ab5b3f88f39c24ee20a24716b379df"
],
- "id": 332
+ "id": 332,
+ "legacy": true
},
"49b80685d332e072c0e7b720032647e842106104e0b1139ab9e811bfb11ec034": {
"fingerprints": [
"940ef46536713d8e2eb4b501e80b6abd8eb4e9928dba44784ce7d7e98595dfe8"
],
- "id": 285
+ "id": 285,
+ "legacy": true
},
"49cbd83c03cabfa0713b97bc96481d035fd4ebe06f07fab5640ed9232d8110b2": {
"fingerprints": [
"c34c5df53080078ffe45b21a7f600469917204f4f0293f1d7209393e5265c04f"
],
- "id": 457
+ "id": 457,
+ "legacy": true
},
"4a2659666dc0203b916f53d80ad8f61ac30bea161f485cc7527e6a5937e49216": {
"fingerprints": [
"8de78655e1be7f7847800b93f694d21d368cc06e033e7fab04bb5eb99da6b700"
],
- "id": 188
+ "id": 188,
+ "legacy": true
},
"4a49edbd2f8f8230bd5592b313573fe1c172a45fa98011cc1eddbb36ade3fce5": {
"fingerprints": [
@@ -22783,37 +24023,43 @@
"fingerprints": [
"b5bd2cb79cbd1907298d6bdf4842e516d8c78fa6fc96d25f71af814e16cc245e"
],
- "id": 381
+ "id": 381,
+ "legacy": true
},
"4ba6031ca305b09e53bde3705145481d0332b651fe30370dd5254cc4d2cb32f3": {
"fingerprints": [
"76ef4762e573206006cbc338b17ca4bc200574a11928d90c3ef31c5e803e6c6f"
],
- "id": 328
+ "id": 328,
+ "legacy": true
},
"4bdc636f48d21fb68c5a3cd4a20685788043bdb524e7e84d4192c451ee3429b5": {
"fingerprints": [
"92bf5119abeccad0b1332dc4e1d05fba75b5679044ee0ca26e931f744f2f33cf"
],
- "id": 131
+ "id": 131,
+ "legacy": true
},
"4cc29758a2cb9b50109987f37537cf0c55ba2e6798937307a00296b01dffe44a": {
"fingerprints": [
"6cfb09893dfdf9457e3303592aa4755bc859ab6ba6a2e11c11cddc2409abda02"
],
- "id": 284
+ "id": 284,
+ "legacy": true
},
"4d40e7af4304a09de87fbf9896204c055141e3f809b2fe733bb2310fdf98a162": {
"fingerprints": [
"6ea54741d004667eed1b4816634aa3a79e6e4b96950f8279dafc8d9bd8812137"
],
- "id": 155
+ "id": 155,
+ "legacy": true
},
"4e6c1616637199b5077a80ad0c2248c725e576fc8a719989456bc9cafddb7524": {
"fingerprints": [
"c795ff8ff20c966688f064a1e091421d3110a3456c17ec2404b998738741f622"
],
- "id": 454
+ "id": 454,
+ "legacy": true
},
"4eada9b5311e718199d98ea82b95005cba93198ab1f97efcbe8dc6201628f8af": {
"fingerprints": [
@@ -22825,25 +24071,29 @@
"fingerprints": [
"209e956af04df3996507c887d356230d6eb49fdbdd2d8a058ff50b8f80f690aa"
],
- "id": 470
+ "id": 470,
+ "legacy": true
},
"4f7162b974491c98585ec28fe759aa00c330d0b465190a896cc4b616231831fc": {
"fingerprints": [
"c1d80ce474a51128b77e794a98aa2d62a0225da3f419e5c7ed73dfbf660e7109"
],
- "id": 476
+ "id": 476,
+ "legacy": true
},
"508f8c6178af329bb6bb753ab943d9023be796c3adbb6c5cd4664b66feeccae5": {
"fingerprints": [
"6ec6614e9a8efd47d6318ffdfd0bf65b493a141f77c38d0b319be1bbbc053dd2"
],
- "id": 413
+ "id": 413,
+ "legacy": true
},
"5094b73b736adf73a0cbf43e27bf14407b4a36aa363a457fce33949ceba8e649": {
"fingerprints": [
"eb7e05aa58e7bd328a282bf8867033f3c035342b516ee85c01673dffffbbfe58"
],
- "id": 385
+ "id": 385,
+ "legacy": true
},
"50cc86ba96db3263c79a43ead07553d9f56659e6907e72d8c026637a1cdc85dc": {
"fingerprints": [
@@ -22861,7 +24111,8 @@
"fingerprints": [
"b644d955fff29b74e3b5687e908ee7c3c9197ba3336cc6328531f6c057d677fd"
],
- "id": 406
+ "id": 406,
+ "legacy": true
},
"5192438ec369d7ee0ce71f5c6db75f941efbf72e58441715e99eab04c2c8acee": {
"fingerprints": [
@@ -22873,13 +24124,15 @@
"fingerprints": [
"c2959db8339e8dbcf6409ca92a66c49fd2e32494940a901143bd7eb72827dec2"
],
- "id": 324
+ "id": 324,
+ "legacy": true
},
"522c3960328026a1e322389a8a08fedc1b86d9c2b59b33484b77f7ce790635d7": {
"fingerprints": [
"687ea89089309d2cfe107db059fb10d676f45d3283aee056903eea0cf3c188f8"
],
- "id": 320
+ "id": 320,
+ "legacy": true
},
"5375662628fa0a6840aec8c592bf5d8de564ed3efb62c7c932fca8d754d9bbd6": {
"fingerprints": [
@@ -22897,7 +24150,8 @@
"fingerprints": [
"c45d7bb08e6d67e62e4235110b564e5f78fd92ef058c840aea4e6455d7585c60"
],
- "id": 484
+ "id": 484,
+ "legacy": true
},
"56174d3ad971a8944964b189811f3008493a6a90422e3c5804ec838d4f94f622": {
"fingerprints": [
@@ -22921,31 +24175,36 @@
"fingerprints": [
"e389360d0fdbaeb3d250584b4730314e222f39c156a020144e8d960561791506"
],
- "id": 121
+ "id": 121,
+ "legacy": true
},
"57a742a88d3e18fc0bc611bc7976c22edc50011757512b1a7e2e1d069b3ecba0": {
"fingerprints": [
"bebce57dcb85f60a93bfa5019edb1a294bf6d81f82d9b4e71f502f0b15a1fc08"
],
- "id": 464
+ "id": 464,
+ "legacy": true
},
"58044626c34c1a7b158ddb676d9e2e65443d818dab3116231e2d62ab6426a0b7": {
"fingerprints": [
"7286ce249fe9e32bd4752257c17cd8f6991a9c1e6f1a3cc73304ed023e6ae4eb"
],
- "id": 440
+ "id": 440,
+ "legacy": true
},
"5899d913ead119b9cdb7ba2f30efe0df68ad2cd225bdf493e8323a25aa4dbe23": {
"fingerprints": [
"d7ba3f4ff8ad05633451470dda3378a3491b90005e5c687d2b68d53647cfdd66"
],
- "id": 482
+ "id": 482,
+ "legacy": true
},
"58a2a698d86fd8497d41f68e4caeb4a98874f433da913dd26c5ca44d08ff72fe": {
"fingerprints": [
"0536801fbb443b3e905fd6d70d8c81eb88551be8061299110d2b4f82e64cade1"
],
- "id": 401
+ "id": 401,
+ "legacy": true
},
"58dd61feb36ea7d258724371709149cb121337864cacb2d0999ad20739d06477": {
"fingerprints": [
@@ -22975,43 +24234,50 @@
"fingerprints": [
"1d4f0596fca2611d09f84c78f2ea565ef2eab9cfc272a1718bd336e6e0ae021a"
],
- "id": 346
+ "id": 346,
+ "legacy": true
},
"5c41a73ab2c35dfcd771f6fd6e3e8fac9b469d386cadda56a95b646eb48cca34": {
"fingerprints": [
"d43af9b35473755c9684fc06d7d8cb70ee5c28e773fb294eb41ee71722924d24"
],
- "id": 468
+ "id": 468,
+ "legacy": true
},
"5dee74cc343db93f8deaf9e41fbc65b334254b5b23b568fa2814db8b7321ac85": {
"fingerprints": [
"4dbb0157a691fa7382289d65c0332ddb1dcb640b40ad10f010a43e20f3afed1e"
],
- "id": 296
+ "id": 296,
+ "legacy": true
},
"5e7673a17a08d61413cd51b57dbaacbebfe5acb915e3966e5321b13eb9efaaeb": {
"fingerprints": [
"6dea86a1e66620a040c3c5943cb215d2ca87fb6ac09b59707e29d2facbd66b4e"
],
- "id": 159
+ "id": 159,
+ "legacy": true
},
"5efa073f49426344483ab0ddbbdda5e35972f9c47c74ddf98ec42290b251ca97": {
"fingerprints": [
"aad9ceed5aa6b1cea28596a8e4e1abed9386d6ebc9d4aad9acde0fa36ba069d0"
],
- "id": 271
+ "id": 271,
+ "legacy": true
},
"5f665b4060be9efaf6ad739f6b39a1db9847277eb8dc144045376de1009e3127": {
"fingerprints": [
"630419aec478cbb4bb8083de9d9cf279752f039def16e46471b679ca93002db0"
],
- "id": 164
+ "id": 164,
+ "legacy": true
},
"6046136879e56450400f7db2ecd0df1b88f667c1e3fffc52964ff9e2e48e85f5": {
"fingerprints": [
"730b619eaa759863c65360b7412e1457eca96844ef2f16d91fcf2efe46a647e9"
],
- "id": 344
+ "id": 344,
+ "legacy": true
},
"6106c0e3a0a299831875127bd7d3cc1859803d511cac11eb6e0840dd166fc10e": {
"fingerprints": [
@@ -23036,13 +24302,15 @@
"fingerprints": [
"e609078465a419780cb6ac4c1c0bfb4653d9d9cc6eb3946eb7f3d69997bad598"
],
- "id": 5
+ "id": 5,
+ "legacy": true
},
"62a31a5c730dba674ddb25de33df143644375b49af07878a667b813491c73971": {
"fingerprints": [
"31eace9b4c9c71734a185680bc24866ca6cbd82b3cb61bcc8706261b59ce1073"
],
- "id": 323
+ "id": 323,
+ "legacy": true
},
"63d9af9b47b1064d49a10e7b7fd566dbc8caa399459bfc2829c571ad8c6ef34a": {
"fingerprints": [
@@ -23054,13 +24322,15 @@
"fingerprints": [
"0c0b6b2bd1edd7b27fead157f8e846b335b784a39f06c47216c8746f64c5ceda"
],
- "id": 448
+ "id": 448,
+ "legacy": true
},
"651bd66f5c3dc637957ef5185e4fa671c21654b1c0ea49384f44bcb256a5084c": {
"fingerprints": [
"3f9da4744ec9676cd38b530e500a463fbcb18165977ff0da6d5993c3fe5fab7c"
],
- "id": 362
+ "id": 362,
+ "legacy": true
},
"6544ff9adb642c4c3698a60d8143b6b93bcef01365b540f614dcc2a45ab94d31": {
"fingerprints": [
@@ -23073,19 +24343,22 @@
"0ed3ffab6c149c8b4e71058e8668d429abfda681c2fff508207641f0d751a3e5",
"ca7a5e68c53d2c51f72f6b465d3ed753f5903ec7901c8d0f55d868337c81975a"
],
- "id": 221
+ "id": 221,
+ "legacy": true
},
"66b00539826a37484930191e028f62dab1cbc89b3acd472dc4e5905e47bf7364": {
"fingerprints": [
"6ea1db6719d6041a06fc0898e5b3cf349a8fa8ecee85edb005965628f617f7c8"
],
- "id": 428
+ "id": 428,
+ "legacy": true
},
"674039e472561963c8cb00d21a97a90a18bb8a1c4c317ac67e382a652bb573c0": {
"fingerprints": [
"c2b9b042dd57830e7d117dac55ac8ae19407d38e41d88f3215bc3a890444a050"
],
- "id": 216
+ "id": 216,
+ "legacy": true
},
"675605f1567e25fbd2526befea2aefbdb2279f3e1baa3a303ae7555d1bda3ee4": {
"fingerprints": [
@@ -23097,13 +24370,15 @@
"fingerprints": [
"604d32d036895aed3bfefaeb727c009ec0f2b3cdfa42a1c71730e6a72c3be9d4"
],
- "id": 452
+ "id": 452,
+ "legacy": true
},
"67a84264d42e204a9a5b0a3667b951db22c505df95ed983b5e8c4d1fce77af43": {
"fingerprints": [
"19abcdff3a74402fa8f0ca206bf7fab0dffff3ae2bbd719584d21090a4353207"
],
- "id": 480
+ "id": 480,
+ "legacy": true
},
"67dc4f32fa10e7d01a79a073aa0c9e0212ec2ffc3d779e0aa7f9c0f0e1c2c893": {
"fingerprints": [
@@ -23115,37 +24390,43 @@
"fingerprints": [
"d41d829e8c1659822af93fce62bffcde264fc84e8b950c5ff275d052354695a3"
],
- "id": 126
+ "id": 126,
+ "legacy": true
},
"682747f8ba621b87cdd3bc295ed5cabce722a1c0c0363d1d68b38928d2787f1e": {
"fingerprints": [
"2cabeafe37d06ca22aba7391c0033d25982952c453647349763a3ab5ad6ccf69"
],
- "id": 487
+ "id": 487,
+ "legacy": true
},
"689bf45b3083fdead55f147fd105e3cf218ad58edf3e4b301c0c5eeea6cf210d": {
"fingerprints": [
"417dcf3180f4ed1a3747acf1179316cd48cb05c5788435168aed98c98cdcb615"
],
- "id": 429
+ "id": 429,
+ "legacy": true
},
"68c3692214724d4b55a760f470b4fca8b5e0fe1d729cff22feb4ca88acd39809": {
"fingerprints": [
"ae4457b40d9eda96677b0d3c92d57b5177abd7ac1037958356d1e094518be5f2"
],
- "id": 231
+ "id": 231,
+ "legacy": true
},
"6a436b58d9d830e8d5b8a642505ad6b41406adcd6894d9414f7be0a1467badb7": {
"fingerprints": [
"05d38c2a70bfc500ccb0cb509159b46b065c6ac9cb42d2e6f16167841434572a"
],
- "id": 426
+ "id": 426,
+ "legacy": true
},
"6a7b1482127002f9005a87356e1dc3e00b70bbbfa795024ff8beff74c4259b75": {
"fingerprints": [
"f657a633eeb9bc5d15a461751749ea4b316727dcf1a9f986b5458445f6485dde"
],
- "id": 421
+ "id": 421,
+ "legacy": true
},
"6b1a505e0246f2f60c490ff0c097a7be27210cbb7500237f88b0cd48298bc9b8": {
"fingerprints": [
@@ -23164,7 +24445,8 @@
"fingerprints": [
"3266967e59cd68008d9dd320811185c704205e8d95fdd84f1c7b311e6704fc32"
],
- "id": 261
+ "id": 261,
+ "legacy": true
},
"6bcfc86c8ddc2af2e6a1180a2ddabb37b7ea3755316b64b9b8951bf0ca351f06": {
"fingerprints": [
@@ -23182,20 +24464,23 @@
"fingerprints": [
"2dc62c3f6c0cc9020bba77e1c511511024b943ee598856da5a22e222b7277a20"
],
- "id": 277
+ "id": 277,
+ "legacy": true
},
"6cae87c558d2441568e38270a8dd8ff484a259dc4f3ce94ccf434c1fa99811f6": {
"fingerprints": [
"9806ab8509e2f35e192f275f0c308b9409b42512f90c659598c22be613962272"
],
- "id": 325
+ "id": 325,
+ "legacy": true
},
"6d28f9e405148b69027da990815211c858841c543feced008c238021983c095a": {
"fingerprints": [
"0378b202ccabba99a12e569a11a077db1edb39482061c75d0073059d9ab5b513",
"e5c01cb4093279faa19fcfa24ea43eb1b26d07a615adf7240184a1e716b761c9"
],
- "id": 376
+ "id": 376,
+ "legacy": true
},
"6d6f0c340971a218a31d10330ea9ae7c7a6550534c6eefeddd2118e114db473e": {
"fingerprints": [
@@ -23219,19 +24504,22 @@
"fingerprints": [
"2d47437de17951215a12f3c58e51c729a58026ef1fcc0a5fb3d9dc012f600d19"
],
- "id": 151
+ "id": 151,
+ "legacy": true
},
"7006a38311e58fb193484233218210c66125a0e4a826aed539ac561dfbfbd903": {
"fingerprints": [
"92a9d9833fe1944db366e8bfae7a95b6480c2d6c6c2a1be65d4236b608fca1bb"
],
- "id": 227
+ "id": 227,
+ "legacy": true
},
"7016270b60b28c6e177edebd718007dfd3310c64a737b7db01a07690c343bc27": {
"fingerprints": [
"cd0b3b2aa174b55f18c7502f3c3a76f2198175ce45637370cf4f48b9c2ce4fbf"
],
- "id": 389
+ "id": 389,
+ "legacy": true
},
"702116ccd8bf23e16466f0e0dba0ed6a239a9c1cd6a8f5a66b39af3595020385": {
"fingerprints": [
@@ -23249,13 +24537,15 @@
"fingerprints": [
"126bf01c1094d2f0ca2e352380b3c724294546ccc65597bef7f12d8a171f1984"
],
- "id": 242
+ "id": 242,
+ "legacy": true
},
"71ed918a7ac6d17b3849c20180b3e7334691bc5fb73377f0070afa0be789b2d1": {
"fingerprints": [
"c31eef5682abb551ebc828ded84098518a6768526d152ee164cfb972a1425d53"
],
- "id": 446
+ "id": 446,
+ "legacy": true
},
"76ee8590374c715437bbca6bba6028eadde2dc6dbbb8c3f610e851f11d1ab7f5": {
"fingerprints": [
@@ -23279,19 +24569,22 @@
"fingerprints": [
"6ccfd302fc44bf4599329b9750878ea44e7e8566564bcbd586169762dd10c74e"
],
- "id": 435
+ "id": 435,
+ "legacy": true
},
"78cf3d3c72daf91cc51b871357a551cf95b837d074c270b08facd463a8d39bb3": {
"fingerprints": [
"82d42db3d657f1944e65c192b1dd58db8df8417b89165b045f5c6a70c5f8939e"
],
- "id": 437
+ "id": 437,
+ "legacy": true
},
"7aedddf36b18f8acb7379fe1ce183212b2350d0788abe0e82457be9badad6d54": {
"fingerprints": [
"8b45da1c06f791eb0cabf26be588f5fb23165c2e614bf885562d0dce50b29b02"
],
- "id": 195
+ "id": 195,
+ "legacy": true
},
"7afe4b071a2f1f46f8ba944a26d584d5960b92fb48c3ba1b7cab84905f32aacd": {
"fingerprints": [
@@ -23304,7 +24597,8 @@
"fingerprints": [
"af6d08eef3cac4e1584abc63c8a9472ac529af99f3f791319a43776063f58dca"
],
- "id": 341
+ "id": 341,
+ "legacy": true
},
"7caa03465124590c601e567e52148e952c0cffe89000530fe0d95b6d50eaae41": {
"fingerprints": [
@@ -23322,13 +24616,15 @@
"fingerprints": [
"e57210ab812c8df308267cb4291b98e956597ca36ec2b95189ef1723396bcac8"
],
- "id": 306
+ "id": 306,
+ "legacy": true
},
"7d6c3ebf9ea735d1854beea7cb941ab1e3503515e087bbb5be695d05f2f556e4": {
"fingerprints": [
"2193cfea381211a1aeaa2de984e630643a87160b1208118145eafb8e1bc69958"
],
- "id": 473
+ "id": 473,
+ "legacy": true
},
"7e0ead76bb6819dc2f54511a84354f6e8b307b9dd82058ea6c004f01d9dda5df": {
"fingerprints": [
@@ -23340,7 +24636,8 @@
"fingerprints": [
"f375e2f77a108bacc4234894a9af308edeca1acd8fbde0e7aaa9634e9daf7e1c"
],
- "id": 395
+ "id": 395,
+ "legacy": true
},
"7e8782c150ce3952f802e636023a5d3e95bb5d68e33e85adb2ba178125cebf15": {
"fingerprints": [
@@ -23352,7 +24649,8 @@
"fingerprints": [
"7af6ea9f753a1e709bd64d0beb867c11e8c295a56e24a6e0471459dccdaa1558"
],
- "id": 274
+ "id": 274,
+ "legacy": true
},
"7f4296fc5b6a4e3b35d3c369623e364ab1af381d8fa7121533c9d6c633ea2461": {
"fingerprints": [
@@ -23364,13 +24662,15 @@
"fingerprints": [
"22e0d11dc9207e16c92b2ee18cfdb2c2e940626847921fc528cedd2f7932f714"
],
- "id": 349
+ "id": 349,
+ "legacy": true
},
"805c6696266b96b147468a321eba9eb8b5968f2c477cdd95fdadd1fc63dd614b": {
"fingerprints": [
"a9a9ca22890d694919c095bb8064cbc4a525a5dbfaf801ec935dbccc07c8baee"
],
- "id": 298
+ "id": 298,
+ "legacy": true
},
"808d68b3fab4884a5f971ace7d10550d7a95a163774f3ec36afffb213fbe4c74": {
"fingerprints": [
@@ -23382,25 +24682,29 @@
"fingerprints": [
"53dfdfa4e297fcfe07594e8c62d5b8ab06b32c7549f38a163094fd6429d5da43"
],
- "id": 258
+ "id": 258,
+ "legacy": true
},
"80dbfb97bdd3926baee41f73c5588faa17d707b03adf4907a2bc677f3ef1717c": {
"fingerprints": [
"7afc9d01a62f03a2de9637936d4afe68090d2de18d03f29c88cfb0b1ba63587f"
],
- "id": 214
+ "id": 214,
+ "legacy": true
},
"816ba0bfdf5fd64d568ec0d052f71164d9e2ccae12e0219ed6cd81e7e845fb84": {
"fingerprints": [
"fb47d92a9909fd4fa9bec02737543e1f3514ced747407a8d9cfa397b0915067c"
],
- "id": 423
+ "id": 423,
+ "legacy": true
},
"81a98fc788c35f557645a95224e50cd1dac8ffb209dc1e5688aa29205f132218": {
"fingerprints": [
"c38dcb38959393358691ea4d4f3ce495ce748996e64ed1891d897a0fc4dd55c6"
],
- "id": 166
+ "id": 166,
+ "legacy": true
},
"82b5f84daf47a59c7ab521e4982aefa40a53406a3aec26039efa6b2e0e7244c1": {
"fingerprints": [
@@ -23412,27 +24716,31 @@
"fingerprints": [
"1e49ac5dc69e86d0565da2c1305c419330b0b781bfec50e54a1b35af7fddd501"
],
- "id": 276
+ "id": 276,
+ "legacy": true
},
"85a3d81d2ad0c79df0a79684e0e2666009a09de15760ea1d76cf0ee7b2825dbd": {
"fingerprints": [
"a1b2dbeb64e706c6169e3c4118b23baa09018a8427666d8bf0e28891ec051950"
],
- "id": 410
+ "id": 410,
+ "legacy": true
},
"85d26be90d934fccdb4ff7b38d8c79ca7652b816d6a52446ca8428a6b85dc57c": {
"fingerprints": [
"e3268f6106ba8b665a1a962ddea1459d2a46972f1f2440329b390b895749ad45",
"e0e17aea06cf9ce12aae8190345a2c59720130a7d8ff72f3745ad75dbaa365b6"
],
- "id": 273
+ "id": 273,
+ "legacy": true
},
"860a7f19210d5ead057a78532b80951453cb2907315f3ba7aa47b69897d70f3f": {
"fingerprints": [
"bd469ff45faae7c54ccbd69d3f3b002255d9b06b10b1d0fa388bf96b918b2ce9",
"944554239d91ed9efedcf906d5e8113160b46fc816dc6bdc77b89da29b6562b9"
],
- "id": 249
+ "id": 249,
+ "legacy": true
},
"86a68f050034126a540d39db2c5f917ef66a94fb9619fa1ecd827cea46ba0cb0": {
"fingerprints": [
@@ -23444,25 +24752,29 @@
"fingerprints": [
"b9bea7860a962ea3611dab97ab6da3e21c1068b97d55575ed0e11279c11c8932"
],
- "id": 53
+ "id": 53,
+ "legacy": true
},
"86c84b1c3a66f4285af797052467e3ed236fd2986f033c02c4771be0b970482a": {
"fingerprints": [
"90f3e05396995ff20922c44592db62d7845e1bf64aef512cca75bc669caa2479"
],
- "id": 366
+ "id": 366,
+ "legacy": true
},
"87157a7585f4d03b00a398461e164e4806e1b3f46d03afbdc9def4e4778be2e9": {
"fingerprints": [
"007e452fd5cf838946696dfe37a2db2ef3991436d27bcbab45922053c15a87a8"
],
- "id": 378
+ "id": 378,
+ "legacy": true
},
"871a9194f4eed5b312ff40c84c1d524aed2f778bbff25f138cf81f680a7adc67": {
"fingerprints": [
"2a575471e31340bc21581cbd2cf13e158463203ece94bcf9d3cc196bf09a5472"
],
- "id": 483
+ "id": 483,
+ "legacy": true
},
"87af34d66fb3f2fdf36e09111e9aba2f6f44b207f3863f3d0b54b25023909aa5": {
"fingerprints": [
@@ -23474,7 +24786,8 @@
"fingerprints": [
"e5bda820e5ce15bfd07ba11ffb1c7c8a5910ce1b90175c34308bc2500453ccdc"
],
- "id": 322
+ "id": 322,
+ "legacy": true
},
"891ff898e4a8d555140056e3176eea91f4d808ee7f6d1bfbcce6f84807639f91": {
"fingerprints": [
@@ -23486,7 +24799,8 @@
"fingerprints": [
"ffcef2224e29b0b36ec8314e686822f3ac0f1c5e0c2d5c0eb2484ce7e2540fd0"
],
- "id": 321
+ "id": 321,
+ "legacy": true
},
"8a27b5557b4bec7cc0305fbf3d53d1f71cd3f34910c5d65e27ecddb82077ba3d": {
"fingerprints": [
@@ -23504,31 +24818,36 @@
"fingerprints": [
"cd201256fe5ced0bfff8df595fff36b1416d5313a999f532ef4a9915df96dee0"
],
- "id": 392
+ "id": 392,
+ "legacy": true
},
"8a903b600a080b38dfe20dfb6acd23122f64620e5808b9fc8688952fc1a3559c": {
"fingerprints": [
"59b3829f1ff443344958fae8bff621b684c848cfbf7ead6b63a6ca50f2794f89"
],
- "id": 275
+ "id": 275,
+ "legacy": true
},
"8ab4e88556cbf864a5e9fd50171cd4ed8424e8f0801b99e236c810915950ae4b": {
"fingerprints": [
"894ce6ddb012cb3f736954668de63f436080e95f17b7a81bd924eb21bee9e440"
],
- "id": 370
+ "id": 370,
+ "legacy": true
},
"8adb238554a0cbfc3a11fecc183e3cd2c23d25e7894cf2bbae58eb70a44e7cf3": {
"fingerprints": [
"9676f287356c89a12683d65234098cb77c4f1c18f23c0e541de0e196725b7ebe"
],
- "id": 234
+ "id": 234,
+ "legacy": true
},
"8b49506a3461063ea8cc13ffce2b581de15a94b957092a93123467b89ed802e2": {
"fingerprints": [
"606223d9db80df3939601e74b7e828e2800cce4273f76f276aa62db0a8e3b6c1"
],
- "id": 375
+ "id": 375,
+ "legacy": true
},
"8bb593a93be1d0e8a822bb887c547890c3e706aad2dab76254f97fb36b82fc26": {
"fingerprints": [
@@ -23540,7 +24859,8 @@
"fingerprints": [
"efb5157e9c66caa1dcc63c9fac0127cde83b7a426c4579b7b43a41ba46a56deb"
],
- "id": 418
+ "id": 418,
+ "legacy": true
},
"8d767764b3cbda08929d072a22a561f4dcdd1bc57d3cbddc948c47d2b47f9122": {
"fingerprints": [
@@ -23552,31 +24872,36 @@
"fingerprints": [
"b8bbe523bfca3b11d50f73f7f10b3ec8ec958aa1dc86f66d9541907ff1a110ef"
],
- "id": 384
+ "id": 384,
+ "legacy": true
},
"8e15d426cd04898f218be2e5fe3784f375094cc435dc61ad86c4a3c01511dbe1": {
"fingerprints": [
"7a77c6c61eeeb9aa65c4ea410d65d895b26a81123283009db104b48de80b2479"
],
- "id": 439
+ "id": 439,
+ "legacy": true
},
"8e8046ec4cac015a507ce0d2d0154a4b40e8e42b3165cfa546571435112d17e5": {
"fingerprints": [
"d48d3d23eedb50a459e55197601c27774b9d7b18c94d5a059511a10250b93168"
],
- "id": 463
+ "id": 463,
+ "legacy": true
},
"8e8b56f5918a25bd85dce76663fd94cc23690f10ea9586613171c6f8378890d5": {
"fingerprints": [
"894ebc0b23da2a50c0186b7f8f25ef1f6b2935af32a94584ef80aaf877a3a06e"
],
- "id": 239
+ "id": 239,
+ "legacy": true
},
"8ed5b4c041b6b293c0e6413015066d318483c901ff69e86a521d0cb25569f3e8": {
"fingerprints": [
"8327bc8c9d69947b3de3c27511537267f59c21b9fa7b613fafbccd53b7024000"
],
- "id": 228
+ "id": 228,
+ "legacy": true
},
"8fd112c3c8370f147d5ccd3a7d865eb8dd540783bac69fc60088e3743ff33378": {
"fingerprints": [
@@ -23588,19 +24913,22 @@
"fingerprints": [
"ce7dd096c8fde2bf5c438edb574bd6454385334ee8ff106c0f93d5051be6bac3"
],
- "id": 336
+ "id": 336,
+ "legacy": true
},
"913119f2cd3f48aca74ea6443ee50e0de1202d9c54f336dc9300affe97d4577c": {
"fingerprints": [
"eefca888db442cea1f03fac5de5b1af210ae03f5e1658ddb880c645e78624546"
],
- "id": 394
+ "id": 394,
+ "legacy": true
},
"915086ccd4ed1ea749b427f6b0ceb4a0ef5b4a1cf18070539c0f2a758185a382": {
"fingerprints": [
"eac0220c5c9fecc5121d3720872d06707b5266be25d4ebb56ab804bbbf85fe03"
],
- "id": 224
+ "id": 224,
+ "legacy": true
},
"927a1b8562280576d048c50321ada43d8703d2d9521a18c28b8c46cc6aae4efd": {
"fingerprints": [
@@ -23625,25 +24953,29 @@
"b41d516a5351d42deea191fa6edf2a67dee2f36dc969012c76669e616b900ddf",
"77e04c9a751c73f23e2a1336112ec8d5153d382a152fed89d7532c3102771f3c"
],
- "id": 319
+ "id": 319,
+ "legacy": true
},
"93657f8530c596bf909e50da7d8d9cbb36b824cc16ab589137e1438011bc9901": {
"fingerprints": [
"d68f7730b1ec2b3fb698c96d76540c9997415a25737dcd61d44960db77d2723d"
],
- "id": 282
+ "id": 282,
+ "legacy": true
},
"9392ae2149924ade37e645dba1ff4bdddcda2b291b6097669d2afa5c7a372619": {
"fingerprints": [
"8da084fcf99ce07722f89b3205939806fa5cb811e1c813f6a108c7d336b3408e"
],
- "id": 76
+ "id": 76,
+ "legacy": true
},
"93a9b3c96aae1cd661215d0c2a065da963d7160d1c694621bcb28c406df64db2": {
"fingerprints": [
"8a968aadd88b20519672a452a3d6e31eacb71c26bcaf65b32f9793bf2ffa54a9"
],
- "id": 246
+ "id": 246,
+ "legacy": true
},
"94072ad3f58f70f93098e5a5f6c04c96c710bd849d83184919ae90eb890ae400": {
"fingerprints": [
@@ -23655,7 +24987,8 @@
"fingerprints": [
"958abbaeff760f4fbf66ff0f2c2708f4739b2c686127239a2c4ec87a68a984c8"
],
- "id": 478
+ "id": 478,
+ "legacy": true
},
"942a6916a6e4ae527711c5450247a2a74fb8e156a8254ca66e739a11493bb445": {
"fingerprints": [
@@ -23667,7 +25000,8 @@
"fingerprints": [
"632d80bb096d209677d1734e5b35ea9d3019b9c44f8fcb2640c879039ac94ee8"
],
- "id": 391
+ "id": 391,
+ "legacy": true
},
"951ee046fa83316e6786c08c44f13b4ca2ead2d2644d63314391c0cc70887d0d": {
"fingerprints": [
@@ -23686,19 +25020,22 @@
"fingerprints": [
"49f74f824f2e059fe99c98af3219ec0d9a004d1b64dd2fd1452616318ab806c0"
],
- "id": 347
+ "id": 347,
+ "legacy": true
},
"95735473bd67a3b95a8d5f90c5a21ace1e0d7947320674d4ab847972b91544d2": {
"fingerprints": [
"b32396746453442f353e616292bb20bbaa5d23b546450fdb9c54b8386167d529"
],
- "id": 259
+ "id": 259,
+ "legacy": true
},
"96475b35acb1c9303a90bd1dbf57418f78e29af11c4de8c8cba2e5f9309e38d4": {
"fingerprints": [
"b04d708f1ae0456265dd1b66907a2691a28680b853e031df3df9083af71614d7"
],
- "id": 316
+ "id": 316,
+ "legacy": true
},
"967b0cd93fcef7f27ce2c245767ae9b05a776b0649f9965b6290968469686872": {
"fingerprints": [
@@ -23716,7 +25053,8 @@
"fingerprints": [
"997e15c5a4481a8598499753971ee2601d1047c3635aff21af4221a817fd2d96"
],
- "id": 425
+ "id": 425,
+ "legacy": true
},
"9736ac3b25d16c45a45418a964578156480a8cc434541ddc5dd59233229868de": {
"fingerprints": [
@@ -23728,140 +25066,163 @@
"fingerprints": [
"cbd8ed38d4a2d677d453d70dd8890af4f6374cba6299943f1ab3a6936c6fd795"
],
- "id": 396
+ "id": 396,
+ "legacy": true
},
"98008e2edbb72bad42da2fcb06ac1aaa0b2e6e0c72e8ca204fbafd1bb4879441": {
"fingerprints": [
"04acfb3b24793f300f67ef87e44dd72cb9b28b204f389a7cd5ae28785c7d42cd"
],
- "id": 238
+ "id": 238,
+ "legacy": true
},
"980922eee07f86bc7f5e5e95d57db8bdae68e17a421c4e72a96a708a87920124": {
"fingerprints": [
"327a3d761abadea034eb998406275cb1a4776efdae2fdf6d0168ea1c4f5567d0"
],
- "id": 149
+ "id": 149,
+ "legacy": true
},
"9847e5653e5e9e847516e5cb818606aa7544a19be67fd7366d506988e8d84347": {
"fingerprints": [
"71cca5391f9e794b04802530b363e121da8a3043bb26662fea4dca7fc951a4bd"
],
- "id": 486
+ "id": 486,
+ "legacy": true
},
"98b3f10a025041910f197cf17ca0fcdfed75fb2c8c14a843e04d5656c9ebac1a": {
"fingerprints": [
"9a73929a500f1a0bf49dcb046e8039169696557345e9f813f10ff9380db22695"
],
- "id": 235
+ "id": 235,
+ "legacy": true
},
"98ca29f313386721afbf5d14f1abcaa1dc63cc8d1fd7dc361f6b01368938f24b": {
"fingerprints": [
"7c7ed4240bb253bb35c376e12e00b027f1659df9d8267422a93eed75edc7adfb"
],
- "id": 223
+ "id": 223,
+ "legacy": true
},
"991b5ed1b2fd364b9f634b624b305203f29908be318ef6399222d8a3ef7990e5": {
"fingerprints": [
"2602d21e81277a83f6048128f61d794a06f474e1f75e49740a817c2666f62211"
],
- "id": 299
+ "id": 299,
+ "legacy": true
},
"99333c3a665cf0efbb7488b3807b8b65f87b5b29d6880f028edc28442eeae669": {
"fingerprints": [
"8b3fdb151af759c566143e07c950ede4f9e8c7cf808453d33bcb78e52a400af9"
],
- "id": 434
+ "id": 434,
+ "legacy": true
},
"9962ab1699b0eb7c7e8a578bc79893042031c1158c633613199a90b9652a2a75": {
"fingerprints": [
"1501f89c5c4dcf36cf588a17c9fd7cfceb9ee01e8729be355e25de80eb6284b4"
],
- "id": 462
+ "id": 462,
+ "legacy": true
},
"9adb99c93ab256ecca2b5350c75048a8584c12dfc248e3f60ea9354c34ebfcce": {
"fingerprints": [
"03458b6abeecc214953d97149af45391691de9f9cdcc2647863a3d67c95c243b"
],
- "id": 65
+ "id": 65,
+ "legacy": true
},
"9b219d0fbff36a5fb32090571906bceea68617c833a3f61b81e962a8e64db8af": {
"fingerprints": [
"63343abfb89a6a03ebb57e9b3f5fa7be7c4f5c756f3017b3a8c488c3653e9179"
],
- "id": 217
+ "id": 217,
+ "legacy": true
},
"9c6f6a123cbaa4ee34dbeceee24c97d738878cb423f3c2273903424f5d1f6dd5": {
"fingerprints": [
"87c678bfb8b25f38f7e97b336956bbcf144bbacaa53647e61a2325bc1055316b",
"b4410b73e2e6eaca47fbc42f8fa4018af4381dc54cfaa84450461eed09454de9"
],
- "id": 135
+ "id": 135,
+ "legacy": true
},
"9d98a1fb60538c4cc4857ff1a8c8034faf6fc592093f619994b2c813d250b864": {
"fingerprints": [
"7d8ce822222b90c0b14342c7a8145d1f24351f4d1a1fe0edfd312ee73fb00149"
],
- "id": 333
+ "id": 333,
+ "legacy": true
},
"9dc38a9edcf82842b674da186b6d6215ab9e2ec6d72f57b08a892728c31431f3": {
"fingerprints": [
"ae92e90000541a9ebc101b70b6c33a62f5a53a55ba815e81d31abddf03507f5d"
],
- "id": 342
+ "id": 342,
+ "legacy": true
},
"9dd55fc573f546cb6a3831d1112d8710a6f4f82dc87f5fae9d3a1a028dd36e4b": {
"fingerprints": [
"1c01c6f4dbb2fefc22558b2bca32563f49844acfc32b7be4b0ff599f9e8c7af7"
],
- "id": 11
+ "id": 11,
+ "legacy": true
},
"9e5a34b08929bc0a581c8936aafd6ab7517bb15188b4f6fc02c45906f71595b0": {
"fingerprints": [
"5e3571f33f45a7df1537a68b5ffb9e036af9d2f5bc4c9717130dc43d7175aac7"
],
- "id": 354
+ "id": 354,
+ "legacy": true
},
"9ea9fe274537f4f935642cde824fd77eb0e125cf118ab9b4c219f6cbf959b18d": {
"fingerprints": [
"8f1ecdaf29bcd56eddd6b5d56a07fcac2b74d4bcd179179144a0365c27dcf14b"
],
- "id": 431
+ "id": 431,
+ "legacy": true
},
"9ecc51368e86e3460f66c295e4942dd53080f27b1e410aff2d1aa9d4e6bc7e7c": {
"fingerprints": [
"62f240278c564c4dd8bf7d9d4f6f366ea894d22f5f34d989a983acec2fffed50"
],
- "id": 144
+ "id": 144,
+ "legacy": true
},
"9efd911d6ff46f1831111df3c54cd2611cae2398ff7386d1cb6b4f32e3337ed6": {
"fingerprints": [
"b2259996fff735ab35014ef63f3d413190079dd03a0962432635a8695f995305"
],
- "id": 407
+ "id": 407,
+ "legacy": true
},
"a12574f4eb7395cc630a15fec8db1c7c828f66699d984c8c897eca44c808f55d": {
"fingerprints": [
"c499f6cecc5da4d61f14ed0405270c5249d0e79615b0da42659ed2d7ffef8a40"
],
- "id": 310
+ "id": 310,
+ "legacy": true
},
"a1d45d06297341b1f3a735cfa38f283e6879fec06281a361e5f417cc70d29dc9": {
"fingerprints": [
"81c2568503eb3be5eec366653960e6d1be9448915e4605b793fbeb34ccb2470f"
],
- "id": 424
+ "id": 424,
+ "legacy": true
},
"a25a7214c2b6c86142ada39dff2d73d865aa57843fdd2db77b3febf82683de2d": {
"fingerprints": [
"c0c05a8d8da55eaf27aa9b910b0a6ef0d8bbded346928db872e182c2073e9802"
],
- "id": 240
+ "id": 240,
+ "legacy": true
},
"a2dc98ca7cbbee1822b25b267bd5ca502fa7b0cf4fff0703ee6a416703f3c7ea": {
"fingerprints": [
"c1b12f480020336e5b04f520bc19c2e2e10ab42c9d9235f05cbec33ffa4d4dea"
],
- "id": 334
+ "id": 334,
+ "legacy": true
},
"a320f4d534d7be97c1ae8dd0499735bc895c323add2d388bfccf662c23d7f99a": {
"fingerprints": [
@@ -23873,43 +25234,50 @@
"fingerprints": [
"49c8175a9815e08bef129a929de1bacad04e4db67a8c839293953e5031c81ca0"
],
- "id": 307
+ "id": 307,
+ "legacy": true
},
"a4003bd5bdd894e01a8e01e06b62c7aa82f03de5253133570aad4fd0e7d81d3c": {
"fingerprints": [
"7f12cd5f7e5e290ec7d85179d5b72c20a5be7508ffdb5bf81ab9684a7fc9f667"
],
- "id": 106
+ "id": 106,
+ "legacy": true
},
"a4b89bb70656ea498f2d9e00a497fdb9dcd20b81b8938e952bba2df9f65729c3": {
"fingerprints": [
"5a1b5d6bc65523b40a6deffa45b48e4288ae8dd86dd70a5b858d4a5affc94f71"
],
- "id": 371
+ "id": 371,
+ "legacy": true
},
"a4cbf48516af3160ebc62acac6e7f258609ed0891535010c16692493a9fe1fbf": {
"fingerprints": [
"8ba1bd9c88efb3947e60ebe21137f81df7f09994cef27f097055018b8194c634"
],
- "id": 449
+ "id": 449,
+ "legacy": true
},
"a51a2f3a050e838a5050696578dbbedaac1a107ee2d9d48fae505d18d0da5cf8": {
"fingerprints": [
"70b922bfda0e3f4a342e4ee22d579ae598d071cc5ec9c30f123680340388aea5"
],
- "id": 260
+ "id": 260,
+ "legacy": true
},
"a5204dbb2754b97e3c8a104eacb374a6498a438773c75077f0063c2ceb25d2a2": {
"fingerprints": [
"e8b28d2a3d81f63b4e4467c2190a631fc062353b5f2d25851dda6b644ac78b3f"
],
- "id": 305
+ "id": 305,
+ "legacy": true
},
"a59d2f09c8b168cd9afa3bc3eb4db0d7a43588d523287f2b83a822eb33709170": {
"fingerprints": [
"9cefb0cb7b74e642932532831e0dc8f4d68ad414261fc3f474b795e72a164e57"
],
- "id": 453
+ "id": 453,
+ "legacy": true
},
"a6e11ff15ec326a5e3f18ad33a056694dc84c699766d028a5ad0efe1a8e53ac7": {
"fingerprints": [
@@ -23921,38 +25289,44 @@
"fingerprints": [
"5f0b62eab5e353ea6521651658fbb65359f443280a4afbd104d77d10f9f04c07"
],
- "id": 70
+ "id": 70,
+ "legacy": true
},
"a74b4b6a2eb55b9864c04ecb16003ff5db5b51e42cf859f95e9d0a1dd4644096": {
"fingerprints": [
"e8c6aa6b5f58a8f2a6365cf98e65693563a38b7b2f32cf1be06f2d2229d4bf59"
],
- "id": 364
+ "id": 364,
+ "legacy": true
},
"a76e2949cb87f6236b5f68c690747587d6448ea21cfead7950084ac015190b25": {
"fingerprints": [
"229ccc196d32c98421cc119e78486eebef603aecd525c6b88b47abb740692b96"
],
- "id": 455
+ "id": 455,
+ "legacy": true
},
"a798d92f76c9c6755e5f55f86cd14aedcc0655371e27ccde0377745ce3c50013": {
"fingerprints": [
"058a40323ec8c46262c3052a5d357b91ac24d3da26351b3ff4407e99f7a4e9b4"
],
- "id": 356
+ "id": 356,
+ "legacy": true
},
"a7a8f039894f5f675e92a778e008e424c9417dba06a1738b45b4e08d36fc2d7c": {
"fingerprints": [
"75c9d4361cb96e993abd9620cf043be9407a4633f202f0f4c0e17851cc6089cd",
"f28630babf256e567b5821069fcf13148ab9a23e28fc0d70615aae6ed284f4c8"
],
- "id": 220
+ "id": 220,
+ "legacy": true
},
"a7e39bd7df609bef3262bf3db4dc8f3814e0db5a7a52156a6d0c35b4dae8a6ad": {
"fingerprints": [
"b3c962d34019fb38ab9fe9c62399742ab26c43c2d18ce3f2b13c14321e52964b"
],
- "id": 301
+ "id": 301,
+ "legacy": true
},
"a81293445db196a2030f9e455fe3c74a9a4f8317b02b01406027a8708174434c": {
"fingerprints": [
@@ -23964,7 +25338,8 @@
"fingerprints": [
"93e65ec762f055dc718a332582c41a04430d72e3cb87e8b897b67516f0d1aa39"
],
- "id": 268
+ "id": 268,
+ "legacy": true
},
"a87443b3d896eb257ccce99b95ada9bc81b9db4e3142aa9a99af0942cb0a4a3a": {
"fingerprints": [
@@ -23976,13 +25351,15 @@
"fingerprints": [
"a71272aeaaa3cfe8727f7fb39f0fb3d1e5426e9060b06ee6f13e9a3c5833cd43"
],
- "id": 4
+ "id": 4,
+ "legacy": true
},
"aa1c2bedb1a508baad7fb3f5e02897b907c748dea9b7908904aadbd0497aab6a": {
"fingerprints": [
"cd808284cf746ff2fd6eb58aa1d59c4ad4b3ca56fdc6274a8926a7835f32313d"
],
- "id": 252
+ "id": 252,
+ "legacy": true
},
"aa2630a7b617b04d0a294bab7a8caaa5016e6dbe604837a83a85719fab667eb5": {
"fingerprints": [
@@ -23994,19 +25371,22 @@
"fingerprints": [
"cb6b05d9e8e57cd882b10b4db70de4bb1de42ba48a7bd0318b635bf6e7781a9d"
],
- "id": 265
+ "id": 265,
+ "legacy": true
},
"ab39a4b025955691a40269f353fa1d5cb94eaf6c7ea9808484bbbb62fd9f68f3": {
"fingerprints": [
"2834991cf677466d22baac3b0055e5b911d9a9e55f5b85ba02dc566782c30e8a"
],
- "id": 262
+ "id": 262,
+ "legacy": true
},
"ab5cdb3356397356d6e691973c25b8618b65d76a90486ea7a8a5c17767f4673a": {
"fingerprints": [
"309b4a87f6ca56c93169aaa99c6d988854d7892bd5437e2d07b29cbeda55d35d"
],
- "id": 160
+ "id": 160,
+ "legacy": true
},
"ab98495276adf1ecaff28f35c53048781e5c1718dab9c8e67a504f4f6a51328f": {
"fingerprints": [
@@ -24018,61 +25398,71 @@
"fingerprints": [
"2dde9d0c0a90e7b32b5abc01f41799d42e95a1e3c31c3b39373bb8141ea54471"
],
- "id": 451
+ "id": 451,
+ "legacy": true
},
"ac447dedd0432aab9c070f2cca01b6dab09bef07cf4ca6aaa755634f857b315a": {
"fingerprints": [
"d1a0319098034e3aec729a0b5c3111229d9d26e3e623e8c5e6843fa06ee8e2e4"
],
- "id": 479
+ "id": 479,
+ "legacy": true
},
"acf65e1d62cb58a2bafd6ffab40fb88699c47397cf5cb483d42d69cad34cd48b": {
"fingerprints": [
"e6b8f8766485f807ae7f8dac1670461f07c0a13eef3a1ff717538d7abad391b4"
],
- "id": 24
+ "id": 24,
+ "legacy": true
},
"acf7ad98e6f065866e6f8cdf0ceb6f7481f6957b6dff823f6b94d79f01a61c39": {
"fingerprints": [
"ea7e312ece487b4c0aa63cc80ab9fcb33c720573f8945f7761745fc63863d39d"
],
- "id": 382
+ "id": 382,
+ "legacy": true
},
"ad304c884a5d376bd195209a14c39e07f0d3f5cf893d802b053e1b926e55d774": {
"fingerprints": [
"488e134f30c5db56b76473e608086842bf21af8ab3cd7ac67ebdf125d531834e"
],
- "id": 390
+ "id": 390,
+ "legacy": true
},
"ae2033b3082825a703e5a6adc3221a86854aa411db047dd5f53eb84aa14bdc01": {
"fingerprints": [
"c109e0d1b64000b01e894bdaa955e1ff91b6d084a838d90e044b9e3fcd2a8bfa"
],
- "id": 383
+ "id": 383,
+ "legacy": true
},
"ae56d847973d199390e66e4024c9f87d87371e8ba8876af83d1e644f54664738": {
"fingerprints": [
"b7a7ec419454411761225ecf30d99585f851356077bf83274b11588fd05521b8"
],
- "id": 281
+ "id": 281,
+ "legacy": true
},
"af110f6b5ae8b767eac6e0aa273f3816e7a40a644edacb4398146356e77509d6": {
"fingerprints": [
"46273285615d96e52da9fc2ed8c036f10af3d9f6280f8d288706c52b2011b4da"
],
- "id": 386
+ "id": 386,
+ "legacy": true
},
"af207c61fd9c7cf92c2afe8154282dc3f2cbf32f75cd172814c52b03b7ebc258": {
"fingerprints": [
"cb627d18b58ad56dde331a30456bc65c601a4e9b18dedcea08e7daaa07815ff0"
],
- "id": 257
+ "id": 257,
+ "legacy": true
},
"af6ab51b7bad1dedd533eb59332b6227d6557f20b4443216db735b92280c7a44": {
"fingerprints": [
"bcdd8df4276366d7ff4b688dc81500d8e98252c049c8ff1e8c82f2baec9d5c16"
],
- "id": 337
+ "id": 337,
+ "legacy": true
},
"aff988906dde12955d9bebbf928fdcc31cce328d5b9384f21c8941ca26e20391": {
"fingerprints": [
@@ -24090,7 +25480,8 @@
"fingerprints": [
"5b1d9d24de0afea8b35ba04a1c3e25d0812cdf7c4625de0a89af9fe4bbd1bb15"
],
- "id": 412
+ "id": 412,
+ "legacy": true
},
"b0f6f15b4817ebe6fe0b4bfcd7d3ace4c758b0ab6f8a9da2ed92e618239d9c98": {
"fingerprints": [
@@ -24104,25 +25495,29 @@
"e7685634efacf69ace939a6b255b7b4fabef42935b50a265acb5cb6027e44e70",
"6872586219c349d85aaa4586a14451f2451ae3b6092dbb1effb0147c33bf0fd4"
],
- "id": 72
+ "id": 72,
+ "legacy": true
},
"b16cb1ba529a39e2dfd53b3ff5a79f1904614d83e31304f0278bb40b38cf7824": {
"fingerprints": [
"0771920c8cb874d5c5a4dc0d6a51a2d495d38c4de2cd5b83d2a06faa051935f6"
],
- "id": 432
+ "id": 432,
+ "legacy": true
},
"b1be0f7a5e638b559d8b521fef6017ad8fa16eb0548e846b2ac4b41d89b41f14": {
"fingerprints": [
"da98f640194df128c7888bc8e3479a9dd31795ff087c649052fbafb02eaef184"
],
- "id": 211
+ "id": 211,
+ "legacy": true
},
"b213a9cbaa9a8831ac0b3aa80e9d15856cd43a7cc2e0bac5fcb84a24751a8a78": {
"fingerprints": [
"54ae8a683fe2d78ff1ef0e0b3f58425092953ba08c67fe4a95595d1cebcdcb30"
],
- "id": 450
+ "id": 450,
+ "legacy": true
},
"b21d2a743318712ba16f39919d961a4bafba3bca9a43a75b1fcfe22c5d70caba": {
"fingerprints": [
@@ -24134,50 +25529,58 @@
"fingerprints": [
"ebf3c02a8789b1fb7d511995d663b72906d913ce0d5e10568a8a77e2586167e7"
],
- "id": 48
+ "id": 48,
+ "legacy": true
},
"b3182e289ae34ddf2be643ab79c244301605fa0f1eaae6d10fb929600af84df0": {
"fingerprints": [
"f00355eef101c7df4e46cce6417dffce3db82dbb1369c3b439c4e33bee445c42"
],
- "id": 355
+ "id": 355,
+ "legacy": true
},
"b4296d5fe60e52f3f0ff99da75af5e7e62599f99ebe0fa413f66e6b425c3d09f": {
"fingerprints": [
"9df0ec44f55b36d79d4b53c208bef8cb63d78dcc8fcafde1662312f212204a37"
],
- "id": 348
+ "id": 348,
+ "legacy": true
},
"b489ccb224b9a6b81dd274ceaf5209c252998c9a76af48e4f4c50a0728461825": {
"fingerprints": [
"1e51942b84fd467bf77d1c89da241c04254dc8f3ef4c22451fe7a89978bdcd4f"
],
- "id": 465
+ "id": 465,
+ "legacy": true
},
"b4a039eafc4310ba9bde093edb8f9d9d0b3d4c7c004d48288c35dbcc19467d18": {
"fingerprints": [
"af8b6762a1e528228161a95d5c559ee266278f75d79e830189a503506abd6b4c"
],
- "id": 82
+ "id": 82,
+ "legacy": true
},
"b5ec35baab538884cfa8dd97376b102f03e53b482c64100c250722ae9b042cbc": {
"fingerprints": [
"fc50b26bdc4a8fdf1344cc80157ae13ac671e2706facfc0605fe34e249eb72d6"
],
- "id": 430
+ "id": 430,
+ "legacy": true
},
"b638cff05c8a832758edc3028af9e2d55514568bc6bb34ab36d140b97ac6b12d": {
"fingerprints": [
"0f4e9cdd264b025550d170806340214fe94434c9b02f697ec710fc5feafb5e38"
],
- "id": 68
+ "id": 68,
+ "legacy": true
},
"b656a4343831a2acf11eeabc3a44b97025fffba2b910da8714cf827d81be10c9": {
"fingerprints": [
"796b93d0a3ba22e191f2495f150a5f9bfee2ce1503da217b74b8a984685110f1",
"1a2512cda6744abea11432a2fdc9f8c088db5a98c89e13352574cde4d9e80cdd"
],
- "id": 408
+ "id": 408,
+ "legacy": true
},
"b738290cc08547e79ac67f831ebb33547c4e7db4514e2d2988c23c441340eb41": {
"fingerprints": [
@@ -24189,13 +25592,15 @@
"fingerprints": [
"04f1bec36951bc1454a904ce32890c5da3cde1356b7900f6e62dfa2041ebad51"
],
- "id": 475
+ "id": 475,
+ "legacy": true
},
"b9182f52af0dd18e3a99ebbae7883d4e4cc7fe2f81fad0d36ca661efc32d0a92": {
"fingerprints": [
"4bdb7418bdf7ffe33ba0884afa7c0c61fd85a153972f65f7d01cb3ec7eb4073c"
],
- "id": 312
+ "id": 312,
+ "legacy": true
},
"b94c198300cec5c057ad0727b70bbe91816992256439a7b32f4598119dda9c97": {
"fingerprints": [
@@ -24219,7 +25624,8 @@
"fingerprints": [
"fabcf5197cdd7f458ac33832d3284021db2425fd6bea7a2e69b7486e8f51f9cc"
],
- "id": 243
+ "id": 243,
+ "legacy": true
},
"bcfb44aab9ad021015706b4121ea761c81c9e88967590f6f94ae744dc88b78fb": {
"fingerprints": [
@@ -24243,32 +25649,37 @@
"fingerprints": [
"fe7114d07a147759891ff37b4f53eb43568296bc3bf89bc12cafb186985ef28d"
],
- "id": 372
+ "id": 372,
+ "legacy": true
},
"bf01c35f337113f167b4a50186765e7b1e3890af586328f185cd0d6bae813521": {
"fingerprints": [
"f4336bc2ac75950beccf1c1f2f9da6dddafd1f41161ca71f59c76889bd474033"
],
- "id": 415
+ "id": 415,
+ "legacy": true
},
"bfe82909872e4434f115c51a56168019594d0e03dca363d9f3b4839d0babcde5": {
"fingerprints": [
"68ad50909b04363c605ef13581a939ff2c96372e3f12325b0a6861e1d59f6603"
],
- "id": 404
+ "id": 404,
+ "legacy": true
},
"c06c872fc2d0ac08d78d421981fbda4e35500d0946f79894edd21ac29dec0719": {
"fingerprints": [
"2605875afcc176b2d66dd66a995d7f8d5ebb86ce120d0e7e9e7c6ef294a27d4c"
],
- "id": 232
+ "id": 232,
+ "legacy": true
},
"c07135f6b452398264a4776dbd0a6a307c60a36f967bd26321dcb817b5c0c481": {
"fingerprints": [
"44640a0a0e4d000fbd574d2b8a07bdb4d1dfed3b45baaba76f785778c7011961",
"61dc0c0391694c655200c1505ebcc9e4e216bc31a5c51a3611283423c1d89e37"
],
- "id": 167
+ "id": 167,
+ "legacy": true
},
"c1ad1b1898ec395048df070bfa217e25c913bed8ca6b73de085528846a0103c1": {
"fingerprints": [
@@ -24280,13 +25691,15 @@
"fingerprints": [
"8fdd298d1c93b22bfc42aab1c3a15f0d01832ca0a1aef28d5680f06e6c7fd4ef"
],
- "id": 26
+ "id": 26,
+ "legacy": true
},
"c42533d3af4998f5ad9f072521d85d472fa7ffdcfc588c8247b337dc77109389": {
"fingerprints": [
"12d480c1a3c664781b99d9df0e9faf3f1cacee1b3c30c3123a337a4a454ffed2"
],
- "id": 373
+ "id": 373,
+ "legacy": true
},
"c444b5b66ce5d71e1b5e40f27385c95cbfd24a05b56f70cac0992f0f50c3379c": {
"fingerprints": [
@@ -24298,19 +25711,22 @@
"fingerprints": [
"5533a0401f612c688ebce5bf53f2ec14a734eb178bfae00e50e85dae6723078a"
],
- "id": 443
+ "id": 443,
+ "legacy": true
},
"c5697be91cd655539b560758e91b6e085461623741034c485e47d7e9d25a03c0": {
"fingerprints": [
"06db3af2db7baee00c03b9578288bbde541d906eb0069327413295ffb486008e"
],
- "id": 213
+ "id": 213,
+ "legacy": true
},
"c5ea259c629803508649f02177f63c32fa85cc4ad5c35f0d541c45df10a49fd7": {
"fingerprints": [
"3cfc3c14d1f684ff17e38c43ca440c00b967ec933e8bfe064ca1d72c90f2adb0"
],
- "id": 286
+ "id": 286,
+ "legacy": true
},
"c63d68c648a18b77641c427a669d61c9768a55f4fcd0322eac96c57700299cf1": {
"fingerprints": [
@@ -24323,13 +25739,15 @@
"fingerprints": [
"8095210805db4bbc355e4428d8fd6ec2cde3ab5fb97a9942988eb8f4dcd06016"
],
- "id": 3
+ "id": 3,
+ "legacy": true
},
"c746127c5f6b529ce9e2948efd9465444089319acf03f34d0bf37eadc77db22f": {
"fingerprints": [
"6fdb3f76c8b801a75338d8a50a7c02879f6198b57e594d318d3832900fedcd79"
],
- "id": 43
+ "id": 43,
+ "legacy": true
},
"c784333d20bcd742b9fdc3236f4e509b8937070e73067e254dd3bf9c45bf4dde": {
"fingerprints": [
@@ -24347,43 +25765,57 @@
"fingerprints": [
"6468bf8cf3cf688ebb2a6841bd70e97b5229b49df8690d7b74193e9ce3886141"
],
- "id": 397
+ "id": 397,
+ "legacy": true
},
"c90d009c47eeb9f2a29ae848f5d930f2b41ef5edbc5c5695c1414345c1dd67b4": {
"fingerprints": [
"37d8dc8af7867845da3344a6b1bade448d8a80e47b5579f96bf631768f9f30f6"
],
- "id": 358
+ "id": 358,
+ "legacy": true
},
"c954c2c0b189825bb65ddb3ddca080b7dbcfe6b17cade1022bada818336677d0": {
"fingerprints": [
"e873d4082a7b4632934f48a5cc1ee500932f661e56c3467c5c84d31447476b0c"
],
- "id": 308
+ "id": 308,
+ "legacy": true
},
"c9905b0ee01202293ca026e64f08412442c5504c06e44ca7e9726d61f20e4089": {
"fingerprints": [
"df545bf919a2439c36983b54cdfc903dfa4f37d3996d8d84b4c31eec6f3c163e"
],
- "id": 402
+ "id": 402,
+ "legacy": true
},
"cb6e91711ad6d55c8906f379cb071fb5c47933654a7415612eee6629f26fbcd7": {
"fingerprints": [
"f09b122c7114f4a09bd4ea4f4a99d558b46e4c25cd81140d29c05613914c3841"
],
- "id": 41
+ "id": 41,
+ "legacy": true
+ },
+ "cbad7b1d384849df0946b7ee8e7f5f7ce3aed876fda7bc9d30d8b16f29ff2c53": {
+ "fingerprints": [
+ "657cfe2fa73faa38462571f332a2363a46fce7020951710702cdfbb6eeda3305"
+ ],
+ "id": 492,
+ "legacy": true
},
"cbe5ac15d88b5cac3f81e6df3bfb57bea60958813a47b77f3c5cb6b98191bdb5": {
"fingerprints": [
"ecc3e9c3407503bee091aa952f41348ff88baa863b2264befac807901574e939"
],
- "id": 8
+ "id": 8,
+ "legacy": true
},
"cc4997863c8c48a4cb5c3e6537dc06028d8638be49f5f8a2ba56f2f2c8a8c779": {
"fingerprints": [
"a1f05ccb80c2d710ec7d479abdcbb879e58d7edb7149fe78a87884e3d0bad0f9"
],
- "id": 267
+ "id": 267,
+ "legacy": true
},
"ce24eb0626defd8168c96a7701f09301600fe5dd0dbce58e9c97b830af02ef28": {
"fingerprints": [
@@ -24407,7 +25839,8 @@
"fingerprints": [
"507941c74460a0b47086220d4e9932572ab5d1b5bbcb8980ab1cb17651a844d2"
],
- "id": 148
+ "id": 148,
+ "legacy": true
},
"d0773adb60043e954309d9714fe053eaad8aa5b9586edba468e276df82065adf": {
"fingerprints": [
@@ -24431,7 +25864,8 @@
"fingerprints": [
"f1b13f5c9a326403b0f31bbe7699cd17c7d1c0b981586dd1a7b219c52508fe99"
],
- "id": 367
+ "id": 367,
+ "legacy": true
},
"d2a5f32f0e01b910ef4e3b46bf84e5af5fb5689e7d1507e929e368ac88c6cc76": {
"fingerprints": [
@@ -24443,74 +25877,93 @@
"fingerprints": [
"9d190b2e314566685be8a889e27aa8c7d7ae1d8aaddba3c1ecf9d24863cd34b9"
],
- "id": 255
+ "id": 255,
+ "legacy": true
},
"d3980aadd21638c70d74a4bb1f8ab5e11724e62ed408f9fa8d3d4d916900286b": {
"fingerprints": [
"24a55c2ab051442d0617766541239a4ad032d7c55175aa34ffde2fbc4f5c5294"
],
- "id": 472
+ "id": 472,
+ "legacy": true
+ },
+ "d49c6f289cd056519492480f192f00a6fc7c1862dab2e7b5d8e05f6678fae141": {
+ "fingerprints": [
+ "a1a86d04121eb87f027c66f53303c28e5739f943fc84b38ad6af009035dd9457"
+ ],
+ "id": 491,
+ "legacy": true
},
"d4af6c0a482310bd7c54bb7ab121916f86c0c07cd52fcac32d3844c26005115f": {
"fingerprints": [
"614fd18da1490560cdad1196e2492ab7062eab1a67b3a30f1d0585a7d6ba6824"
],
- "id": 326
+ "id": 326,
+ "legacy": true
},
"d5597ea3453a6261f5d42eb9caf5bdb4e38a1edebdb5bea6d7c0bc1a8abecab2": {
"fingerprints": [
"0e88eb6ea256e19ef8d3abd61a24d38dbad632816dd957294427e4724d81a386"
],
- "id": 405
+ "id": 405,
+ "legacy": true
},
"d646f3ea2d7003fcaa77ad219136c78e024a6f2e2307dfb8cfa97a171373ecdf": {
"fingerprints": [
"74cb3a4ea791afb0a2d1a0b13301b3bee0e50ad5c79a1a6f2c663e6f4ee7a484"
],
- "id": 374
+ "id": 374,
+ "legacy": true
},
"d6a18443d348db994f934ccd8e635d833a27ac1e56f8afaf7c97cb4f43eab68b": {
"fingerprints": [
"4b22d5a6aec99f3cdb79aa5ec06838479cd5ecba7164f7f22dc1d65f63d85708"
],
- "id": 172
+ "id": 172,
+ "legacy": true
},
"d8fb33e385c9c2da729a84706ba927dcbb79273e122ffd9673363b70b7f36cbb": {
"fingerprints": [
"8c4edfd04348f322969e7e29a4cd4dca004655061c16e1b076422ef342ad630e"
],
- "id": 153
+ "id": 153,
+ "legacy": true
},
"d92405c46d912a563e43287f56cd410a1cdf6367c57c9ea7c5cae039dcbcce50": {
"fingerprints": [
"8da75f1327217c88060fd2529eff2816e50b0c74541ea4ea3dfcee66a71efe09"
],
- "id": 365
+ "id": 365,
+ "legacy": true
},
"d9c473cee25f94d1bc6062bd62911477276f064b827a944e064f85d0912d2c5e": {
"fingerprints": [
"248302a977f40f7dd6a2b770586adfaac3eb1e85fd1a102dbd7863c72b8f8ef2"
],
- "id": 253
+ "id": 253,
+ "legacy": true
},
"da800b80b2a87d399e66fa19d72fdf49983b47d8cf322c7c79503a0c7e28feaf": {
"fingerprints": [
"3a43e220fe7f3ea9653d1e21742eac2b75c20fd8980305bc502caf8c2d9b41a1"
],
- "id": 230
+ "id": 230,
+ "legacy": true
},
"da8796be34cc81abee7304c4d2bca0ac984c5b24b61b13e2285e1d27ad8cebf0": {
"fingerprints": [
"7b1f8d8eff5d7349fedb7eae89c29aacc41704f1503ae3c8c2eba10225d0f568",
"ae2fec829118a2455ad6a415e71823eb9b7b6e3578a51ac8a51446eadbb0979c"
],
- "id": 218
+ "id": 218,
+ "legacy": true
},
"db15c0062b520f318a19dacfecd64f9e7a3fbe609fd586796f20ae028e8e3058": {
"fingerprints": [
"d6f034bd94aa233f0297eca4245b283973e447aa590f310c77f48fdf83112254"
],
- "id": 168
+ "id": 168,
+ "legacy": true
},
"dbc1e3a15238a0483bcdb8fdec616e03e705a48e2a501157cadf3b9c7311c5e5": {
"fingerprints": [
@@ -24522,7 +25975,8 @@
"fingerprints": [
"7d2bf3489ebc9ad3448b8b0827715a3cbfe3d523e3b56a9b5fc1d2a2da2f20fe"
],
- "id": 399
+ "id": 399,
+ "legacy": true
},
"dd5ed1c090f9f448061baa94a6bb11017544e9eefaa20cc714ce6c633f5dc629": {
"fingerprints": [
@@ -24534,56 +25988,65 @@
"fingerprints": [
"41d4f6dcf130b9843a3b9a9530953e925fdd84e8b7aeb8f205b8fae39352617d"
],
- "id": 236
+ "id": 236,
+ "legacy": true
},
"df530bac9fcd914c252c2fbdceddc6183d4ae8c680ad65f03e204861dd7b1c73": {
"fingerprints": [
"885de64c340e3ea70658f01e1145f957fcda27aabeea1ab9faa9fdb0102d4077"
],
- "id": 313
+ "id": 313,
+ "legacy": true
},
"e0ef882da48ab0b7efb0d9ba15b2717dd08f043c25ac09b56b8b57fceeb5a35d": {
"fingerprints": [
"e6e4a951ecbf7d8edc01bc873f7b6fd35868bdb10ed786f3a1b1ee16d8cec3e9"
],
- "id": 369
+ "id": 369,
+ "legacy": true
},
"e156445fa20c32ad00937b27d096b8963bcc863950333a877e68fa69707a03af": {
"fingerprints": [
"54b4fc43d44aa4ca9fc03ca7e9949fbae267a064d02da21852412a381b5d1537"
],
- "id": 445
+ "id": 445,
+ "legacy": true
},
"e26613a578e158c2a44e4fec41e6f37a0a991fe1a5fe736c303f4420a90fb50a": {
"fingerprints": [
"f1f3cc207a6d47947b8cb9c30422229de0d71fb867e0b9a3eda08e0e1736bc28"
],
- "id": 331
+ "id": 331,
+ "legacy": true
},
"e2d891efb738669105d530de5ed72e2b2ac3f4a67078b5349b3fdaca496f5eb8": {
"fingerprints": [
"3f06e55681d496f5be169eb5389f9f2b8ff61e1708df6881724849cd5d27cb69"
],
- "id": 9
+ "id": 9,
+ "legacy": true
},
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855": {
"fingerprints": [
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
],
- "id": 488
+ "id": 488,
+ "legacy": true
},
"e42f24bd4d37f4aa2e56b979d83d1e65219fe0e9e3a382a1b3cb66c93955de75": {
"fingerprints": [
"c766a9bef2d4071c863a31aa4920e813b2d198608cb7b7cfe21143b836df09ea",
"e17890ee09a3fbf4f48b9c414a17d637b7a50647e9bc752322727fcc1742a911"
],
- "id": 29
+ "id": 29,
+ "legacy": true
},
"e43dea894f42cecf4a1dd60ed1dab82f7c0a308ae32a3d49a7aa1a3e957015f7": {
"fingerprints": [
"2dc70e588d340de5966ae32f6fc796bdb5de6d7c25cd249a4be64e9df9036323"
],
- "id": 212
+ "id": 212,
+ "legacy": true
},
"e5ca37bc7b6c361979bc6b123ca9a1db019046d7ff5f57dfb854b19d10b0682f": {
"fingerprints": [
@@ -24601,13 +26064,15 @@
"fingerprints": [
"a798a1c70e9b6d50eaa5724a26fac7991848edc61bf48d79816bcafb66972128"
],
- "id": 345
+ "id": 345,
+ "legacy": true
},
"ea2f9e087eaebbdfc0569eca18364e5236254624854f92e37871b5ee36744883": {
"fingerprints": [
"4e7480ad702a379dc589adb4faa625e6a5993f87ef2375d5437ffe3b79be4e96"
],
- "id": 297
+ "id": 297,
+ "legacy": true
},
"ea87f462deefffbd7775aa2a4b7e0fcb91c22eee6df69ed90100ccc73b311476": {
"fingerprints": [
@@ -24621,7 +26086,8 @@
"b0b1730ecbc7ff4505142c49f1295e6eda6bcaed7e2c68c5be91b5a11001f024",
"0d83b611b648a1a75eb8558400795375cad92e264ed8e9d7a757c1f5ee2bb22d"
],
- "id": 215
+ "id": 215,
+ "legacy": true
},
"ec9056fe9509411609763aee831ef37c832b75b3d727528fc7c75201c1ff28e6": {
"fingerprints": [
@@ -24639,32 +26105,37 @@
"fingerprints": [
"781d64dfa77b00f2c006700b1fda86bf68b865a603c7a656f92e90c042ca2873"
],
- "id": 377
+ "id": 377,
+ "legacy": true
},
"ede4b1535a529bf1606bc6ff757b91470aa30aeaffd2d6df2eba340dae302fca": {
"fingerprints": [
"e8a2f441657678975f2b97d775719c7d49d92234554540ec14d92e16fe27d2cb",
"3deae6ae975284e0e6fa2eb76ce46e12441869a2a7d4e67dc7ab8664fefdbbb0"
],
- "id": 219
+ "id": 219,
+ "legacy": true
},
"ef4fa1c630f04950e0e2d10dc19f149d08ab46dec95da3131cbaea8af8ea3027": {
"fingerprints": [
"42143a511a3afcdd80d555debb4191ec6bb285ee66e62ec657ed20adf7d55faa"
],
- "id": 393
+ "id": 393,
+ "legacy": true
},
"ef53ffaf0ceb040d077f5bd80a9deef6d4507fdb6f9bcf8c3594bece7ebdb025": {
"fingerprints": [
"36544d2fce03c6c72b70eb1a8064264dc1511768c2d8f76a8b9f1f2bbd153b7d"
],
- "id": 361
+ "id": 361,
+ "legacy": true
},
"effee1f1e5f39f42ff80d471c9c5a799a8c843f9b676315f9eab3f4c7a2f7fc8": {
"fingerprints": [
"4898c6888c0cffb0d3e31aca8a37d4e3515ff746d02635d86646cfa0a3185ae7"
],
- "id": 129
+ "id": 129,
+ "legacy": true
},
"f1c6ba670cfc88e4df52973cae420f0a089dd474144fe5806c420064e1591229": {
"fingerprints": [
@@ -24676,7 +26147,8 @@
"fingerprints": [
"ddbf149733bc2bf8a09d7f012b01a6dea11d7bae26713783ef6407a2495bf189"
],
- "id": 474
+ "id": 474,
+ "legacy": true
},
"f3438e23b3ce532522facf307923f58fd18608e9ba7addc30e952b43c49616c3": {
"fingerprints": [
@@ -24688,13 +26160,15 @@
"fingerprints": [
"97f654859cbde586fd90311e82ec7902c238cba0d6e529564c9c88f44895ec50"
],
- "id": 467
+ "id": 467,
+ "legacy": true
},
"f463c54d9f1a047aed52656ac785e07ebec528e0207bfd3f55d893237668f6ae": {
"fingerprints": [
"d95fea3ca4eedce74cd76e75fc6d1ff62c441f0fa8bc77f034b19e5db258015d"
],
- "id": 96
+ "id": 96,
+ "legacy": true
},
"f48badd7df6a06690d0ae31373b12855f8dedb14517f362a313101cc98cc6b35": {
"fingerprints": [
@@ -24707,43 +26181,50 @@
"3f9f27d583204b9e09c8a3d2066c4b57d3a2479c3693650880505698105dbce9",
"ab7036365c7154aa29c2c29f5d4191163b162a2225011357d56d07ffa7bc1f72"
],
- "id": 118
+ "id": 118,
+ "legacy": true
},
"f5857d8862bc2ba3c9ddca3f84146dc8d81f4d579d2b387bf60065381ee641dd": {
"fingerprints": [
"ccc89489371bad111c90619bea240a2e6dadd99f9f6e1d4d41e58ed6de3d0285"
],
- "id": 335
+ "id": 335,
+ "legacy": true
},
"f5e19c8e14fe755f551cec2b7113e7c98023b176ebe6c1abcf872b2a7b932304": {
"fingerprints": [
"5607e260163f49c8ea4175a1c0a53b13195cb7d07845611e943a2ff507036834"
],
- "id": 363
+ "id": 363,
+ "legacy": true
},
"f6146bc238e8fce0d47b7074c9a26b1aa0f883528510f06d9cfec41ff6ca1968": {
"fingerprints": [
"e606ddeee2ee7f5cdef5d9058ff8b7d0a9f042877f6a171ed8ff6960e4cc5ea5"
],
- "id": 247
+ "id": 247,
+ "legacy": true
},
"f6b59c8e2789a1fd5d5b253742feadc6925cb93edc345e53166e12c52ba2a601": {
"fingerprints": [
"8f9e2751dcd574e9ba90e744ea92581fd0af640ae86ac1ce2198c90f96b44823"
],
- "id": 327
+ "id": 327,
+ "legacy": true
},
"f73be5eba536912c557fb855517ad1ee0487bd8f63498c3949164177ba06c5de": {
"fingerprints": [
"77a03f69e4f3955589acaca06f6773a0d98d16dea05c6d94ee3ef6fb2beb7605"
],
- "id": 380
+ "id": 380,
+ "legacy": true
},
"f7aff41b2709f175f8aba17e567b27046b2dd54bf6e7e263d3295873437b9cff": {
"fingerprints": [
"6baf50ae3467eff3c35fefdc76a02a97fab6267723eda91e99f1b3dc2b28f82e"
],
- "id": 387
+ "id": 387,
+ "legacy": true
},
"f7ecded5c66047d28ed6466b543c40e0743abe81d109254dcf845d4c2c7853c5": {
"fingerprints": [
@@ -24755,20 +26236,23 @@
"fingerprints": [
"9f9744463be13714754e1a3becf98c08cc205e4ab32028f4e2830c4a1b2775b8"
],
- "id": 222
+ "id": 222,
+ "legacy": true
},
"fac95de3c24a174194800cffaa3ca51d7116630664a9b60c8758b4ef0dc58f88": {
"fingerprints": [
"793cbf4559b9fde38ab22df16869f69881ae14c4b0139ac788a78a1afcca02fb",
"8688e58f4c7a945fadce7f62bfef521b82da7dc38bfdb0163478a5fe42e57870"
],
- "id": 119
+ "id": 119,
+ "legacy": true
},
"faddde04bcf08ca8f4e22efd2afeade6bf3d850ae47be96a82d539494f120cbd": {
"fingerprints": [
"8f633df0191a417dcd4f6331f0e90eb947158c8a3ea59bfe81420041315eac6c"
],
- "id": 350
+ "id": 350,
+ "legacy": true
},
"fbe3018031f9586bcbf41727e417b7d1c45c2f47f93be372a17b96b50757d5a2": {
"fingerprints": [
@@ -24780,25 +26264,29 @@
"fingerprints": [
"39c75caecee8920c909f132491641350b57e2702a65a991545b01d1be4a2220b"
],
- "id": 158
+ "id": 158,
+ "legacy": true
},
"fcf7da983603e88862030d96137d8e13031badfb4d56c1fd4cacc339f6bdbb2a": {
"fingerprints": [
"7d3b465a6014e526c0affcee2127d2311727ad811c26842d006af37306cc80bd"
],
- "id": 28
+ "id": 28,
+ "legacy": true
},
"fd371bea9755ff60c8828c849b8e5215de532d61b009855fa0ad630d90eef82e": {
"fingerprints": [
"8560f91c3624daba9570b5fea0dbe36ff11a8323be9486854fb3f34a5571198d"
],
- "id": 490
+ "id": 490,
+ "legacy": true
},
"fd872d176617e50c266119d0fdb047b0732da2048b121af7b9860ca3e2f2f2be": {
"fingerprints": [
"a6c51e0da5ca0a9309d2e4c0e40c2af9107aae8203857fe198e3e769e343085c"
],
- "id": 123
+ "id": 123,
+ "legacy": true
},
"fea2b7d645fba73d753c1ec9a7870c40e1f7b0c561e927b985bf711866e36f22": {
"fingerprints": [
@@ -24816,7 +26304,8 @@
"fingerprints": [
"08297a4047dba23680c731db6e317653ca7848e1bebd3a0b0179a707f92cf178"
],
- "id": 54
+ "id": 54,
+ "legacy": true
}
}
} \ No newline at end of file
diff --git a/chromium/net/data/ssl/root_stores/update_root_stores.py b/chromium/net/data/ssl/root_stores/update_root_stores.py
index 82e007bf818..8aca424fc36 100755
--- a/chromium/net/data/ssl/root_stores/update_root_stores.py
+++ b/chromium/net/data/ssl/root_stores/update_root_stores.py
@@ -48,9 +48,12 @@ const struct RootCertData {
// The SHA-256 hash of the associated certificate's subjectPublicKeyInfo.
unsigned char sha256_spki_hash[32];
- // A value suitable for histograms using the NetTrustAnchors enum. The value
- // 0 is reserved (not used), for use as a sentinel value.
- int16_t histogram_id;
+ // A value suitable for histograms using the NetTrustAnchors enum.
+ int16_t histogram_id : 15;
+
+ // If true, indicates the CA is considered a "Legacy" CA, formerly trusted
+ // or not yet trusted.
+ bool legacy_ca : 1;
} kRootCerts[] = {
"""
@@ -88,8 +91,10 @@ def main():
header_file.write(LICENSE_AND_HEADER)
for spki, data in sorted(root_stores['spkis'].items()):
cpp_str = ''.join('0x{:02X}, '.format(x) for x in bytearray.fromhex(spki))
- log_id = data['id']
- header_file.write('{ { %s },\n%d }, ' % (cpp_str, log_id))
+ log_id = int(data['id'])
+ legacy = 'legacy' in data and data['legacy']
+ header_file.write('{ { %s },\n%d, %s }, ' %
+ (cpp_str, log_id, "true" if legacy else "false"))
header_file.write(FOOTER)
diff --git a/chromium/net/data/ssl/scripts/generate-test-certs.sh b/chromium/net/data/ssl/scripts/generate-test-certs.sh
index 0eee7f514de..a4e309f2c92 100755
--- a/chromium/net/data/ssl/scripts/generate-test-certs.sh
+++ b/chromium/net/data/ssl/scripts/generate-test-certs.sh
@@ -334,6 +334,19 @@ CA_NAME="req_ca_dn" \
-in out/61_months_after_2012_07.req \
-out ../certificates/61_months_after_2012_07.pem \
-config ca.cnf
+# 39 months, based on a CA calculating one month as 'last day of Month 0' to
+# last day of 'Month 1'.
+openssl req -config ../scripts/ee.cnf \
+ -newkey rsa:2048 -text -out out/39_months_based_on_last_day.req
+CA_NAME="req_ca_dn" \
+ openssl ca \
+ -batch \
+ -extensions user_cert \
+ -startdate 170228000000Z \
+ -enddate 200530000000Z \
+ -in out/39_months_based_on_last_day.req \
+ -out ../certificates/39_months_based_on_last_day.pem \
+ -config ca.cnf
# start date after expiry date
openssl req -config ../scripts/ee.cnf \
-newkey rsa:2048 -text -out out/start_after_expiry.req
diff --git a/chromium/net/data/ssl/scripts/quic-test.cnf.txt b/chromium/net/data/ssl/scripts/quic-test.cnf
index c8daaf30d0a..c8daaf30d0a 100644
--- a/chromium/net/data/ssl/scripts/quic-test.cnf.txt
+++ b/chromium/net/data/ssl/scripts/quic-test.cnf
diff --git a/chromium/net/data/websocket/OWNERS b/chromium/net/data/websocket/OWNERS
index 4546121a80f..d5f50691953 100644
--- a/chromium/net/data/websocket/OWNERS
+++ b/chromium/net/data/websocket/OWNERS
@@ -1,5 +1,4 @@
ricea@chromium.org
-tyoshino@chromium.org
yhirano@chromium.org
# TEAM: blink-network-dev@chromium.org
diff --git a/chromium/net/disk_cache/blockfile/entry_impl.cc b/chromium/net/disk_cache/blockfile/entry_impl.cc
index 16e49b9787e..489b2ccc8e9 100644
--- a/chromium/net/disk_cache/blockfile/entry_impl.cc
+++ b/chromium/net/disk_cache/blockfile/entry_impl.cc
@@ -925,6 +925,10 @@ int EntryImpl::ReadyForSparseIO(const CompletionCallback& callback) {
return net::ERR_IO_PENDING;
}
+void EntryImpl::SetLastUsedTimeForTest(base::Time time) {
+ SetTimes(time, time);
+}
+
// When an entry is deleted from the cache, we clean up all the data associated
// with it for two reasons: to simplify the reuse of the block (we know that any
// unused block is filled with zeros), and to simplify the handling of write /
diff --git a/chromium/net/disk_cache/blockfile/entry_impl.h b/chromium/net/disk_cache/blockfile/entry_impl.h
index f3f63cf5d76..a7c8d7cc1b8 100644
--- a/chromium/net/disk_cache/blockfile/entry_impl.h
+++ b/chromium/net/disk_cache/blockfile/entry_impl.h
@@ -193,6 +193,7 @@ class NET_EXPORT_PRIVATE EntryImpl
bool CouldBeSparse() const override;
void CancelSparseIO() override;
int ReadyForSparseIO(const CompletionCallback& callback) override;
+ void SetLastUsedTimeForTest(base::Time time) override;
private:
enum {
diff --git a/chromium/net/disk_cache/blockfile/file_win.cc b/chromium/net/disk_cache/blockfile/file_win.cc
index e2ea893a219..036d2ce6d7a 100644
--- a/chromium/net/disk_cache/blockfile/file_win.cc
+++ b/chromium/net/disk_cache/blockfile/file_win.cc
@@ -10,6 +10,7 @@
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_pump_for_io.h"
#include "net/base/net_errors.h"
#include "net/disk_cache/disk_cache.h"
@@ -25,7 +26,7 @@ struct MyOverlapped {
return &context_.overlapped;
}
- base::MessageLoopForIO::IOContext context_;
+ base::MessagePumpForIO::IOContext context_;
scoped_refptr<disk_cache::File> file_;
scoped_refptr<CompletionHandler> completion_handler_;
disk_cache::FileIOCallback* callback_;
@@ -35,7 +36,7 @@ static_assert(offsetof(MyOverlapped, context_) == 0,
"should start with overlapped");
// Helper class to handle the IO completion notifications from the message loop.
-class CompletionHandler : public base::MessageLoopForIO::IOHandler,
+class CompletionHandler : public base::MessagePumpForIO::IOHandler,
public base::RefCounted<CompletionHandler> {
public:
CompletionHandler() = default;
@@ -45,8 +46,8 @@ class CompletionHandler : public base::MessageLoopForIO::IOHandler,
friend class base::RefCounted<CompletionHandler>;
~CompletionHandler() override {}
- // implement base::MessageLoopForIO::IOHandler.
- void OnIOCompleted(base::MessageLoopForIO::IOContext* context,
+ // implement base::MessagePumpForIO::IOHandler.
+ void OnIOCompleted(base::MessagePumpForIO::IOContext* context,
DWORD actual_bytes,
DWORD error) override;
@@ -74,7 +75,7 @@ CompletionHandler* CompletionHandler::Get() {
}
void CompletionHandler::OnIOCompleted(
- base::MessageLoopForIO::IOContext* context,
+ base::MessagePumpForIO::IOContext* context,
DWORD actual_bytes,
DWORD error) {
MyOverlapped* data = reinterpret_cast<MyOverlapped*>(context);
@@ -276,7 +277,7 @@ void File::WaitForPendingIO(int* num_pending_io) {
while (*num_pending_io) {
// Asynchronous IO operations may be in flight and the completion may end
// up calling us back so let's wait for them.
- base::MessageLoopForIO::IOHandler* handler = CompletionHandler::Get();
+ base::MessagePumpForIO::IOHandler* handler = CompletionHandler::Get();
base::MessageLoopForIO::current()->WaitForIOCompletion(100, handler);
}
}
diff --git a/chromium/net/disk_cache/blockfile/mapped_file.h b/chromium/net/disk_cache/blockfile/mapped_file.h
index 21dd0c7c9ea..3e36c79825a 100644
--- a/chromium/net/disk_cache/blockfile/mapped_file.h
+++ b/chromium/net/disk_cache/blockfile/mapped_file.h
@@ -13,7 +13,7 @@
#include "net/base/net_export.h"
#include "net/disk_cache/blockfile/file.h"
#include "net/disk_cache/blockfile/file_block.h"
-#include "net/net_features.h"
+#include "net/net_buildflags.h"
namespace base {
class FilePath;
diff --git a/chromium/net/disk_cache/disk_cache.h b/chromium/net/disk_cache/disk_cache.h
index 756a04a3286..c8461f578e9 100644
--- a/chromium/net/disk_cache/disk_cache.h
+++ b/chromium/net/disk_cache/disk_cache.h
@@ -122,7 +122,11 @@ class NET_EXPORT Backend {
// operations so the callbacks are not invoked, possibly leaving the work
// half way (for instance, dooming just a few entries). Note that pending IO
// for a given Entry (as opposed to the Backend) will still generate a
- // callback from within this method.
+ // callback.
+ // Warning: there is some inconsistency in details between different backends
+ // on what will succeed and what will fail. In particular the blockfile
+ // backend will leak entries closed after backend deletion, while others
+ // handle it properly.
virtual ~Backend() {}
// Returns the type of this cache.
@@ -382,6 +386,11 @@ class NET_EXPORT Entry {
// Note: This method is deprecated.
virtual int ReadyForSparseIO(const CompletionCallback& callback) = 0;
+ // Used in tests to set the last used time. Note that backend might have
+ // limited precision. Also note that this call may modify the last modified
+ // time.
+ virtual void SetLastUsedTimeForTest(base::Time time) = 0;
+
protected:
virtual ~Entry() {}
};
diff --git a/chromium/net/disk_cache/entry_unittest.cc b/chromium/net/disk_cache/entry_unittest.cc
index 374a9816ff7..1bcc96fd57c 100644
--- a/chromium/net/disk_cache/entry_unittest.cc
+++ b/chromium/net/disk_cache/entry_unittest.cc
@@ -4883,15 +4883,6 @@ TEST_F(DiskCacheEntryTest, SimpleCacheChecksumpScrewUp) {
entry->Close();
}
-// TODO(morlovich): There seems to be an imperfection of leak detection, see
-// https://crbug.com/811276. Please reenable this test when the bug is fixed.
-TEST_F(DiskCacheEntryTest, DISABLED_UseAfterBackendDestruction) {
- // InitCache uses the kNoRandom flag that check-fails on the tested scenario.
- CreateBackend(0);
- DisableIntegrityCheck();
- UseAfterBackendDestruction();
-}
-
TEST_F(DiskCacheEntryTest, SimpleUseAfterBackendDestruction) {
SetSimpleCacheMode();
InitCache();
diff --git a/chromium/net/disk_cache/memory/mem_entry_impl.cc b/chromium/net/disk_cache/memory/mem_entry_impl.cc
index 177416883d2..4026bd10a52 100644
--- a/chromium/net/disk_cache/memory/mem_entry_impl.cc
+++ b/chromium/net/disk_cache/memory/mem_entry_impl.cc
@@ -272,6 +272,10 @@ int MemEntryImpl::ReadyForSparseIO(const CompletionCallback& callback) {
return net::OK;
}
+void MemEntryImpl::SetLastUsedTimeForTest(base::Time time) {
+ last_used_ = time;
+}
+
size_t MemEntryImpl::EstimateMemoryUsage() const {
// Subtlety: the entries in children_ are not double counted, as the entry
// pointers won't be followed by EstimateMemoryUsage.
diff --git a/chromium/net/disk_cache/memory/mem_entry_impl.h b/chromium/net/disk_cache/memory/mem_entry_impl.h
index 728bec0e2e4..d500ea9e37d 100644
--- a/chromium/net/disk_cache/memory/mem_entry_impl.h
+++ b/chromium/net/disk_cache/memory/mem_entry_impl.h
@@ -133,6 +133,7 @@ class NET_EXPORT_PRIVATE MemEntryImpl final
bool CouldBeSparse() const override;
void CancelSparseIO() override {}
int ReadyForSparseIO(const CompletionCallback& callback) override;
+ void SetLastUsedTimeForTest(base::Time time) override;
size_t EstimateMemoryUsage() const;
private:
diff --git a/chromium/net/disk_cache/simple/simple_entry_impl.cc b/chromium/net/disk_cache/simple/simple_entry_impl.cc
index 147350d3714..594e50f6180 100644
--- a/chromium/net/disk_cache/simple/simple_entry_impl.cc
+++ b/chromium/net/disk_cache/simple/simple_entry_impl.cc
@@ -599,6 +599,13 @@ int SimpleEntryImpl::ReadyForSparseIO(const CompletionCallback& callback) {
return net::OK;
}
+void SimpleEntryImpl::SetLastUsedTimeForTest(base::Time time) {
+ // Note that we do not update |last_used_| here as it gets overwritten
+ // by UpdateDataFromEntryStat with the current time. It would be more involved
+ // to make that value stick and is not needed by the current tests.
+ backend_->index()->SetLastUsedTimeForTest(entry_hash_, time);
+}
+
size_t SimpleEntryImpl::EstimateMemoryUsage() const {
// TODO(xunjieli): crbug.com/669108. It'd be nice to have the rest of |entry|
// measured, but the ownership of SimpleSynchronousEntry isn't straightforward
diff --git a/chromium/net/disk_cache/simple/simple_entry_impl.h b/chromium/net/disk_cache/simple/simple_entry_impl.h
index 1f56b92c4df..6cae881d3cf 100644
--- a/chromium/net/disk_cache/simple/simple_entry_impl.h
+++ b/chromium/net/disk_cache/simple/simple_entry_impl.h
@@ -132,6 +132,7 @@ class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
bool CouldBeSparse() const override;
void CancelSparseIO() override;
int ReadyForSparseIO(const CompletionCallback& callback) override;
+ void SetLastUsedTimeForTest(base::Time time) override;
// Returns the estimate of dynamically allocated memory in bytes.
size_t EstimateMemoryUsage() const;
diff --git a/chromium/net/disk_cache/simple/simple_index.cc b/chromium/net/disk_cache/simple/simple_index.cc
index 30cf9efc833..a891458d32c 100644
--- a/chromium/net/disk_cache/simple/simple_index.cc
+++ b/chromium/net/disk_cache/simple/simple_index.cc
@@ -278,6 +278,13 @@ size_t SimpleIndex::EstimateMemoryUsage() const {
base::trace_event::EstimateMemoryUsage(removed_entries_);
}
+void SimpleIndex::SetLastUsedTimeForTest(uint64_t entry_hash,
+ const base::Time last_used) {
+ EntrySet::iterator it = entries_set_.find(entry_hash);
+ DCHECK(it != entries_set_.end());
+ it->second.SetLastUsedTime(last_used);
+}
+
void SimpleIndex::Insert(uint64_t entry_hash) {
DCHECK(io_thread_checker_.CalledOnValidThread());
// Upon insert we don't know yet the size of the entry.
diff --git a/chromium/net/disk_cache/simple/simple_index.h b/chromium/net/disk_cache/simple/simple_index.h
index 426241e2777..0da8cd91888 100644
--- a/chromium/net/disk_cache/simple/simple_index.h
+++ b/chromium/net/disk_cache/simple/simple_index.h
@@ -192,6 +192,8 @@ class NET_EXPORT_PRIVATE SimpleIndex
// Returns the estimate of dynamically allocated memory in bytes.
size_t EstimateMemoryUsage() const;
+ void SetLastUsedTimeForTest(uint64_t entry_hash, const base::Time last_used);
+
private:
friend class SimpleIndexTest;
FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, IndexSizeCorrectOnMerge);
diff --git a/chromium/net/dns/OWNERS b/chromium/net/dns/OWNERS
index 4be0e485147..52b51f2ed1f 100644
--- a/chromium/net/dns/OWNERS
+++ b/chromium/net/dns/OWNERS
@@ -1,5 +1,3 @@
-mgersh@chromium.org
-
per-file *_struct_traits*.*=set noparent
per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/chromium/net/dns/address_sorter_posix.cc b/chromium/net/dns/address_sorter_posix.cc
index 051bafeeb61..37af8da106d 100644
--- a/chromium/net/dns/address_sorter_posix.cc
+++ b/chromium/net/dns/address_sorter_posix.cc
@@ -280,7 +280,7 @@ void AddressSorterPosix::Sort(const AddressList& list,
// Each socket can only be bound once.
std::unique_ptr<DatagramClientSocket> socket(
socket_factory_->CreateDatagramClientSocket(
- DatagramSocket::DEFAULT_BIND, RandIntCallback(), NULL /* NetLog */,
+ DatagramSocket::DEFAULT_BIND, nullptr /* NetLog */,
NetLogSource()));
// Even though no packets are sent, cannot use port 0 in Connect.
diff --git a/chromium/net/dns/address_sorter_posix_unittest.cc b/chromium/net/dns/address_sorter_posix_unittest.cc
index 204fc87e64c..c91fcf44b72 100644
--- a/chromium/net/dns/address_sorter_posix_unittest.cc
+++ b/chromium/net/dns/address_sorter_posix_unittest.cc
@@ -66,6 +66,33 @@ class TestUDPClientSocket : public DatagramClientSocket {
return OK;
}
void UseNonBlockingIO() override {}
+ int WriteAsync(
+ const char* buffer,
+ size_t buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override {
+ NOTIMPLEMENTED();
+ return OK;
+ }
+ int WriteAsync(
+ DatagramBuffers buffers,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override {
+ NOTIMPLEMENTED();
+ return OK;
+ }
+ DatagramBuffers GetUnwrittenBuffers() override {
+ DatagramBuffers result;
+ NOTIMPLEMENTED();
+ return result;
+ }
+ void SetWriteAsyncEnabled(bool enabled) override {}
+ void SetMaxPacketSize(size_t max_packet_size) override {}
+ bool WriteAsyncEnabled() override { return false; }
+ void SetWriteMultiCoreEnabled(bool enabled) override {}
+ void SetSendmmsgEnabled(bool enabled) override {}
+ void SetWriteBatchingActive(bool active) override {}
+
int ConnectUsingNetwork(NetworkChangeNotifier::NetworkHandle network,
const IPEndPoint& address) override {
NOTIMPLEMENTED();
@@ -79,6 +106,7 @@ class TestUDPClientSocket : public DatagramClientSocket {
return NetworkChangeNotifier::kInvalidNetworkHandle;
}
void ApplySocketTag(const SocketTag& tag) override {}
+ void SetMsgConfirm(bool confirm) override {}
int Connect(const IPEndPoint& remote) override {
if (connected_)
@@ -110,19 +138,18 @@ class TestSocketFactory : public ClientSocketFactory {
std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
DatagramSocket::BindType,
- const RandIntCallback&,
NetLog*,
const NetLogSource&) override {
return std::unique_ptr<DatagramClientSocket>(
new TestUDPClientSocket(&mapping_));
}
- std::unique_ptr<StreamSocket> CreateTransportClientSocket(
+ std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
const AddressList&,
std::unique_ptr<SocketPerformanceWatcher>,
NetLog*,
const NetLogSource&) override {
NOTIMPLEMENTED();
- return std::unique_ptr<StreamSocket>();
+ return nullptr;
}
std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
std::unique_ptr<ClientSocketHandle>,
diff --git a/chromium/net/dns/dns_client.cc b/chromium/net/dns/dns_client.cc
index c1c9e419d48..6158b0a07ac 100644
--- a/chromium/net/dns/dns_client.cc
+++ b/chromium/net/dns/dns_client.cc
@@ -15,10 +15,6 @@
#include "net/dns/dns_transaction.h"
#include "net/socket/client_socket_factory.h"
-namespace base {
-class Value;
-}
-
namespace net {
namespace {
@@ -58,18 +54,6 @@ class DnsClientImpl : public DnsClient {
AddressSorter* GetAddressSorter() override { return address_sorter_.get(); }
- std::unique_ptr<const base::Value> GetPersistentData() const override {
- if (!session_)
- return std::unique_ptr<const base::Value>();
- return session_->GetPersistentData();
- }
-
- void ApplyPersistentData(const base::Value& data) override {
- if (!session_)
- return;
- session_->ApplyPersistentData(data);
- }
-
private:
scoped_refptr<DnsSession> session_;
std::unique_ptr<DnsTransactionFactory> factory_;
diff --git a/chromium/net/dns/dns_client.h b/chromium/net/dns/dns_client.h
index 7809a9103d6..57f823ee2d7 100644
--- a/chromium/net/dns/dns_client.h
+++ b/chromium/net/dns/dns_client.h
@@ -7,7 +7,6 @@
#include <memory>
-#include "base/values.h"
#include "net/base/net_export.h"
#include "net/base/rand_callback.h"
@@ -39,13 +38,6 @@ class NET_EXPORT DnsClient {
// Returns NULL if the current config is not valid.
virtual AddressSorter* GetAddressSorter() = 0;
- // Does nothing if the current config is not valid.
- virtual void ApplyPersistentData(const base::Value& data) = 0;
-
- // Returns std::unique_ptr<const Value>(NULL) if the current config is not
- // valid.
- virtual std::unique_ptr<const base::Value> GetPersistentData() const = 0;
-
// Creates default client.
static std::unique_ptr<DnsClient> CreateClient(NetLog* net_log);
diff --git a/chromium/net/dns/dns_session.cc b/chromium/net/dns/dns_session.cc
index 3e6efc170fc..85c7b09f622 100644
--- a/chromium/net/dns/dns_session.cc
+++ b/chromium/net/dns/dns_session.cc
@@ -18,7 +18,6 @@
#include "base/rand_util.h"
#include "base/stl_util.h"
#include "base/time/time.h"
-#include "base/values.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/dns/dns_config_service.h"
@@ -330,12 +329,6 @@ std::unique_ptr<StreamSocket> DnsSession::CreateTCPSocket(
return socket_pool_->CreateTCPSocket(server_index, source);
}
-void DnsSession::ApplyPersistentData(const base::Value& data) {}
-
-std::unique_ptr<const base::Value> DnsSession::GetPersistentData() const {
- return std::unique_ptr<const base::Value>();
-}
-
// Release a socket.
void DnsSession::FreeSocket(unsigned server_index,
std::unique_ptr<DatagramClientSocket> socket) {
diff --git a/chromium/net/dns/dns_session.h b/chromium/net/dns/dns_session.h
index 3a09d33887c..803a64d641a 100644
--- a/chromium/net/dns/dns_session.h
+++ b/chromium/net/dns/dns_session.h
@@ -114,9 +114,6 @@ class NET_EXPORT_PRIVATE DnsSession
std::unique_ptr<StreamSocket> CreateTCPSocket(unsigned server_index,
const NetLogSource& source);
- void ApplyPersistentData(const base::Value& data);
- std::unique_ptr<const base::Value> GetPersistentData() const;
-
private:
friend class base::RefCounted<DnsSession>;
~DnsSession() override;
diff --git a/chromium/net/dns/dns_session_unittest.cc b/chromium/net/dns/dns_session_unittest.cc
index a9afe2b0d6a..a70380245a5 100644
--- a/chromium/net/dns/dns_session_unittest.cc
+++ b/chromium/net/dns/dns_session_unittest.cc
@@ -31,17 +31,16 @@ class TestClientSocketFactory : public ClientSocketFactory {
std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
NetLog* net_log,
const NetLogSource& source) override;
- std::unique_ptr<StreamSocket> CreateTransportClientSocket(
+ std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
const AddressList& addresses,
std::unique_ptr<SocketPerformanceWatcher>,
NetLog*,
const NetLogSource&) override {
NOTIMPLEMENTED();
- return std::unique_ptr<StreamSocket>();
+ return nullptr;
}
std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
@@ -181,7 +180,6 @@ bool DnsSessionTest::ExpectEvent(const PoolEvent& expected) {
std::unique_ptr<DatagramClientSocket>
TestClientSocketFactory::CreateDatagramClientSocket(
DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
NetLog* net_log,
const NetLogSource& source) {
// We're not actually expecting to send or receive any data, so use the
diff --git a/chromium/net/dns/dns_socket_pool.cc b/chromium/net/dns/dns_socket_pool.cc
index e77a03acf12..4732a0c19fc 100644
--- a/chromium/net/dns/dns_socket_pool.cc
+++ b/chromium/net/dns/dns_socket_pool.cc
@@ -74,8 +74,8 @@ std::unique_ptr<DatagramClientSocket> DnsSocketPool::CreateConnectedSocket(
std::unique_ptr<DatagramClientSocket> socket;
NetLogSource no_source;
- socket = socket_factory_->CreateDatagramClientSocket(
- kBindType, rand_int_callback_, net_log_, no_source);
+ socket = socket_factory_->CreateDatagramClientSocket(kBindType, net_log_,
+ no_source);
if (socket.get()) {
int rv = socket->Connect((*nameservers_)[server_index]);
diff --git a/chromium/net/dns/dns_test_util.cc b/chromium/net/dns/dns_test_util.cc
index 8418d3bc309..186a7ef3145 100644
--- a/chromium/net/dns/dns_test_util.cc
+++ b/chromium/net/dns/dns_test_util.cc
@@ -232,12 +232,6 @@ AddressSorter* MockDnsClient::GetAddressSorter() {
return address_sorter_.get();
}
-void MockDnsClient::ApplyPersistentData(const base::Value& data) {}
-
-std::unique_ptr<const base::Value> MockDnsClient::GetPersistentData() const {
- return std::unique_ptr<const base::Value>();
-}
-
void MockDnsClient::CompleteDelayedTransactions() {
factory_->CompleteDelayedTransactions();
}
diff --git a/chromium/net/dns/dns_test_util.h b/chromium/net/dns/dns_test_util.h
index 133c33fa978..a991c3332a8 100644
--- a/chromium/net/dns/dns_test_util.h
+++ b/chromium/net/dns/dns_test_util.h
@@ -204,8 +204,6 @@ class MockDnsClient : public DnsClient {
const DnsConfig* GetConfig() const override;
DnsTransactionFactory* GetTransactionFactory() override;
AddressSorter* GetAddressSorter() override;
- void ApplyPersistentData(const base::Value& data) override;
- std::unique_ptr<const base::Value> GetPersistentData() const override;
// Completes all DnsTransactions that were delayed by a rule.
void CompleteDelayedTransactions();
diff --git a/chromium/net/dns/dns_transaction.cc b/chromium/net/dns/dns_transaction.cc
index 8dcd693070c..ce1efa4ed06 100644
--- a/chromium/net/dns/dns_transaction.cc
+++ b/chromium/net/dns/dns_transaction.cc
@@ -34,6 +34,7 @@
#include "net/base/io_buffer.h"
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
+#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/dns/dns_protocol.h"
@@ -414,6 +415,7 @@ class DnsHTTPAttempt : public DnsAttempt, public URLRequest::Delegate {
"is disabled by default"
}
)"));
+ net_log_ = request_->net_log();
if (use_post) {
request_->set_method("POST");
@@ -454,9 +456,7 @@ class DnsHTTPAttempt : public DnsAttempt, public URLRequest::Delegate {
const DnsResponse* resp = response_.get();
return (resp != NULL && resp->IsValid()) ? resp : NULL;
}
- const NetLogWithSource& GetSocketNetLog() const override {
- return request_->net_log();
- }
+ const NetLogWithSource& GetSocketNetLog() const override { return net_log_; }
// URLRequest::Delegate overrides
@@ -574,6 +574,7 @@ class DnsHTTPAttempt : public DnsAttempt, public URLRequest::Delegate {
CompletionCallback callback_;
std::unique_ptr<DnsResponse> response_;
std::unique_ptr<URLRequest> request_;
+ NetLogWithSource net_log_;
base::WeakPtrFactory<DnsHTTPAttempt> weak_factory_;
diff --git a/chromium/net/dns/dns_transaction_unittest.cc b/chromium/net/dns/dns_transaction_unittest.cc
index f61f0ffba7f..3aaf2ad0652 100644
--- a/chromium/net/dns/dns_transaction_unittest.cc
+++ b/chromium/net/dns/dns_transaction_unittest.cc
@@ -21,6 +21,7 @@
#include "base/sys_byteorder.h"
#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
+#include "base/values.h"
#include "net/base/ip_address.h"
#include "net/base/port_util.h"
#include "net/base/upload_bytes_element_reader.h"
@@ -31,6 +32,8 @@
#include "net/dns/dns_session.h"
#include "net/dns/dns_test_util.h"
#include "net/dns/dns_util.h"
+#include "net/log/net_log.h"
+#include "net/log/net_log_capture_mode.h"
#include "net/log/net_log_with_source.h"
#include "net/proxy_resolution/proxy_config_service_fixed.h"
#include "net/socket/socket_test_util.h"
@@ -229,7 +232,6 @@ class TestSocketFactory : public MockClientSocketFactory {
std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
NetLog* net_log,
const NetLogSource& source) override {
if (fail_next_socket_) {
@@ -238,9 +240,7 @@ class TestSocketFactory : public MockClientSocketFactory {
new FailingUDPClientSocket(&empty_data_, net_log));
}
SocketDataProvider* data_provider = mock_data().GetNext();
- std::unique_ptr<TestUDPClientSocket> socket(
- new TestUDPClientSocket(this, data_provider, net_log));
- return std::move(socket);
+ return std::make_unique<TestUDPClientSocket>(this, data_provider, net_log);
}
void OnConnect(const IPEndPoint& endpoint) {
@@ -282,9 +282,10 @@ class TransactionHelper {
void StartTransaction(DnsTransactionFactory* factory) {
EXPECT_EQ(NULL, transaction_.get());
transaction_ = factory->CreateTransaction(
- hostname_, qtype_, base::Bind(&TransactionHelper::OnTransactionComplete,
- base::Unretained(this)),
- NetLogWithSource());
+ hostname_, qtype_,
+ base::Bind(&TransactionHelper::OnTransactionComplete,
+ base::Unretained(this)),
+ NetLogWithSource::Make(&net_log_, net::NetLogSourceType::NONE));
transaction_->SetRequestContext(&request_context_);
transaction_->SetRequestPriority(DEFAULT_PRIORITY);
EXPECT_EQ(hostname_, transaction_->GetHostname());
@@ -366,6 +367,8 @@ class TransactionHelper {
TestURLRequestContext* request_context() { return &request_context_; }
+ NetLog* net_log() { return &net_log_; }
+
private:
std::string hostname_;
uint16_t qtype_;
@@ -375,6 +378,7 @@ class TransactionHelper {
TestURLRequestContext request_context_;
std::unique_ptr<base::RunLoop> transaction_complete_run_loop_;
bool completed_;
+ NetLog net_log_;
};
// Callback that allows a test to modify HttpResponseinfo
@@ -785,8 +789,7 @@ class DnsTransactionTest : public testing::Test {
void TearDown() override {
// Check that all socket data was at least written to.
- if (base::MessageLoop::current() &&
- base::MessageLoop::current()->IsType(base::MessageLoop::TYPE_IO)) {
+ if (base::MessageLoopForIO::IsCurrent()) {
URLRequestFilter* filter = URLRequestFilter::GetInstance();
filter->ClearHandlers();
}
@@ -1818,6 +1821,46 @@ TEST_F(DnsTransactionTest, HttpsCantLookupDohServers) {
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
}
+class CountingObserver : public net::NetLog::ThreadSafeObserver {
+ public:
+ CountingObserver() : count_(0), dict_count_(0) {}
+
+ ~CountingObserver() override {
+ if (net_log())
+ net_log()->RemoveObserver(this);
+ }
+
+ void OnAddEntry(const NetLogEntry& entry) override {
+ ++count_;
+ std::unique_ptr<base::Value> value = entry.ParametersToValue();
+ if (value && value->is_dict())
+ dict_count_++;
+ }
+
+ int count() const { return count_; }
+
+ int dict_count() const { return dict_count_; }
+
+ private:
+ int count_;
+ int dict_count_;
+};
+
+TEST_F(DnsTransactionTest, HttpsPostLookupWithLog) {
+ ConfigDohServers(true /* clear_udp */, true /* use_post */);
+ AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
+ arraysize(kT0ResponseDatagram), SYNCHRONOUS,
+ Transport::HTTPS);
+ TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
+ CountingObserver observer;
+ helper0.net_log()->AddObserver(&observer,
+ NetLogCaptureMode::IncludeSocketBytes());
+ EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(observer.count(), 5);
+ EXPECT_EQ(observer.dict_count(), 3);
+}
+
TEST_F(DnsTransactionTest, TCPLookup) {
AddAsyncQueryAndRcode(kT0HostName, kT0Qtype,
dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC);
diff --git a/chromium/net/dns/host_cache.cc b/chromium/net/dns/host_cache.cc
index 41cab7cdf6e..b900828fcc2 100644
--- a/chromium/net/dns/host_cache.cc
+++ b/chromium/net/dns/host_cache.cc
@@ -438,8 +438,6 @@ void HostCache::EvictOneEntry(base::TimeTicks now) {
}
}
- if (!eviction_callback_.is_null())
- eviction_callback_.Run(oldest_it->first, oldest_it->second);
RecordErase(ERASE_EVICT, now, oldest_it->second);
entries_.erase(oldest_it);
}
diff --git a/chromium/net/dns/host_cache.h b/chromium/net/dns/host_cache.h
index cb9c6eafbd2..816c0384c0b 100644
--- a/chromium/net/dns/host_cache.h
+++ b/chromium/net/dns/host_cache.h
@@ -154,7 +154,6 @@ class NET_EXPORT HostCache {
};
using EntryMap = std::map<Key, Entry>;
- using EvictionCallback = base::Callback<void(const Key&, const Entry&)>;
// Constructs a HostCache that stores up to |max_entries|.
explicit HostCache(size_t max_entries);
@@ -193,10 +192,6 @@ class NET_EXPORT HostCache {
// Marks all entries as stale on account of a network change.
void OnNetworkChange();
- void set_eviction_callback(const EvictionCallback& callback) {
- eviction_callback_ = callback;
- }
-
void set_persistence_delegate(PersistenceDelegate* delegate);
// Empties the cache.
@@ -264,7 +259,6 @@ class NET_EXPORT HostCache {
EntryMap entries_;
size_t max_entries_;
int network_changes_;
- EvictionCallback eviction_callback_;
// Number of cache entries that were restored in the last call to
// RestoreFromListValue(). Used in histograms.
size_t restore_size_;
diff --git a/chromium/net/dns/host_cache_unittest.cc b/chromium/net/dns/host_cache_unittest.cc
index e95717d8266..7f6e569dea2 100644
--- a/chromium/net/dns/host_cache_unittest.cc
+++ b/chromium/net/dns/host_cache_unittest.cc
@@ -392,58 +392,6 @@ TEST(HostCacheTest, Evict) {
EXPECT_TRUE(cache.Lookup(key3, now));
}
-void TestEvictionCallback(int* evict_count,
- HostCache::Key* key_out,
- const HostCache::Key& key,
- const HostCache::Entry& entry) {
- ++*evict_count;
- *key_out = key;
-}
-
-// Try to add too many entries to cache; it should evict the one with the oldest
-// expiration time.
-TEST(HostCacheTest, EvictWithCallback) {
- HostCache cache(2);
-
- int evict_count = 0;
- HostCache::Key evicted_key = Key("nothingevicted.com");
- cache.set_eviction_callback(
- base::Bind(&TestEvictionCallback, &evict_count, &evicted_key));
-
- base::TimeTicks now;
-
- HostCache::Key key1 = Key("foobar.com");
- HostCache::Key key2 = Key("foobar2.com");
- HostCache::Key key3 = Key("foobar3.com");
- HostCache::Entry entry =
- HostCache::Entry(OK, AddressList(), HostCache::Entry::SOURCE_UNKNOWN);
-
- EXPECT_EQ(0u, cache.size());
- EXPECT_FALSE(cache.Lookup(key1, now));
- EXPECT_FALSE(cache.Lookup(key2, now));
- EXPECT_FALSE(cache.Lookup(key3, now));
-
- // |key1| expires in 10 seconds, but |key2| in just 5.
- cache.Set(key1, entry, now, base::TimeDelta::FromSeconds(10));
- cache.Set(key2, entry, now, base::TimeDelta::FromSeconds(5));
- EXPECT_EQ(2u, cache.size());
- EXPECT_TRUE(cache.Lookup(key1, now));
- EXPECT_TRUE(cache.Lookup(key2, now));
- EXPECT_FALSE(cache.Lookup(key3, now));
-
- EXPECT_EQ(0, evict_count);
-
- // |key2| should be chosen for eviction, since it expires sooner.
- cache.Set(key3, entry, now, base::TimeDelta::FromSeconds(10));
- EXPECT_EQ(2u, cache.size());
- EXPECT_TRUE(cache.Lookup(key1, now));
- EXPECT_FALSE(cache.Lookup(key2, now));
- EXPECT_TRUE(cache.Lookup(key3, now));
-
- EXPECT_EQ(1, evict_count);
- EXPECT_EQ(key2.hostname, evicted_key.hostname);
-}
-
// Try to retrieve stale entries from the cache. They should be returned by
// |LookupStale()| but not |Lookup()|, with correct |EntryStaleness| data.
TEST(HostCacheTest, Stale) {
diff --git a/chromium/net/dns/host_resolver.cc b/chromium/net/dns/host_resolver.cc
index 165fb00fc42..3986b873ea4 100644
--- a/chromium/net/dns/host_resolver.cc
+++ b/chromium/net/dns/host_resolver.cc
@@ -120,10 +120,6 @@ std::unique_ptr<base::Value> HostResolver::GetDnsConfigAsValue() const {
return nullptr;
}
-void HostResolver::InitializePersistence(
- const PersistCallback& persist_callback,
- std::unique_ptr<const base::Value> old_data) {}
-
void HostResolver::SetNoIPv6OnWifi(bool no_ipv6_on_wifi) {
NOTREACHED();
}
diff --git a/chromium/net/dns/host_resolver.h b/chromium/net/dns/host_resolver.h
index 7876d8787ab..43d251c1785 100644
--- a/chromium/net/dns/host_resolver.h
+++ b/chromium/net/dns/host_resolver.h
@@ -208,16 +208,6 @@ class NET_EXPORT HostResolver {
// nullptr if it's configured to always use the system host resolver.
virtual std::unique_ptr<base::Value> GetDnsConfigAsValue() const;
- typedef base::Callback<void(std::unique_ptr<const base::Value>)>
- PersistCallback;
- // Configures the HostResolver to be able to persist data (e.g. observed
- // performance) between sessions. |persist_callback| is a callback that will
- // be called when the HostResolver wants to persist data; |old_data| is the
- // data last persisted by the resolver on the previous session.
- virtual void InitializePersistence(
- const PersistCallback& persist_callback,
- std::unique_ptr<const base::Value> old_data);
-
// Sets the HostResolver to assume that IPv6 is unreachable when on a wifi
// connection. See https://crbug.com/696569 for further context.
virtual void SetNoIPv6OnWifi(bool no_ipv6_on_wifi);
diff --git a/chromium/net/dns/host_resolver_impl.cc b/chromium/net/dns/host_resolver_impl.cc
index f46c06a8125..3a279aaef06 100644
--- a/chromium/net/dns/host_resolver_impl.cc
+++ b/chromium/net/dns/host_resolver_impl.cc
@@ -562,9 +562,6 @@ void MakeNotStale(HostCache::EntryStaleness* stale_info) {
stale_info->stale_hits = 0;
}
-// Persist data every five minutes (potentially, cache and learned RTT).
-const int64_t kPersistDelaySec = 300;
-
} // namespace
//-----------------------------------------------------------------------------
@@ -670,6 +667,9 @@ class HostResolverImpl::RequestImpl : public HostResolver::Request {
// Calls HostResolverProc in TaskScheduler. Performs retries if necessary.
//
+// In non-test code, the HostResolverProc is always SystemHostResolverProc,
+// which calls a platform API that implements host resolution.
+//
// Whenever we try to resolve the host, we post a delayed task to check if host
// resolution (OnLookupComplete) is completed or not. If the original attempt
// hasn't completed, then we start another attempt for host resolution. We take
@@ -966,7 +966,11 @@ class HostResolverImpl::ProcTask
//-----------------------------------------------------------------------------
-// Resolves the hostname using DnsTransaction.
+// Resolves the hostname using DnsTransaction, which is a full implementation of
+// a DNS stub resolver. One DnsTransaction is created for each resolution
+// needed, which for AF_UNSPEC resolutions includes both A and AAAA. The
+// transactions are scheduled separately and started separately.
+//
// TODO(szym): This could be moved to separate source file as well.
class HostResolverImpl::DnsTask : public base::SupportsWeakPtr<DnsTask> {
public:
@@ -1769,8 +1773,6 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job,
net_log_.EndEventWithNetErrorCode(NetLogEventType::HOST_RESOLVER_IMPL_JOB,
entry.error());
- resolver_->SchedulePersist();
-
DCHECK(!requests_.empty());
if (entry.error() == OK || entry.error() == ERR_ICANN_NAME_COLLISION) {
@@ -1977,7 +1979,6 @@ HostResolverImpl::HostResolverImpl(const Options& options, NetLog* net_log)
last_ipv6_probe_result_(true),
additional_resolver_flags_(0),
fallback_to_proctask_(true),
- persist_initialized_(false),
weak_ptr_factory_(this),
probe_weak_ptr_factory_(this) {
if (options.enable_caching)
@@ -2415,8 +2416,7 @@ bool HostResolverImpl::IsGloballyReachable(const IPAddress& dest,
const NetLogWithSource& net_log) {
std::unique_ptr<DatagramClientSocket> socket(
ClientSocketFactory::GetDefaultFactory()->CreateDatagramClientSocket(
- DatagramSocket::DEFAULT_BIND, RandIntCallback(), net_log.net_log(),
- net_log.source()));
+ DatagramSocket::DEFAULT_BIND, net_log.net_log(), net_log.source()));
int rv = socket->Connect(IPEndPoint(dest, 53));
if (rv != OK)
return false;
@@ -2646,36 +2646,6 @@ void HostResolverImpl::SetDnsClient(std::unique_ptr<DnsClient> dns_client) {
AbortDnsTasks();
}
-void HostResolverImpl::InitializePersistence(
- const PersistCallback& persist_callback,
- std::unique_ptr<const base::Value> old_data) {
- DCHECK(!persist_initialized_);
- persist_callback_ = persist_callback;
- persist_initialized_ = true;
- if (old_data)
- ApplyPersistentData(std::move(old_data));
-}
-
-void HostResolverImpl::ApplyPersistentData(
- std::unique_ptr<const base::Value> data) {}
-
-std::unique_ptr<const base::Value> HostResolverImpl::GetPersistentData() {
- return std::unique_ptr<const base::Value>();
-}
-
-void HostResolverImpl::SchedulePersist() {
- if (!persist_initialized_ || persist_timer_.IsRunning())
- return;
- persist_timer_.Start(
- FROM_HERE, base::TimeDelta::FromSeconds(kPersistDelaySec),
- base::Bind(&HostResolverImpl::DoPersist, weak_ptr_factory_.GetWeakPtr()));
-}
-
-void HostResolverImpl::DoPersist() {
- DCHECK(persist_initialized_);
- persist_callback_.Run(GetPersistentData());
-}
-
HostResolverImpl::RequestImpl::~RequestImpl() {
if (job_)
job_->CancelRequest(this);
diff --git a/chromium/net/dns/host_resolver_impl.h b/chromium/net/dns/host_resolver_impl.h
index 0eada32f204..c98b12a7cda 100644
--- a/chromium/net/dns/host_resolver_impl.h
+++ b/chromium/net/dns/host_resolver_impl.h
@@ -31,11 +31,11 @@ class NetLog;
class NetLogWithSource;
// For each hostname that is requested, HostResolver creates a
-// HostResolverImpl::Job. When this job gets dispatched it creates a ProcTask
-// which runs the given HostResolverProc in TaskScheduler. If requests for that
-// same host are made during the job's lifetime, they are attached to the
-// existing job rather than creating a new one. This avoids doing parallel
-// resolves for the same host.
+// HostResolverImpl::Job. When this job gets dispatched it creates a task
+// (ProcTask for the system resolver or DnsTask for the async resolver) which
+// resolves the hostname. If requests for that same host are made during the
+// job's lifetime, they are attached to the existing job rather than creating a
+// new one. This avoids doing parallel resolves for the same host.
//
// The way these classes fit together is illustrated by:
//
@@ -159,10 +159,6 @@ class NET_EXPORT HostResolverImpl
// Returns the number of entries in the host cache, or 0 if there is no cache.
size_t CacheSize() const;
- void InitializePersistence(
- const PersistCallback& persist_callback,
- std::unique_ptr<const base::Value> old_data) override;
-
void SetNoIPv6OnWifi(bool no_ipv6_on_wifi) override;
bool GetNoIPv6OnWifi() override;
@@ -316,12 +312,6 @@ class NET_EXPORT HostResolverImpl
// and resulted in |net_error|.
void OnDnsTaskResolve(int net_error);
- void ApplyPersistentData(std::unique_ptr<const base::Value>);
- std::unique_ptr<const base::Value> GetPersistentData();
-
- void SchedulePersist();
- void DoPersist();
-
// Allows the tests to catch slots leaking out of the dispatcher. One
// HostResolverImpl::Job could occupy multiple PrioritizedDispatcher job
// slots.
@@ -377,10 +367,6 @@ class NET_EXPORT HostResolverImpl
// TaskScheduler task runner, but can be overridden for tests.
scoped_refptr<base::TaskRunner> proc_task_runner_;
- bool persist_initialized_;
- PersistCallback persist_callback_;
- base::OneShotTimer persist_timer_;
-
URLRequestContext* url_request_context_;
std::vector<DnsConfig::DnsOverHttpsServerConfig> dns_over_https_servers_;
diff --git a/chromium/net/dns/host_resolver_impl_unittest.cc b/chromium/net/dns/host_resolver_impl_unittest.cc
index cbf1dec09af..f9d485a9141 100644
--- a/chromium/net/dns/host_resolver_impl_unittest.cc
+++ b/chromium/net/dns/host_resolver_impl_unittest.cc
@@ -25,6 +25,7 @@
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
+#include "base/values.h"
#include "net/base/address_list.h"
#include "net/base/ip_address.h"
#include "net/base/mock_network_change_notifier.h"
diff --git a/chromium/net/dns/mock_mdns_socket_factory.h b/chromium/net/dns/mock_mdns_socket_factory.h
index 059a93aa754..05224de2dcb 100644
--- a/chromium/net/dns/mock_mdns_socket_factory.h
+++ b/chromium/net/dns/mock_mdns_socket_factory.h
@@ -45,12 +45,16 @@ class MockMDnsDatagramServerSocket : public DatagramServerSocket {
MOCK_METHOD1(SetReceiveBufferSize, int(int32_t size));
MOCK_METHOD1(SetSendBufferSize, int(int32_t size));
MOCK_METHOD0(SetDoNotFragment, int());
+ MOCK_METHOD1(SetMsgConfirm, void(bool confirm));
MOCK_METHOD0(Close, void());
MOCK_CONST_METHOD1(GetPeerAddress, int(IPEndPoint* address));
int GetLocalAddress(IPEndPoint* address) const override;
MOCK_METHOD0(UseNonBlockingIO, void());
+ MOCK_METHOD0(UseWriteBatching, void());
+ MOCK_METHOD0(UseMultiCore, void());
+ MOCK_METHOD0(UseSendmmsg, void());
MOCK_CONST_METHOD0(NetLog, const NetLogWithSource&());
MOCK_METHOD0(AllowAddressReuse, void());
diff --git a/chromium/net/dns/mojo_host_struct_traits.cc b/chromium/net/dns/mojo_host_struct_traits.cc
index 27332de010e..07f7a3a0864 100644
--- a/chromium/net/dns/mojo_host_struct_traits.cc
+++ b/chromium/net/dns/mojo_host_struct_traits.cc
@@ -6,7 +6,6 @@
#include <utility>
-#include "base/memory/ptr_util.h"
#include "net/base/address_list.h"
#include "net/interfaces/address_family_mojom_traits.h"
diff --git a/chromium/net/dns/notify_watcher_mac.cc b/chromium/net/dns/notify_watcher_mac.cc
index 6d22d70b94d..e2e5528ab4c 100644
--- a/chromium/net/dns/notify_watcher_mac.cc
+++ b/chromium/net/dns/notify_watcher_mac.cc
@@ -7,6 +7,7 @@
#include <notify.h>
#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
#include "base/posix/eintr_wrapper.h"
namespace net {
@@ -28,10 +29,7 @@ bool NotifyWatcherMac::Watch(const char* key, const CallbackType& callback) {
return false;
DCHECK_GE(notify_fd_, 0);
if (!base::MessageLoopForIO::current()->WatchFileDescriptor(
- notify_fd_,
- true,
- base::MessageLoopForIO::WATCH_READ,
- &watcher_,
+ notify_fd_, true, base::MessagePumpForIO::WATCH_READ, &watcher_,
this)) {
Cancel();
return false;
diff --git a/chromium/net/dns/notify_watcher_mac.h b/chromium/net/dns/notify_watcher_mac.h
index 5a8734398d7..a33fbbf9960 100644
--- a/chromium/net/dns/notify_watcher_mac.h
+++ b/chromium/net/dns/notify_watcher_mac.h
@@ -7,13 +7,13 @@
#include "base/callback.h"
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_pump_for_io.h"
namespace net {
// Watches for notifications from Libnotify and delivers them to a Callback.
// After failure the watch is cancelled and will have to be restarted.
-class NotifyWatcherMac : public base::MessageLoopForIO::Watcher {
+class NotifyWatcherMac : public base::MessagePumpForIO::FdWatcher {
public:
// Called on received notification with true on success and false on error.
typedef base::Callback<void(bool succeeded)> CallbackType;
@@ -31,14 +31,14 @@ class NotifyWatcherMac : public base::MessageLoopForIO::Watcher {
void Cancel();
private:
- // MessageLoopForIO::Watcher:
+ // MessagePumpForIO::FdWatcher:
void OnFileCanReadWithoutBlocking(int fd) override;
void OnFileCanWriteWithoutBlocking(int fd) override {}
int notify_fd_;
int notify_token_;
CallbackType callback_;
- base::MessageLoopForIO::FileDescriptorWatcher watcher_;
+ base::MessagePumpForIO::FdWatchController watcher_;
DISALLOW_COPY_AND_ASSIGN(NotifyWatcherMac);
};
diff --git a/chromium/net/docs/bug-triage-suggested-workflow.md b/chromium/net/docs/bug-triage-suggested-workflow.md
index 3c548e089e4..dcde25f45cd 100644
--- a/chromium/net/docs/bug-triage-suggested-workflow.md
+++ b/chromium/net/docs/bug-triage-suggested-workflow.md
@@ -21,7 +21,7 @@
trace in the bug, so no one else has to look up the crash stack from the ID.
* If there's just a blank form and a crash ID, just ignore the bug.
-* If network causes are possible, ask for a net-internals log (If it's not a
+* If network causes are possible, ask for a net-export log (If it's not a
browser crash) and attach the most specific internals-network label that's
applicable. If there isn't an applicable narrower component, a clear owner
for the issue, or there are multiple possibilities, attach the
@@ -50,7 +50,7 @@ For each alert that fires, determine if it's a real alert and file a bug if so.
## Investigating component=Internals>Network bugs
* Note that you may want to investigate Needs-Feedback bugs first, as
- that may result in some bugs being added to this list.
+ that may result in some bugs being added to this list.
* It's recommended that while on triage duty, you subscribe to the
Internals>Network component (but not its subcomponents). To do this, go
@@ -90,7 +90,7 @@ For each alert that fires, determine if it's a real alert and file a bug if so.
* If it may be a network bug, attach additional possibly relevant component if
any, and continue investigating. Once you either determine it's a
non-network bug, or figure out accurate more specific network components, your
- job is done, though you should still ask for a net-internals dump if it seems
+ job is done, though you should still ask for a net-export dump if it seems
likely to be useful.
* Note that Chrome-OS-specific network-related code (Captive portal detection,
@@ -105,11 +105,10 @@ For each alert that fires, determine if it's a real alert and file a bug if so.
user.
* Try to reproduce locally. If you can, and it's a regression, use
src/tools/bisect-builds.py to figure out when it regressed.
- * Ask more data from the user as needed (net-internals dumps, repro case,
- crash ID from about:crashes, run tests, etc).
- * If asking for an about:net-internals dump, provide this link:
+ * Ask more data from the user as needed (net-export dumps, repro case,
+ crash ID from chrome://crashes, run tests, etc).
+ * If asking for a chrome://net-export dump, provide this link:
https://sites.google.com/a/chromium.org/dev/for-testers/providing-network-details.
- Can just grab the link from about:net-internals, as needed.
* Try to figure out what's going on, and which more specific network component
is most appropriate.
@@ -119,10 +118,9 @@ For each alert that fires, determine if it's a real alert and file a bug if so.
strongly suspect CLs.
* If you are having trouble with an issue, particularly for help understanding
- net-internals logs, email the public net-dev@chromium.org list for help
+ net-export logs, email the public net-dev@chromium.org list for help
debugging. If it's a crasher, or for some other reason discussion needs to
- be done in private, use chrome-network-debugging@google.com. TODO(mmenke):
- Write up a net-internals tips and tricks docs.
+ be done in private, use chrome-network-debugging@google.com.
* If it appears to be a bug in the unowned core of the network stack (i.e. no
subcomponent applies, or only the Internals>Network>HTTP subcomponent
@@ -184,7 +182,7 @@ As an alternative to the above, you can use [Eric Roman's new crash
tool](https://ericroman.users.x20web.corp.google.com/www/net-crash-triage/index.html)
(internal link). Note that it isn't a perfect fit with the triage
responsibilities, specifically:
-
+
* It's only showing Windows releases; Android, iOS, and WebView are
usually different, and Mac is sometimes different.
* The instructions are to look at the latest canary which has a days
@@ -192,7 +190,7 @@ responsibilities, specifically:
than one canary into the past, and hence not visible on the tool.
* Eric's tool filters based on files in "src/net" rather than looking
for magic signature's including the string "net::" ("src/net" is
- probably the better filter).
+ probably the better filter).
## Investigating crashers
diff --git a/chromium/net/docs/bug-triage.md b/chromium/net/docs/bug-triage.md
index b257802ae87..eb349ad128a 100644
--- a/chromium/net/docs/bug-triage.md
+++ b/chromium/net/docs/bug-triage.md
@@ -30,20 +30,20 @@ uniform, predictable two day commitment for all triagers.
### Required:
-* Identify new network bugs on the bug tracker. All Unconfirmed issues filed
- during your triage rotation should be scanned, and, for suspected network
- bugs, a network component assigned and an about:net-internals log requested.
- A triager is responsible for looking at bugs reported from noon PST / 3:00 pm
- EST of the last day of the previous triager's rotation until the same time on
- the last day of their rotation. Once you've assigned a bug to a component,
- mark it Untriaged, so other triagers sorting through Unconfirmed bugs won't
- see it.
-
- * For desktop bugs, ask for a net-internals log and give the user a link to
- https://sites.google.com/a/chromium.org/dev/for-testers/providing-network-details
- (A link there appears on about:net-internals, for easy reference) for
- instructions. On mobile, point them to about:net-export. In either case,
- attach the Needs-Feedback label.
+* Identify new network bugs on the bug tracker, looking at [this issue tracker
+ query](https://bugs.chromium.org/p/chromium/issues/list?q=status%3Aunconfirmed&sort=-id&num=1000).
+
+ * All Unconfirmed issues filed during your triage rotation should be scanned,
+ and, for suspected network bugs, a network component assigned and a
+ chrome://net-export/ log requested. Suggested text: "Please collect and
+ attach a chrome://net-export log. Instructions can be found here:
+ https://sites.google.com/a/chromium.org/dev/for-testers/providing-network-details".
+ A link to the instructions appears on net-export, for easy reference.
+ When asking for a log or more details, attach the Needs-Feedback label.
+
+ * A triager is responsible for looking at bugs reported from noon PST /
+ 3:00 pm EST of the last day of the previous triager's rotation until the
+ same time on the last day of their rotation.
* Investigate UMA notifications.
@@ -51,17 +51,17 @@ uniform, predictable two day commitment for all triagers.
sent to chrome-network-debugging@google.com. Triagers should subscribe
to this list. When an alert fires, the triager should determine if the
alert looks to be real and file a bug with the appropriate label if so.
- Note that if no label more specific than Internals>Network is appropriate,
- the responsibility remains with the triager to continue investigating the
- bug, as above.
-
+ Note that if no label more specific than Internals&gt;Network is
+ appropriate, the responsibility remains with the triager to continue
+ investigating the bug, as above.
+
* The triager is responsible for looking at any notification previous
triagers did not, so when an issue is investigated, the person who did
so should respond to chrome-network-debugging@google.com with a short
email, describing their conclusions. Future triagers can then use the
fact an alert was responded to as an indicator of which of them need
to be followed up on. Alerts fired before the beginning of the
- previous triager's rotation may be ignored.
+ previous triager's rotation may be ignored.
* Investigate [Unconfirmed / Untriaged Internals>Network issues that don't belong to a more specific network component](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3DInternals%3ENetwork+status%3AUnconfirmed,Untriaged+-label:Needs-Feedback&sort=-modified),
prioritizing the most recent issues, ones with the most responsive reporters,
@@ -82,8 +82,8 @@ uniform, predictable two day commitment for all triagers.
due to the way the bug report wizard works, a lot of bugs incorrectly end
up with the network component.
- * The issue is assigned to an appropriate owner, and make sure to mark it
- as "assigned" so the next triager doesn't run into it.
+ * The issue is assigned to an appropriate owner. Make sure to mark it as
+ "assigned" so the next triager doesn't run into it.
* If there is no more specific component for a bug, it should be
investigated by the triager until we have a good understanding of the
@@ -118,6 +118,10 @@ uniform, predictable two day commitment for all triagers.
* Make sure to check for new crashes on all platforms, not just Windows.
+ * [go/chromenetcrash](https://goto.google.com/chromenetcrash) has a list
+ of net crashes by version, though makes it more difficult to tell if a
+ crash makes up a significant portion of all Chrome crashes.
+
### Best Effort (As you have time):
* Investigate old bugs, and bugs associated with Internals>Network
@@ -125,8 +129,8 @@ uniform, predictable two day commitment for all triagers.
* Investigate unowned and owned but forgotten net/ crashers that are still
occurring (As indicated by
- [go/chromecrash](https://goto.google.com/chromecrash)), prioritizing frequent
- and long standing crashers.
+ [go/chromenetcrash](https://goto.google.com/chromenetcrash)), prioritizing
+ frequent and long standing crashers.
* Close obsolete bugs.
@@ -137,4 +141,4 @@ See [bug-triage-labels.md](bug-triage-labels.md) for labeling tips for network
and non-network bugs.
See [crash-course-in-net-internals.md](crash-course-in-net-internals.md) for
-some help on getting started with about:net-internals debugging.
+some help on getting started with chrome://net-internals debugging.
diff --git a/chromium/net/docs/crash-course-in-net-internals.md b/chromium/net/docs/crash-course-in-net-internals.md
index 9187f858e3b..08d5d3fc27f 100644
--- a/chromium/net/docs/crash-course-in-net-internals.md
+++ b/chromium/net/docs/crash-course-in-net-internals.md
@@ -1,7 +1,7 @@
-# A Crash Course in Debugging with about:net-internals
+# A Crash Course in Debugging with chrome://net-internals
This document is intended to help get people started debugging network errors
-with about:net-internals, with some commonly useful tips and tricks. This
+with chrome://net-internals, with some commonly useful tips and tricks. This
document is aimed more at how to get started using some of its features to
investigate bug reports, rather than as a feature overview.
@@ -10,9 +10,9 @@ It would probably be useful to read
# What Data Net-Internals Contains
-about:net-internals provides a view of browser activity from net/'s perspective.
-For this reason, it lacks knowledge of tabs, navigation, frames, resource types,
-etc.
+chrome://net-internals provides a view of browser activity from net/'s
+perspective. For this reason, it lacks knowledge of tabs, navigation, frames,
+resource types, etc.
The leftmost column presents a list of views. Most debugging is done with the
Events view, which will be all this document covers.
@@ -23,13 +23,13 @@ single, global, ChromeNetLog object. This includes both incognito and
non-incognito profiles, among other things. The Events view only shows events
for the period that net-internals was open and running, and is incrementally
updated as events occur. The code attempts to add a top level event for
-URLRequests that were active when the about:net-internals tab was opened, to
+URLRequests that were active when the chrome://net-internals tab was opened, to
help debug hung requests, but that's best-effort only, and only includes
requests for the current profile and the system URLRequestContext.
The other views are all snapshots of the current state of the main
URLRequestContext's components, and are updated on a 5 second timer. These will
-show objects that were created before about:net-internals was opened.
+show objects that were created before chrome://net-internals was opened.
# Events vs Sources
@@ -165,7 +165,7 @@ should generally ignore those, and look for a more interesting one.
This is often useful in finding hung or slow requests.
For a list of other filter commands, you can mouse over the question mark on
-about:net-internals.
+chrome://net-internals.
Once you locate the problematic request, the next is to figure out where the
problem is -- it's often one of the last events, though it could also be related
diff --git a/chromium/net/docs/host-resolver.md b/chromium/net/docs/host-resolver.md
new file mode 100644
index 00000000000..263b8d0f993
--- /dev/null
+++ b/chromium/net/docs/host-resolver.md
@@ -0,0 +1,102 @@
+# Host Resolution
+
+This document is a brief overview of how host resolution works in the Chrome
+network stack.
+
+The stack includes two different implementations: the "system" or "platform"
+resolver, and the "async" or "built-in" resolver. The higher layers are shared
+between the implementations, and the lower layers are implemented separately.
+
+## Shared layers
+
+### Host resolver
+
+The HostResolverImpl is the main interface between DNS and the rest of the
+network stack. It checks the HostCache, checks if there is an already running
+Job, and schedules a new Job if there isn't one in progress.
+
+Data collected at this layer:
+* "Net.DNS.TotalTime" (recommended for DNS experiments)
+* "Net.DNS.TotalTimeNotCached"
+
+### Job
+
+The HostResolverImpl::Job represents a single DNS resolution from the network
+(or in some cases the OS's DNS cache, which Chrome doesn't know about). It
+starts a task depending on which implementation should be used. If a DnsTask
+fails, it retries using a ProcTask.
+
+Data collected at this layer:
+* "Net.DNS.ResolveSuccessTime" (also by address family)
+* "Net.DNS.ResolveFailureTime" (also by address family)
+* "Net.DNS.ResolveCategory"
+* "Net.DNS.ResolveError.Fast"
+* "Net.DNS.ResolveError.Slow"
+
+## System resolver
+
+### Task
+
+The entry point for the system resolver is HostResolverImpl::ProcTask. The task
+runs almost entirely on TaskScheduler. Its main implementation is in
+SystemHostResolverProc. Other implementations of HostResolverProc can be swapped
+in for testing.
+
+Data collected at this layer:
+* "Net.DNS.ProcTask.SuccessTime"
+* "Net.DNS.ProcTask.FailureTime"
+* "Net.OSErrorsForGetaddrinfo*"
+
+### Attempt
+
+Attempts in the system resolver are not a separate class. They're implemented as
+separate tasks posted to TaskScheduler.
+
+Data collected at this layer:
+* "DNS.AttemptFirstSuccess"
+* "DNS.AttemptFirstFailure"
+* "DNS.AttemptSuccess"
+* "DNS.AttemptFailure"
+* "DNS.AttemptDiscarded"
+* "DNS.AttemptCancelled"
+* "DNS.AttemptSuccessDuration"
+* "DNS.AttemptFailDuration"
+
+## Async resolver
+
+### Task
+
+The entry point for the async resolver is HostResolverImpl::DnsTask. DnsTask
+starts one DnsTransaction for each lookup needed, which can be one for a single
+address family or two when both A and AAAA are needed.
+
+Data collected at this layer:
+* "Net.DNS.DnsTask.SuccessTime"
+* "Net.DNS.DnsTask.FailureTime"
+* "Net.DNS.DnsTask.ErrorBeforeFallback.Fast"
+* "Net.DNS.DnsTask.ErrorBeforeFallback.Slow"
+* "Net.DNS.DnsTask.Errors"
+
+### Transaction
+
+The main implementation of the async resolver is in the DnsTransaction. Each
+transaction represents a single query, which might be tried multiple times or in
+different ways.
+
+Data collected at this layer:
+* "AsyncDNS.TransactionFailure"
+* "AsyncDNS.TransactionSuccess" (and by query type)
+
+### Attempt
+
+Attempts in the async resolver are an explicit layer, implemented by subclasses
+of DnsAttempt. In most cases, DnsUDPAttempt is used. DnsTCPAttempt is used
+instead when the server requests it. DnsHTTPAttempt is experimental.
+
+Data collected at this layer:
+* "AsyncDNS.UDPAttemptSuccess"
+* "AsyncDNS.UDPAttemptFail"
+* "AsyncDNS.TCPAttemptSuccess"
+* "AsyncDNS.TCPAttemptFail"
+* "AsyncDNS.AttemptCountSuccess"
+* "AsyncDNS.AttemptCountFail"
diff --git a/chromium/net/extras/sqlite/sqlite_channel_id_store.cc b/chromium/net/extras/sqlite/sqlite_channel_id_store.cc
index 71a9308ba1e..93191650276 100644
--- a/chromium/net/extras/sqlite/sqlite_channel_id_store.cc
+++ b/chromium/net/extras/sqlite/sqlite_channel_id_store.cc
@@ -162,7 +162,7 @@ class SQLiteChannelIDStore::Backend
std::unique_ptr<sql::Connection> db_;
sql::MetaTable meta_table_;
- typedef std::list<PendingOperation*> PendingOperationsList;
+ typedef std::list<std::unique_ptr<PendingOperation>> PendingOperationsList;
PendingOperationsList pending_;
PendingOperationsList::size_type num_pending_;
// True if the persistent store should skip clear on exit rules.
@@ -414,7 +414,7 @@ void SQLiteChannelIDStore::Backend::BatchOperation(
PendingOperationsList::size_type num_pending;
{
base::AutoLock locked(lock_);
- pending_.push_back(po.release());
+ pending_.push_back(std::move(po));
num_pending = ++num_pending_;
}
@@ -440,7 +440,7 @@ void SQLiteChannelIDStore::Backend::PrunePendingOperationsForDeletes(
it != pending_.end();) {
if (base::ContainsValue(server_identifiers,
(*it)->channel_id().server_identifier())) {
- std::unique_ptr<PendingOperation> po(*it);
+ std::unique_ptr<PendingOperation> po(std::move(*it));
it = pending_.erase(it);
--num_pending_;
} else {
@@ -491,7 +491,7 @@ void SQLiteChannelIDStore::Backend::Commit() {
for (PendingOperationsList::iterator it = ops.begin(); it != ops.end();
++it) {
// Free the certs as we commit them to the database.
- std::unique_ptr<PendingOperation> po(*it);
+ std::unique_ptr<PendingOperation> po(std::move(*it));
switch (po->op()) {
case PendingOperation::CHANNEL_ID_ADD: {
add_statement.Reset(true);
diff --git a/chromium/net/extras/sqlite/sqlite_persistent_cookie_store.cc b/chromium/net/extras/sqlite/sqlite_persistent_cookie_store.cc
index c47ccefb164..90afe861f9b 100644
--- a/chromium/net/extras/sqlite/sqlite_persistent_cookie_store.cc
+++ b/chromium/net/extras/sqlite/sqlite_persistent_cookie_store.cc
@@ -21,6 +21,7 @@
#include "base/sequenced_task_runner.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "base/synchronization/atomic_flag.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "net/cookies/canonical_cookie.h"
@@ -37,6 +38,51 @@ using base::Time;
namespace {
+// Used to populate a histogram for problems when loading cookies.
+//
+// Please do not reorder or remove entries. New entries must be added to the
+// end of the list, just before COOKIE_LOAD_PROBLEM_LAST_ENTRY.
+enum CookieLoadProblem {
+ COOKIE_LOAD_PROBLEM_DECRYPT_FAILED = 0,
+ COOKIE_LOAD_PROBLEM_DECRYPT_TIMEOUT = 1,
+ COOKIE_LOAD_PROBLEM_NON_CANONICAL = 2,
+ COOKIE_LOAD_PROBLEM_OPEN_DB = 3,
+ COOKIE_LOAD_PROBLEM_LAST_ENTRY
+};
+
+// Used to populate a histogram for problems when committing cookies.
+//
+// Please do not reorder or remove entries. New entries must be added to the
+// end of the list, just before COOKIE_COMMIT_PROBLEM_LAST_ENTRY.
+enum CookieCommitProblem {
+ COOKIE_COMMIT_PROBLEM_ENCRYPT_FAILED = 0,
+ COOKIE_COMMIT_PROBLEM_ADD = 1,
+ COOKIE_COMMIT_PROBLEM_UPDATE_ACCESS = 2,
+ COOKIE_COMMIT_PROBLEM_DELETE = 3,
+ COOKIE_COMMIT_PROBLEM_LAST_ENTRY
+};
+
+// Used to report a histogram on status of cookie commit to disk.
+//
+// Please do not reorder or remove entries. New entries must be added to the
+// end of the list, just before BACKING_STORE_RESULTS_LAST_ENTRY.
+enum BackingStoreResults {
+ BACKING_STORE_RESULTS_SUCCESS = 0,
+ BACKING_STORE_RESULTS_FAILURE = 1,
+ BACKING_STORE_RESULTS_MIXED = 2,
+ BACKING_STORE_RESULTS_LAST_ENTRY
+};
+
+void RecordCookieLoadProblem(CookieLoadProblem event) {
+ UMA_HISTOGRAM_ENUMERATION("Cookie.LoadProblem", event,
+ COOKIE_LOAD_PROBLEM_LAST_ENTRY);
+}
+
+void RecordCookieCommitProblem(CookieCommitProblem event) {
+ UMA_HISTOGRAM_ENUMERATION("Cookie.CommitProblem", event,
+ COOKIE_COMMIT_PROBLEM_LAST_ENTRY);
+}
+
// The persistent cookie store is loaded into memory on eTLD at a time. This
// variable controls the delay between loading eTLDs, so as to not overload the
// CPU or I/O with these low priority requests immediately after start up.
@@ -50,6 +96,38 @@ const int kLoadDelayMilliseconds = 0;
const int kLoadDelayMilliseconds = 0;
#endif
+// A little helper to help us log (on client thread) if the background runner
+// gets stuck.
+class TimeoutTracker : public base::RefCountedThreadSafe<TimeoutTracker> {
+ public:
+ // Runs on background runner.
+ static scoped_refptr<TimeoutTracker> Begin(
+ const scoped_refptr<base::SequencedTaskRunner>& client_task_runner) {
+ scoped_refptr<TimeoutTracker> tracker = new TimeoutTracker;
+ client_task_runner->PostDelayedTask(
+ FROM_HERE, base::BindOnce(&TimeoutTracker::TimerElapsed, tracker),
+ base::TimeDelta::FromSeconds(60));
+ return tracker;
+ }
+
+ // Runs on background runner.
+ void End() { done_.Set(); }
+
+ private:
+ friend class base::RefCountedThreadSafe<TimeoutTracker>;
+ TimeoutTracker() {}
+ ~TimeoutTracker() { DCHECK(done_.IsSet()); }
+
+ // Run on client runner.
+ void TimerElapsed() {
+ if (!done_.IsSet())
+ RecordCookieLoadProblem(COOKIE_LOAD_PROBLEM_DECRYPT_TIMEOUT);
+ }
+
+ base::AtomicFlag done_;
+ DISALLOW_COPY_AND_ASSIGN(TimeoutTracker);
+};
+
} // namespace
namespace net {
@@ -241,7 +319,7 @@ class SQLitePersistentCookieStore::Backend
std::unique_ptr<sql::Connection> db_;
sql::MetaTable meta_table_;
- typedef std::list<PendingOperation*> PendingOperationsList;
+ typedef std::list<std::unique_ptr<PendingOperation>> PendingOperationsList;
PendingOperationsList pending_;
PendingOperationsList::size_type num_pending_;
// Guard |cookies_|, |pending_|, |num_pending_|.
@@ -352,7 +430,7 @@ namespace {
// expire them in decreasing order of use when we've reached the maximum
// number of cookies.
const int kCurrentVersionNumber = 10;
-const int kCompatibleVersionNumber = 5;
+const int kCompatibleVersionNumber = 10;
// Possible values for the 'priority' column.
enum DBCookiePriority {
@@ -667,7 +745,8 @@ bool SQLitePersistentCookieStore::Backend::InitializeDatabase() {
base::Unretained(this)));
if (!db_->Open(path_)) {
- NOTREACHED() << "Unable to open cookie DB.";
+ DLOG(ERROR) << "Unable to open cookie DB.";
+ RecordCookieLoadProblem(COOKIE_LOAD_PROBLEM_OPEN_DB);
if (corruption_detected_)
db_->Raze();
meta_table_.Reset();
@@ -676,7 +755,8 @@ bool SQLitePersistentCookieStore::Backend::InitializeDatabase() {
}
if (!EnsureDatabaseVersion() || !InitTable(db_.get())) {
- NOTREACHED() << "Unable to open cookie DB.";
+ DLOG(ERROR) << "Unable to open cookie DB.";
+ RecordCookieLoadProblem(COOKIE_LOAD_PROBLEM_OPEN_DB);
if (corruption_detected_)
db_->Raze();
meta_table_.Reset();
@@ -817,13 +897,20 @@ bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains(
void SQLitePersistentCookieStore::Backend::MakeCookiesFromSQLStatement(
std::vector<std::unique_ptr<CanonicalCookie>>* cookies,
sql::Statement* statement) {
+ DCHECK(background_task_runner_->RunsTasksInCurrentSequence());
sql::Statement& smt = *statement;
while (smt.Step()) {
std::string value;
std::string encrypted_value = smt.ColumnString(4);
if (!encrypted_value.empty() && crypto_) {
- if (!crypto_->DecryptString(encrypted_value, &value))
+ scoped_refptr<TimeoutTracker> timeout_tracker =
+ TimeoutTracker::Begin(client_task_runner_);
+ bool decrypt_ok = crypto_->DecryptString(encrypted_value, &value);
+ timeout_tracker->End();
+ if (!decrypt_ok) {
+ RecordCookieLoadProblem(COOKIE_LOAD_PROBLEM_DECRYPT_FAILED);
continue;
+ }
} else {
value = smt.ColumnString(3);
}
@@ -843,8 +930,11 @@ void SQLitePersistentCookieStore::Backend::MakeCookiesFromSQLStatement(
static_cast<DBCookiePriority>(smt.ColumnInt(13))))); // priority
DLOG_IF(WARNING, cc->CreationDate() > Time::Now())
<< L"CreationDate too recent";
- if (cc->IsCanonical())
+ if (cc->IsCanonical()) {
cookies->push_back(std::move(cc));
+ } else {
+ RecordCookieLoadProblem(COOKIE_LOAD_PROBLEM_NON_CANONICAL);
+ }
++num_cookies_read_;
}
}
@@ -1141,7 +1231,7 @@ void SQLitePersistentCookieStore::Backend::BatchOperation(
PendingOperationsList::size_type num_pending;
{
base::AutoLock locked(lock_);
- pending_.push_back(po.release());
+ pending_.push_back(std::move(po));
num_pending = ++num_pending_;
}
@@ -1205,10 +1295,11 @@ void SQLitePersistentCookieStore::Backend::Commit() {
if (!transaction.Begin())
return;
+ bool trouble = false;
for (PendingOperationsList::iterator it = ops.begin(); it != ops.end();
++it) {
// Free the cookies as we commit them to the database.
- std::unique_ptr<PendingOperation> po(*it);
+ std::unique_ptr<PendingOperation> po(std::move(*it));
switch (po->op()) {
case PendingOperation::COOKIE_ADD:
add_smt.Reset(true);
@@ -1217,8 +1308,12 @@ void SQLitePersistentCookieStore::Backend::Commit() {
add_smt.BindString(2, po->cc().Name());
if (crypto_ && crypto_->ShouldEncrypt()) {
std::string encrypted_value;
- if (!crypto_->EncryptString(po->cc().Value(), &encrypted_value))
+ if (!crypto_->EncryptString(po->cc().Value(), &encrypted_value)) {
+ DLOG(WARNING) << "Could not encrypt a cookie, skipping add.";
+ RecordCookieCommitProblem(COOKIE_COMMIT_PROBLEM_ENCRYPT_FAILED);
+ trouble = true;
continue;
+ }
add_smt.BindCString(3, ""); // value
// BindBlob() immediately makes an internal copy of the data.
add_smt.BindBlob(4, encrypted_value.data(),
@@ -1238,8 +1333,11 @@ void SQLitePersistentCookieStore::Backend::Commit() {
add_smt.BindInt(12, po->cc().IsPersistent());
add_smt.BindInt(13,
CookiePriorityToDBCookiePriority(po->cc().Priority()));
- if (!add_smt.Run())
- NOTREACHED() << "Could not add a cookie to the DB.";
+ if (!add_smt.Run()) {
+ DLOG(WARNING) << "Could not add a cookie to the DB.";
+ RecordCookieCommitProblem(COOKIE_COMMIT_PROBLEM_ADD);
+ trouble = true;
+ }
break;
case PendingOperation::COOKIE_UPDATEACCESS:
@@ -1249,8 +1347,12 @@ void SQLitePersistentCookieStore::Backend::Commit() {
update_access_smt.BindString(1, po->cc().Name());
update_access_smt.BindString(2, po->cc().Domain());
update_access_smt.BindString(3, po->cc().Path());
- if (!update_access_smt.Run())
- NOTREACHED() << "Could not update cookie last access time in the DB.";
+ if (!update_access_smt.Run()) {
+ DLOG(WARNING)
+ << "Could not update cookie last access time in the DB.";
+ RecordCookieCommitProblem(COOKIE_COMMIT_PROBLEM_UPDATE_ACCESS);
+ trouble = true;
+ }
break;
case PendingOperation::COOKIE_DELETE:
@@ -1258,8 +1360,11 @@ void SQLitePersistentCookieStore::Backend::Commit() {
del_smt.BindString(0, po->cc().Name());
del_smt.BindString(1, po->cc().Domain());
del_smt.BindString(2, po->cc().Path());
- if (!del_smt.Run())
- NOTREACHED() << "Could not delete a cookie from the DB.";
+ if (!del_smt.Run()) {
+ DLOG(WARNING) << "Could not delete a cookie from the DB.";
+ RecordCookieCommitProblem(COOKIE_COMMIT_PROBLEM_DELETE);
+ trouble = true;
+ }
break;
default:
@@ -1269,7 +1374,11 @@ void SQLitePersistentCookieStore::Backend::Commit() {
}
bool succeeded = transaction.Commit();
UMA_HISTOGRAM_ENUMERATION("Cookie.BackingStoreUpdateResults",
- succeeded ? 0 : 1, 2);
+ succeeded
+ ? (trouble ? BACKING_STORE_RESULTS_MIXED
+ : BACKING_STORE_RESULTS_SUCCESS)
+ : BACKING_STORE_RESULTS_FAILURE,
+ BACKING_STORE_RESULTS_LAST_ENTRY);
}
void SQLitePersistentCookieStore::Backend::SetBeforeFlushCallback(
diff --git a/chromium/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc b/chromium/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
index d475a451475..8af4c6461d8 100644
--- a/chromium/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
+++ b/chromium/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
@@ -1222,4 +1222,26 @@ TEST_F(SQLitePersistentCookieStoreTest, KeyInconsistency) {
EXPECT_EQ("subdomain.gopheriffic.com", get_callback.cookies()[0].Domain());
};
+TEST_F(SQLitePersistentCookieStoreTest, OpsIfInitFailed) {
+ // Test to make sure we don't leak pending operations when initialization
+ // fails really hard. To inject the failure, we put a directory where the
+ // database file ought to be. This test relies on an external leak checker
+ // (e.g. lsan) to actual catch thing.
+ ASSERT_TRUE(
+ base::CreateDirectory(temp_dir_.GetPath().Append(kCookieFilename)));
+ Create(false, false, true /* want current thread to invoke cookie monster */);
+ std::unique_ptr<CookieMonster> cookie_monster =
+ std::make_unique<CookieMonster>(store_.get());
+
+ ResultSavingCookieCallback<bool> set_cookie_callback;
+ cookie_monster->SetCookieWithOptionsAsync(
+ GURL("http://www.example.com/"), "A=B; max-age=3600", CookieOptions(),
+ base::BindOnce(&ResultSavingCookieCallback<bool>::Run,
+ base::Unretained(&set_cookie_callback)));
+ set_cookie_callback.WaitUntilDone();
+ EXPECT_TRUE(set_cookie_callback.result());
+
+ // Things should commit once going out of scope.
+}
+
} // namespace net
diff --git a/chromium/net/filter/OWNERS b/chromium/net/filter/OWNERS
index c0aa5db0708..54385cf8317 100644
--- a/chromium/net/filter/OWNERS
+++ b/chromium/net/filter/OWNERS
@@ -1,4 +1,3 @@
-rdsmith@chromium.org
xunjieli@chromium.org
# COMPONENT: Internals>Network>Filters
diff --git a/chromium/net/filter/source_stream_type_list.h b/chromium/net/filter/source_stream_type_list.h
index 2a79296e425..cc5079090ef 100644
--- a/chromium/net/filter/source_stream_type_list.h
+++ b/chromium/net/filter/source_stream_type_list.h
@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// This file intentionally does not have header guards, it's included
+// inside a macro to generate values. The following line silences a
+// presubmit warning that would otherwise be triggered by this:
+// no-include-guard-because-multiply-included
+
// Specifies type of filters that can be created. Do not change the values
// of this enum; it is preserved in a histogram.
SOURCE_STREAM_TYPE(BROTLI)
diff --git a/chromium/net/http/bidirectional_stream.cc b/chromium/net/http/bidirectional_stream.cc
index 6e755b4ae80..ffbe1f52ca1 100644
--- a/chromium/net/http/bidirectional_stream.cc
+++ b/chromium/net/http/bidirectional_stream.cc
@@ -29,6 +29,7 @@
#include "net/spdy/core/spdy_header_block.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "net/ssl/ssl_config.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"
namespace net {
@@ -103,10 +104,6 @@ BidirectionalStream::BidirectionalStream(
base::Unretained(&request_info_->extra_headers)));
}
- SSLConfig server_ssl_config;
- session->ssl_config_service()->GetSSLConfig(&server_ssl_config);
- session->GetAlpnProtos(&server_ssl_config.alpn_protos);
-
if (!request_info_->url.SchemeIs(url::kHttpsScheme)) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
@@ -115,22 +112,11 @@ BidirectionalStream::BidirectionalStream(
return;
}
- HttpRequestInfo http_request_info;
- http_request_info.url = request_info_->url;
- http_request_info.method = request_info_->method;
- http_request_info.extra_headers = request_info_->extra_headers;
- http_request_info.socket_tag = request_info_->socket_tag;
- stream_request_ =
- session->http_stream_factory()->RequestBidirectionalStreamImpl(
- http_request_info, request_info_->priority, server_ssl_config,
- server_ssl_config, this,
- /* enable_ip_based_pooling = */ true,
- /* enable_alternative_services = */ true, net_log_);
- // Check that this call cannot fail to set a non-NULL |stream_request_|.
- DCHECK(stream_request_);
- // Check that HttpStreamFactory does not invoke OnBidirectionalStreamImplReady
- // synchronously.
- DCHECK(!stream_impl_);
+ SSLConfig ssl_config;
+ session->ssl_config_service()->GetSSLConfig(&ssl_config);
+ session->GetAlpnProtos(&ssl_config.alpn_protos);
+
+ StartRequest(ssl_config);
}
BidirectionalStream::~BidirectionalStream() {
@@ -219,6 +205,26 @@ void BidirectionalStream::PopulateNetErrorDetails(NetErrorDetails* details) {
stream_impl_->PopulateNetErrorDetails(details);
}
+void BidirectionalStream::StartRequest(const SSLConfig& ssl_config) {
+ DCHECK(!stream_request_);
+ HttpRequestInfo http_request_info;
+ http_request_info.url = request_info_->url;
+ http_request_info.method = request_info_->method;
+ http_request_info.extra_headers = request_info_->extra_headers;
+ http_request_info.socket_tag = request_info_->socket_tag;
+ stream_request_ =
+ session_->http_stream_factory()->RequestBidirectionalStreamImpl(
+ http_request_info, request_info_->priority, ssl_config, ssl_config,
+ this,
+ /* enable_ip_based_pooling = */ true,
+ /* enable_alternative_services = */ true, net_log_);
+ // Check that this call does not fail.
+ DCHECK(stream_request_);
+ // Check that HttpStreamFactory does not invoke OnBidirectionalStreamImplReady
+ // synchronously.
+ DCHECK(!stream_impl_);
+}
+
void BidirectionalStream::OnStreamReady(bool request_headers_sent) {
request_headers_sent_ = request_headers_sent;
if (net_log_.IsCapturing()) {
@@ -329,11 +335,34 @@ void BidirectionalStream::OnBidirectionalStreamImplReady(
std::unique_ptr<BidirectionalStreamImpl> stream) {
DCHECK(!stream_impl_);
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("bidirectional_stream", R"(
+ semantics {
+ sender: "Bidirectional Stream"
+ description:
+ "Bidirectional stream is used to exchange data with a server on "
+ "behalf of an RPC API."
+ trigger:
+ "When an application makes an RPC to the server."
+ data:
+ "Any arbitrary data."
+ destination: OTHER
+ destination_other:
+ "Any destination that the application chooses."
+ }
+ policy {
+ cookies_allowed: NO
+ setting: "This feature is not used in Chrome."
+ policy_exception_justification:
+ "This feature is not used in Chrome."
+ }
+ )");
+
stream_request_.reset();
stream_impl_ = std::move(stream);
stream_impl_->Start(request_info_.get(), net_log_,
send_request_headers_automatically_, this,
- std::move(timer_));
+ std::move(timer_), traffic_annotation);
}
void BidirectionalStream::OnWebSocketHandshakeStreamReady(
@@ -378,7 +407,16 @@ void BidirectionalStream::OnNeedsClientAuth(const SSLConfig& used_ssl_config,
SSLCertRequestInfo* cert_info) {
DCHECK(stream_request_);
- NotifyFailed(ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
+ // BidirectionalStream doesn't support client auth. It ignores client auth
+ // requests with null client cert and key.
+ SSLConfig ssl_config = used_ssl_config;
+ ssl_config.send_client_cert = true;
+ ssl_config.client_cert = nullptr;
+ ssl_config.client_private_key = nullptr;
+ session_->ssl_client_auth_cache()->Add(cert_info->host_and_port, nullptr,
+ nullptr);
+ stream_request_ = nullptr;
+ StartRequest(ssl_config);
}
void BidirectionalStream::OnHttpsProxyTunnelResponse(
diff --git a/chromium/net/http/bidirectional_stream.h b/chromium/net/http/bidirectional_stream.h
index 6fffad72e1a..69f26186c27 100644
--- a/chromium/net/http/bidirectional_stream.h
+++ b/chromium/net/http/bidirectional_stream.h
@@ -19,6 +19,7 @@
#include "net/base/net_export.h"
#include "net/http/bidirectional_stream_impl.h"
#include "net/http/http_stream_factory.h"
+#include "net/http/http_stream_request.h"
#include "net/log/net_log_with_source.h"
namespace net {
@@ -26,7 +27,6 @@ namespace net {
class HttpAuthController;
class HttpNetworkSession;
class HttpStream;
-class HttpStreamRequest;
class IOBuffer;
class ProxyInfo;
class SpdyHeaderBlock;
@@ -176,6 +176,7 @@ class NET_EXPORT BidirectionalStream : public BidirectionalStreamImpl::Delegate,
void PopulateNetErrorDetails(NetErrorDetails* details);
private:
+ void StartRequest(const SSLConfig& ssl_config);
// BidirectionalStreamImpl::Delegate implementation:
void OnStreamReady(bool request_headers_sent) override;
void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override;
diff --git a/chromium/net/http/bidirectional_stream_impl.h b/chromium/net/http/bidirectional_stream_impl.h
index b5228f25fd3..c5f1ee9ff93 100644
--- a/chromium/net/http/bidirectional_stream_impl.h
+++ b/chromium/net/http/bidirectional_stream_impl.h
@@ -15,6 +15,7 @@
#include "net/base/load_timing_info.h"
#include "net/base/net_export.h"
#include "net/socket/next_proto.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace base {
class Timer;
@@ -103,7 +104,8 @@ class NET_EXPORT_PRIVATE BidirectionalStreamImpl {
const NetLogWithSource& net_log,
bool send_request_headers_automatically,
BidirectionalStreamImpl::Delegate* delegate,
- std::unique_ptr<base::Timer> timer) = 0;
+ std::unique_ptr<base::Timer> timer,
+ const NetworkTrafficAnnotationTag& traffic_annotation) = 0;
// Sends request headers to server.
// When |send_request_headers_automatically_| is
diff --git a/chromium/net/http/bidirectional_stream_unittest.cc b/chromium/net/http/bidirectional_stream_unittest.cc
index b78e099fe4c..5d736e96554 100644
--- a/chromium/net/http/bidirectional_stream_unittest.cc
+++ b/chromium/net/http/bidirectional_stream_unittest.cc
@@ -32,6 +32,7 @@
#include "net/socket/socket_test_util.h"
#include "net/spdy/chromium/spdy_session.h"
#include "net/spdy/chromium/spdy_test_util_common.h"
+#include "net/ssl/ssl_cert_request_info.h"
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
@@ -579,6 +580,70 @@ TEST_F(BidirectionalStreamTest,
base::RunLoop().RunUntilIdle();
}
+TEST_F(BidirectionalStreamTest, ClientAuthRequestIgnored) {
+ scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
+ cert_request->host_and_port = host_port_pair_;
+
+ // First attempt receives client auth request.
+ SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
+ ssl_data1.next_proto = kProtoHTTP2;
+ ssl_data1.cert_request_info = cert_request.get();
+
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
+ StaticSocketDataProvider socket_data1(nullptr, 0, nullptr, 0);
+ session_deps_.socket_factory->AddSocketDataProvider(&socket_data1);
+
+ // Second attempt succeeds.
+ SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
+ MockWrite writes[] = {
+ CreateMockWrite(req, 0),
+ };
+ SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
+ SpdySerializedFrame body_frame(spdy_util_.ConstructSpdyDataFrame(1, true));
+ MockRead reads[] = {
+ CreateMockRead(resp, 1), CreateMockRead(body_frame, 2),
+ MockRead(SYNCHRONOUS, net::OK, 3),
+ };
+
+ SSLSocketDataProvider ssl_data2(ASYNC, OK);
+ ssl_data2.next_proto = kProtoHTTP2;
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
+ SequencedSocketData socket_data2(reads, arraysize(reads), writes,
+ arraysize(writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&socket_data2);
+
+ http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
+ SpdySessionKey key(host_port_pair_, ProxyServer::Direct(),
+ PRIVACY_MODE_DISABLED, SocketTag());
+ std::unique_ptr<BidirectionalStreamRequestInfo> request_info(
+ new BidirectionalStreamRequestInfo);
+ request_info->method = "GET";
+ request_info->url = default_url_;
+ request_info->end_stream_on_headers = true;
+ request_info->priority = LOWEST;
+
+ scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
+ std::unique_ptr<TestDelegateBase> delegate(
+ new TestDelegateBase(read_buffer.get(), kReadBufferSize));
+
+ delegate->SetRunUntilCompletion(true);
+ delegate->Start(std::move(request_info), http_session_.get());
+
+ // Ensure the certificate was added to the client auth cache.
+ scoped_refptr<X509Certificate> client_cert;
+ scoped_refptr<SSLPrivateKey> client_private_key;
+ ASSERT_TRUE(http_session_->ssl_client_auth_cache()->Lookup(
+ host_port_pair_, &client_cert, &client_private_key));
+ ASSERT_FALSE(client_cert);
+ ASSERT_FALSE(client_private_key);
+
+ const SpdyHeaderBlock& response_headers = delegate->response_headers();
+ EXPECT_EQ("200", response_headers.find(":status")->second);
+ EXPECT_EQ(1, delegate->on_data_read_count());
+ EXPECT_EQ(0, delegate->on_data_sent_count());
+ EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
+}
+
// Simulates user calling ReadData after END_STREAM has been received in
// BidirectionalStreamSpdyImpl.
TEST_F(BidirectionalStreamTest, TestReadDataAfterClose) {
diff --git a/chromium/net/http/broken_alternative_services.cc b/chromium/net/http/broken_alternative_services.cc
index 04e541f575a..6c57a23af7f 100644
--- a/chromium/net/http/broken_alternative_services.cc
+++ b/chromium/net/http/broken_alternative_services.cc
@@ -30,11 +30,10 @@ base::TimeDelta ComputeBrokenAlternativeServiceExpirationDelay(
} // namespace
-BrokenAlternativeServices::BrokenAlternativeServices(Delegate* delegate,
- base::TickClock* clock)
- : delegate_(delegate),
- clock_(clock),
- weak_ptr_factory_(this) {
+BrokenAlternativeServices::BrokenAlternativeServices(
+ Delegate* delegate,
+ const base::TickClock* clock)
+ : delegate_(delegate), clock_(clock), weak_ptr_factory_(this) {
DCHECK(delegate_);
DCHECK(clock_);
}
@@ -297,4 +296,4 @@ void BrokenAlternativeServices ::
weak_ptr_factory_.GetWeakPtr()));
}
-} // namespace net \ No newline at end of file
+} // namespace net
diff --git a/chromium/net/http/broken_alternative_services.h b/chromium/net/http/broken_alternative_services.h
index f60b6c298a5..16e20ea2ba3 100644
--- a/chromium/net/http/broken_alternative_services.h
+++ b/chromium/net/http/broken_alternative_services.h
@@ -41,7 +41,7 @@ class NET_EXPORT_PRIVATE BrokenAlternativeServices {
// |clock| is used for setting expiration times and scheduling the
// expiration of broken alternative services. It must not be null.
// |delegate| and |clock| are both unowned and must outlive this.
- BrokenAlternativeServices(Delegate* delegate, base::TickClock* clock);
+ BrokenAlternativeServices(Delegate* delegate, const base::TickClock* clock);
BrokenAlternativeServices(const BrokenAlternativeServices&) = delete;
void operator=(const BrokenAlternativeServices&) = delete;
@@ -135,8 +135,8 @@ class NET_EXPORT_PRIVATE BrokenAlternativeServices {
void ExpireBrokenAlternateProtocolMappings();
void ScheduleBrokenAlternateProtocolMappingsExpiration();
- Delegate* delegate_; // Unowned
- base::TickClock* clock_; // Unowned
+ Delegate* delegate_; // Unowned
+ const base::TickClock* clock_; // Unowned
// List of <broken alt svc, expiration time> pairs sorted by expiration time.
BrokenAlternativeServiceList broken_alternative_service_list_;
diff --git a/chromium/net/http/broken_alternative_services_unittest.cc b/chromium/net/http/broken_alternative_services_unittest.cc
index 341419d0d69..05bce72cb7a 100644
--- a/chromium/net/http/broken_alternative_services_unittest.cc
+++ b/chromium/net/http/broken_alternative_services_unittest.cc
@@ -23,7 +23,7 @@ class BrokenAlternativeServicesTest
: test_task_runner_(new base::TestMockTimeTaskRunner()),
test_task_runner_context_(test_task_runner_),
broken_services_clock_(test_task_runner_->GetMockTickClock()),
- broken_services_(this, broken_services_clock_.get()) {}
+ broken_services_(this, broken_services_clock_) {}
// BrokenAlternativeServices::Delegate implementation
void OnExpireBrokenAlternativeService(
@@ -37,7 +37,7 @@ class BrokenAlternativeServicesTest
scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_;
base::TestMockTimeTaskRunner::ScopedContext test_task_runner_context_;
- std::unique_ptr<base::TickClock> broken_services_clock_;
+ const base::TickClock* broken_services_clock_;
BrokenAlternativeServices broken_services_;
std::vector<AlternativeService> expired_alt_svcs_;
@@ -634,4 +634,4 @@ TEST_F(BrokenAlternativeServicesTest, Clear) {
} // namespace
-} // namespace net \ No newline at end of file
+} // namespace net
diff --git a/chromium/net/http/http_auth.h b/chromium/net/http/http_auth.h
index bf63af6e562..e4419e1f675 100644
--- a/chromium/net/http/http_auth.h
+++ b/chromium/net/http/http_auth.h
@@ -88,12 +88,16 @@ class NET_EXPORT_PRIVATE HttpAuth {
IDENT_SRC_DEFAULT_CREDENTIALS,
};
+ // Identifier for auth scheme.
+ //
+ // The values are used for calculating UMA buckets. Add but don't remove or
+ // reuse.
enum Scheme {
AUTH_SCHEME_BASIC = 0,
AUTH_SCHEME_DIGEST,
AUTH_SCHEME_NTLM,
AUTH_SCHEME_NEGOTIATE,
- AUTH_SCHEME_SPDYPROXY,
+ AUTH_SCHEME_SPDYPROXY, // No longer used.
AUTH_SCHEME_MOCK,
AUTH_SCHEME_MAX,
};
diff --git a/chromium/net/http/http_cache.h b/chromium/net/http/http_cache.h
index 0041907e7e5..ebdc8dcf4dd 100644
--- a/chromium/net/http/http_cache.h
+++ b/chromium/net/http/http_cache.h
@@ -189,11 +189,11 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory {
// not changed. This method returns without blocking, and the operation will
// be performed asynchronously without any completion notification.
// Takes ownership of |buf|.
- void WriteMetadata(const GURL& url,
- RequestPriority priority,
- base::Time expected_response_time,
- IOBuffer* buf,
- int buf_len);
+ virtual void WriteMetadata(const GURL& url,
+ RequestPriority priority,
+ base::Time expected_response_time,
+ IOBuffer* buf,
+ int buf_len);
// Get/Set the cache's mode.
void set_mode(Mode value) { mode_ = value; }
diff --git a/chromium/net/http/http_cache_transaction.cc b/chromium/net/http/http_cache_transaction.cc
index 14601307264..10eafcf1e74 100644
--- a/chromium/net/http/http_cache_transaction.cc
+++ b/chromium/net/http/http_cache_transaction.cc
@@ -2510,8 +2510,9 @@ int HttpCache::Transaction::BeginPartialCacheValidation() {
int HttpCache::Transaction::ValidateEntryHeadersAndContinue() {
DCHECK_EQ(mode_, READ_WRITE);
- if (!partial_->UpdateFromStoredHeaders(
- response_.headers.get(), entry_->disk_entry, truncated_)) {
+ if (!partial_->UpdateFromStoredHeaders(response_.headers.get(),
+ entry_->disk_entry, truncated_,
+ cache_->IsWritingInProgress(entry_))) {
return DoRestartPartialRequest();
}
@@ -3156,12 +3157,16 @@ void HttpCache::Transaction::ResetPartialState(bool delete_object) {
if (!delete_object) {
// The simplest way to re-initialize partial_ is to create a new object.
partial_.reset(new PartialData());
- if (partial_->Init(request_->extra_headers))
+
+ // Reset the range header to the original value (http://crbug.com/820599).
+ custom_request_->extra_headers.RemoveHeader(HttpRequestHeaders::kRange);
+ if (partial_->Init(initial_request_->extra_headers))
partial_->SetHeaders(custom_request_->extra_headers);
else
partial_.reset();
}
}
+
void HttpCache::Transaction::ResetNetworkTransaction() {
SaveNetworkTransactionInfo(*network_trans_);
network_trans_.reset();
diff --git a/chromium/net/http/http_cache_unittest.cc b/chromium/net/http/http_cache_unittest.cc
index 83c838d352d..39cb246b238 100644
--- a/chromium/net/http/http_cache_unittest.cc
+++ b/chromium/net/http/http_cache_unittest.cc
@@ -19,6 +19,7 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
+#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@@ -82,6 +83,8 @@ namespace net {
using CacheEntryStatus = HttpResponseInfo::CacheEntryStatus;
+class WebSocketEndpointLockManager;
+
namespace {
// Returns a simple text serialization of the given
@@ -643,7 +646,8 @@ class FakeWebSocketHandshakeStreamCreateHelper
~FakeWebSocketHandshakeStreamCreateHelper() override = default;
std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
std::unique_ptr<ClientSocketHandle> connect,
- bool using_proxy) override {
+ bool using_proxy,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager) override {
return nullptr;
}
std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp2Stream(
@@ -1977,6 +1981,174 @@ TEST(HttpCache, RangeGET_ParallelValidationCacheLockTimeout) {
EXPECT_EQ(1, cache.disk_cache()->create_count());
}
+// Tests a full request and a simultaneous range request and the range request
+// dooms the entry created by the full request due to not being able to
+// conditionalize.
+TEST(HttpCache, RangeGET_ParallelValidationCouldntConditionalize) {
+ MockHttpCache cache;
+
+ MockTransaction mock_transaction(kSimpleGET_Transaction);
+ mock_transaction.url = kRangeGET_TransactionOK.url;
+ ScopedMockTransaction transaction(mock_transaction);
+
+ // Remove the cache-control and other headers so that the response cannot be
+ // conditionalized.
+ transaction.response_headers = "";
+
+ std::vector<std::unique_ptr<Context>> context_list;
+ const int kNumTransactions = 2;
+
+ for (int i = 0; i < kNumTransactions; ++i) {
+ context_list.push_back(std::make_unique<Context>());
+ }
+
+ // Let 1st transaction complete headers phase for no range and read some part
+ // of the response and write in the cache.
+ std::string first_read;
+ MockHttpRequest request1(transaction);
+ {
+ request1.url = GURL(kRangeGET_TransactionOK.url);
+ auto& c = context_list[0];
+ c->result = cache.CreateTransaction(&c->trans);
+ ASSERT_THAT(c->result, IsOk());
+ EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
+
+ c->result =
+ c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
+ base::RunLoop().RunUntilIdle();
+
+ const int kBufferSize = 5;
+ scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
+ ReleaseBufferCompletionCallback cb(buffer.get());
+ c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
+ EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
+
+ std::string data_read(buffer->data(), kBufferSize);
+ first_read = data_read;
+
+ EXPECT_EQ(LOAD_STATE_READING_RESPONSE, c->trans->GetLoadState());
+ }
+
+ // 2nd transaction requests a range.
+ ScopedMockTransaction range_transaction(kRangeGET_TransactionOK);
+ range_transaction.request_headers = "Range: bytes = 0-29\r\n" EXTRA_HEADER;
+ MockHttpRequest request2(range_transaction);
+ {
+ auto& c = context_list[1];
+ c->result = cache.CreateTransaction(&c->trans);
+ ASSERT_THAT(c->result, IsOk());
+ EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
+
+ c->result =
+ c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
+ }
+
+ // The second request would have doomed the 1st entry and created a new entry.
+ EXPECT_EQ(2, cache.network_layer()->transaction_count());
+ EXPECT_EQ(0, cache.disk_cache()->open_count());
+ EXPECT_EQ(2, cache.disk_cache()->create_count());
+
+ for (int i = 0; i < kNumTransactions; ++i) {
+ auto& c = context_list[i];
+ if (c->result == ERR_IO_PENDING)
+ c->result = c->callback.WaitForResult();
+
+ if (i == 0) {
+ ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
+ transaction);
+ continue;
+ }
+ range_transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 ";
+ ReadAndVerifyTransaction(c->trans.get(), range_transaction);
+ }
+}
+
+// Tests a 200 request and a simultaneous range request where conditionalization
+// is possible.
+TEST(HttpCache, RangeGET_ParallelValidationCouldConditionalize) {
+ MockHttpCache cache;
+
+ MockTransaction mock_transaction(kSimpleGET_Transaction);
+ mock_transaction.url = kRangeGET_TransactionOK.url;
+ mock_transaction.data = kFullRangeData;
+ std::string response_headers_str = base::StrCat(
+ {"ETag: StrongOne\n",
+ "Content-Length:", base::IntToString(strlen(kFullRangeData)), "\n"});
+ mock_transaction.response_headers = response_headers_str.c_str();
+
+ ScopedMockTransaction transaction(mock_transaction);
+
+ std::vector<std::unique_ptr<Context>> context_list;
+ const int kNumTransactions = 2;
+
+ for (int i = 0; i < kNumTransactions; ++i) {
+ context_list.push_back(std::make_unique<Context>());
+ }
+
+ // Let 1st transaction complete headers phase for no range and read some part
+ // of the response and write in the cache.
+ std::string first_read;
+ MockHttpRequest request1(transaction);
+ {
+ request1.url = GURL(kRangeGET_TransactionOK.url);
+ auto& c = context_list[0];
+ c->result = cache.CreateTransaction(&c->trans);
+ ASSERT_THAT(c->result, IsOk());
+ EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
+
+ c->result =
+ c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
+ base::RunLoop().RunUntilIdle();
+
+ const int kBufferSize = 5;
+ scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
+ ReleaseBufferCompletionCallback cb(buffer.get());
+ c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
+ EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
+
+ std::string data_read(buffer->data(), kBufferSize);
+ first_read = data_read;
+
+ EXPECT_EQ(LOAD_STATE_READING_RESPONSE, c->trans->GetLoadState());
+ }
+
+ // 2nd transaction requests a range.
+ ScopedMockTransaction range_transaction(kRangeGET_TransactionOK);
+ range_transaction.request_headers = "Range: bytes = 0-29\r\n" EXTRA_HEADER;
+ MockHttpRequest request2(range_transaction);
+ {
+ auto& c = context_list[1];
+ c->result = cache.CreateTransaction(&c->trans);
+ ASSERT_THAT(c->result, IsOk());
+ EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
+
+ c->result =
+ c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
+ }
+
+ EXPECT_EQ(2, cache.network_layer()->transaction_count());
+ EXPECT_EQ(0, cache.disk_cache()->open_count());
+ EXPECT_EQ(1, cache.disk_cache()->create_count());
+
+ // Finish and verify the first request.
+ auto& c0 = context_list[0];
+ c0->result = c0->callback.WaitForResult();
+ ReadRemainingAndVerifyTransaction(c0->trans.get(), first_read, transaction);
+
+ // And the second.
+ auto& c1 = context_list[1];
+ c1->result = c1->callback.WaitForResult();
+
+ range_transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 ";
+ ReadAndVerifyTransaction(c1->trans.get(), range_transaction);
+}
+
// Tests parallel validation on range requests with overlapping ranges.
TEST(HttpCache, RangeGET_ParallelValidationOverlappingRanges) {
MockHttpCache cache;
diff --git a/chromium/net/http/http_cache_writers.cc b/chromium/net/http/http_cache_writers.cc
index 6bf0074be18..1ab3fbbcd79 100644
--- a/chromium/net/http/http_cache_writers.cc
+++ b/chromium/net/http/http_cache_writers.cc
@@ -283,6 +283,11 @@ bool HttpCache::Writers::ShouldTruncate() {
return false;
}
+ if (response_info_truncation_.headers->HasHeader("Content-Encoding")) {
+ should_keep_entry_ = false;
+ return false;
+ }
+
int64_t content_length =
response_info_truncation_.headers->GetContentLength();
if (content_length >= 0 && content_length <= current_size)
diff --git a/chromium/net/http/http_cache_writers_unittest.cc b/chromium/net/http/http_cache_writers_unittest.cc
index c386a625432..86a943b2765 100644
--- a/chromium/net/http/http_cache_writers_unittest.cc
+++ b/chromium/net/http/http_cache_writers_unittest.cc
@@ -106,7 +106,8 @@ class WritersTest : public testing::Test {
void CreateWritersAddTransaction(
HttpCache::ParallelWritingPattern parallel_writing_pattern_ =
- HttpCache::PARALLEL_WRITING_JOIN) {
+ HttpCache::PARALLEL_WRITING_JOIN,
+ bool content_encoding_present = false) {
TestCompletionCallback callback;
// Create and Start a mock network transaction.
@@ -116,6 +117,8 @@ class WritersTest : public testing::Test {
NetLogWithSource());
base::RunLoop().RunUntilIdle();
response_info_ = *(network_transaction->GetResponseInfo());
+ if (content_encoding_present)
+ response_info_.headers->AddHeader("Content-Encoding: gzip");
// Create a mock cache transaction.
std::unique_ptr<TestHttpCacheTransaction> transaction =
@@ -188,6 +191,28 @@ class WritersTest : public testing::Test {
return OK;
}
+ int ReadFewBytes(std::string* result) {
+ EXPECT_TRUE(transactions_.size() >= (size_t)1);
+ TestHttpCacheTransaction* transaction = transactions_.begin()->get();
+ TestCompletionCallback callback;
+
+ std::string content;
+ int rv = 0;
+ scoped_refptr<IOBuffer> buf(new IOBuffer(5));
+ rv = writers_->Read(buf.get(), 5, callback.callback(), transaction);
+ if (rv == ERR_IO_PENDING) {
+ rv = callback.WaitForResult();
+ base::RunLoop().RunUntilIdle();
+ }
+
+ if (rv > 0)
+ result->append(buf->data(), rv);
+ else if (rv < 0)
+ return rv;
+
+ return OK;
+ }
+
void ReadVerifyTwoDifferentBufferLengths(
const std::vector<int>& buffer_lengths) {
EXPECT_EQ(2u, buffer_lengths.size());
@@ -782,4 +807,17 @@ TEST_F(WritersTest, StopCachingWithNotKeepEntry) {
EXPECT_FALSE(ShouldKeepEntry());
}
+// Tests that if content-encoding is set, the entry should not be marked as
+// truncated, since we should not be creating range requests for compressed
+// entries.
+TEST_F(WritersTest, ContentEncodingShouldNotTruncate) {
+ CreateWritersAddTransaction(HttpCache::PARALLEL_WRITING_JOIN,
+ true /* content_encoding_present */);
+ std::string result;
+ ReadFewBytes(&result);
+
+ EXPECT_FALSE(ShouldTruncate());
+ EXPECT_FALSE(ShouldKeepEntry());
+}
+
} // namespace net
diff --git a/chromium/net/http/http_network_layer_unittest.cc b/chromium/net/http/http_network_layer_unittest.cc
index 818ed2aaa11..c563937c6ad 100644
--- a/chromium/net/http/http_network_layer_unittest.cc
+++ b/chromium/net/http/http_network_layer_unittest.cc
@@ -16,7 +16,7 @@
#include "net/http/http_transaction_test_util.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log_with_source.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/socket/socket_test_util.h"
#include "net/spdy/chromium/spdy_session_pool.h"
#include "net/ssl/ssl_config_service_defaults.h"
diff --git a/chromium/net/http/http_network_session.cc b/chromium/net/http/http_network_session.cc
index 4df631d4732..3d2662a38de 100644
--- a/chromium/net/http/http_network_session.cc
+++ b/chromium/net/http/http_network_session.cc
@@ -20,12 +20,11 @@
#include "base/trace_event/memory_dump_request_args.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/values.h"
-#include "net/base/network_throttle_manager_impl.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_response_body_drainer.h"
#include "net/http/http_stream_factory_impl.h"
#include "net/http/url_security_manager.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/quic/chromium/quic_crypto_client_stream_factory.h"
#include "net/quic/chromium/quic_stream_factory.h"
#include "net/quic/core/crypto/quic_random.h"
@@ -37,6 +36,7 @@
#include "net/socket/client_socket_pool_manager_impl.h"
#include "net/socket/next_proto.h"
#include "net/socket/ssl_client_socket.h"
+#include "net/socket/websocket_endpoint_lock_manager.h"
#include "net/spdy/chromium/spdy_session_pool.h"
namespace net {
@@ -48,7 +48,8 @@ base::AtomicSequenceNumber g_next_shard_id;
std::unique_ptr<ClientSocketPoolManager> CreateSocketPoolManager(
HttpNetworkSession::SocketPoolType pool_type,
const HttpNetworkSession::Context& context,
- const std::string& ssl_session_cache_shard) {
+ const std::string& ssl_session_cache_shard,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager) {
// TODO(yutak): Differentiate WebSocket pool manager and allow more
// simultaneous connections for WebSockets.
return std::make_unique<ClientSocketPoolManagerImpl>(
@@ -60,7 +61,7 @@ std::unique_ptr<ClientSocketPoolManager> CreateSocketPoolManager(
context.cert_verifier, context.channel_id_service,
context.transport_security_state, context.cert_transparency_verifier,
context.ct_policy_enforcer, ssl_session_cache_shard,
- context.ssl_config_service, pool_type);
+ context.ssl_config_service, websocket_endpoint_lock_manager, pool_type);
}
} // unnamed namespace
@@ -113,7 +114,7 @@ HttpNetworkSession::Params::Params()
quic_max_server_configs_stored_in_properties(0u),
quic_enable_socket_recv_optimization(false),
mark_quic_broken_when_network_blackholes(false),
- retry_without_alt_svc_on_quic_errors(false),
+ retry_without_alt_svc_on_quic_errors(true),
support_ietf_format_quic_altsvc(false),
quic_close_sessions_on_ip_change(false),
quic_idle_connection_timeout_seconds(kIdleConnectionTimeoutSeconds),
@@ -181,6 +182,8 @@ HttpNetworkSession::HttpNetworkSession(const Params& params,
http_auth_handler_factory_(context.http_auth_handler_factory),
proxy_resolution_service_(context.proxy_resolution_service),
ssl_config_service_(context.ssl_config_service),
+ websocket_endpoint_lock_manager_(
+ std::make_unique<WebSocketEndpointLockManager>()),
push_delegate_(nullptr),
quic_stream_factory_(
context.net_log,
@@ -235,7 +238,6 @@ HttpNetworkSession::HttpNetworkSession(const Params& params,
AddDefaultHttp2Settings(params.http2_settings),
params.time_func),
http_stream_factory_(std::make_unique<HttpStreamFactoryImpl>(this)),
- network_stream_throttler_(std::make_unique<NetworkThrottleManagerImpl>()),
params_(params),
context_(context) {
DCHECK(proxy_resolution_service_);
@@ -245,9 +247,11 @@ HttpNetworkSession::HttpNetworkSession(const Params& params,
const std::string ssl_session_cache_shard =
"http_network_session/" + base::IntToString(g_next_shard_id.GetNext());
normal_socket_pool_manager_ = CreateSocketPoolManager(
- NORMAL_SOCKET_POOL, context, ssl_session_cache_shard);
+ NORMAL_SOCKET_POOL, context, ssl_session_cache_shard,
+ websocket_endpoint_lock_manager_.get());
websocket_socket_pool_manager_ = CreateSocketPoolManager(
- WEBSOCKET_SOCKET_POOL, context, ssl_session_cache_shard);
+ WEBSOCKET_SOCKET_POOL, context, ssl_session_cache_shard,
+ websocket_endpoint_lock_manager_.get());
if (params_.enable_http2) {
next_protos_.push_back(kProtoHTTP2);
diff --git a/chromium/net/http/http_network_session.h b/chromium/net/http/http_network_session.h
index 5500de3a033..7c1b196d131 100644
--- a/chromium/net/http/http_network_session.h
+++ b/chromium/net/http/http_network_session.h
@@ -57,7 +57,6 @@ class HttpResponseBodyDrainer;
class HttpServerProperties;
class NetLog;
class NetworkQualityProvider;
-class NetworkThrottleManager;
class ProxyDelegate;
class ProxyResolutionService;
class QuicClock;
@@ -68,6 +67,7 @@ class SSLClientSocketPool;
class SSLConfigService;
class TransportClientSocketPool;
class TransportSecurityState;
+class WebSocketEndpointLockManager;
// Specifies the maximum HPACK dynamic table size the server is allowed to set.
const uint32_t kSpdyMaxHeaderTableSize = 64 * 1024;
@@ -285,6 +285,9 @@ class NET_EXPORT HttpNetworkSession : public base::MemoryCoordinatorClient {
return proxy_resolution_service_;
}
SSLConfigService* ssl_config_service() { return ssl_config_service_.get(); }
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager() {
+ return websocket_endpoint_lock_manager_.get();
+ }
SpdySessionPool* spdy_session_pool() { return &spdy_session_pool_; }
QuicStreamFactory* quic_stream_factory() { return &quic_stream_factory_; }
HttpAuthHandlerFactory* http_auth_handler_factory() {
@@ -296,9 +299,6 @@ class NET_EXPORT HttpNetworkSession : public base::MemoryCoordinatorClient {
HttpStreamFactory* http_stream_factory() {
return http_stream_factory_.get();
}
- NetworkThrottleManager* throttler() {
- return network_stream_throttler_.get();
- }
NetLog* net_log() {
return net_log_;
}
@@ -362,12 +362,13 @@ class NET_EXPORT HttpNetworkSession : public base::MemoryCoordinatorClient {
CertVerifier* const cert_verifier_;
HttpAuthHandlerFactory* const http_auth_handler_factory_;
- // Not const since it's modified by HttpNetworkSessionPeer for testing.
- ProxyResolutionService* proxy_resolution_service_;
+ ProxyResolutionService* const proxy_resolution_service_;
const scoped_refptr<SSLConfigService> ssl_config_service_;
HttpAuthCache http_auth_cache_;
SSLClientAuthCache ssl_client_auth_cache_;
+ std::unique_ptr<WebSocketEndpointLockManager>
+ websocket_endpoint_lock_manager_;
std::unique_ptr<ClientSocketPoolManager> normal_socket_pool_manager_;
std::unique_ptr<ClientSocketPoolManager> websocket_socket_pool_manager_;
std::unique_ptr<ServerPushDelegate> push_delegate_;
@@ -376,8 +377,6 @@ class NET_EXPORT HttpNetworkSession : public base::MemoryCoordinatorClient {
std::unique_ptr<HttpStreamFactory> http_stream_factory_;
std::map<HttpResponseBodyDrainer*, std::unique_ptr<HttpResponseBodyDrainer>>
response_drainers_;
- std::unique_ptr<NetworkThrottleManager> network_stream_throttler_;
-
NextProtoVector next_protos_;
Params params_;
diff --git a/chromium/net/http/http_network_session_peer.cc b/chromium/net/http/http_network_session_peer.cc
index d132611b91d..bfcc592ad2c 100644
--- a/chromium/net/http/http_network_session_peer.cc
+++ b/chromium/net/http/http_network_session_peer.cc
@@ -4,9 +4,8 @@
#include "net/http/http_network_session_peer.h"
-#include "net/base/network_throttle_manager.h"
#include "net/http/http_proxy_client_socket_pool.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/socket/client_socket_pool_manager.h"
#include "net/socket/socks_client_socket_pool.h"
#include "net/socket/ssl_client_socket_pool.h"
@@ -29,11 +28,6 @@ void HttpNetworkSessionPeer::SetHttpStreamFactory(
session_->http_stream_factory_.swap(http_stream_factory);
}
-void HttpNetworkSessionPeer::SetNetworkStreamThrottler(
- std::unique_ptr<NetworkThrottleManager> network_throttle_manager) {
- session_->network_stream_throttler_.swap(network_throttle_manager);
-}
-
HttpNetworkSession::Params* HttpNetworkSessionPeer::params() {
return &(session_->params_);
}
diff --git a/chromium/net/http/http_network_session_peer.h b/chromium/net/http/http_network_session_peer.h
index bb0d0c7dce3..b173f5de684 100644
--- a/chromium/net/http/http_network_session_peer.h
+++ b/chromium/net/http/http_network_session_peer.h
@@ -16,7 +16,6 @@ namespace net {
class ClientSocketPoolManager;
class HttpStreamFactory;
-class NetworkThrottleManager;
class NET_EXPORT_PRIVATE HttpNetworkSessionPeer {
public:
@@ -30,9 +29,6 @@ class NET_EXPORT_PRIVATE HttpNetworkSessionPeer {
void SetHttpStreamFactory(
std::unique_ptr<HttpStreamFactory> http_stream_factory);
- void SetNetworkStreamThrottler(
- std::unique_ptr<NetworkThrottleManager> network_throttle_manager);
-
HttpNetworkSession::Params* params();
private:
diff --git a/chromium/net/http/http_network_transaction.cc b/chromium/net/http/http_network_transaction.cc
index 98f52f6a5dc..9d96d1a83cf 100644
--- a/chromium/net/http/http_network_transaction.cc
+++ b/chromium/net/http/http_network_transaction.cc
@@ -15,6 +15,7 @@
#include "base/compiler_specific.h"
#include "base/format_macros.h"
#include "base/metrics/field_trial.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h"
#include "base/stl_util.h"
@@ -112,7 +113,8 @@ HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority,
websocket_handshake_stream_base_create_helper_(NULL),
net_error_details_(),
retry_attempts_(0),
- num_restarts_(0) {}
+ num_restarts_(0),
+ ssl_version_interference_error_(OK) {}
HttpNetworkTransaction::~HttpNetworkTransaction() {
if (stream_.get()) {
@@ -150,14 +152,14 @@ int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info,
proxy_ssl_config_.rev_checking_enabled = false;
}
- if (request_info->method != "POST") {
+ if (HttpUtil::IsMethodSafe(request_info->method)) {
can_send_early_data_ = true;
}
if (request_->load_flags & LOAD_PREFETCH)
response_.unused_since_prefetch = true;
- next_state_ = STATE_THROTTLE;
+ next_state_ = STATE_NOTIFY_BEFORE_CREATE_STREAM;
int rv = DoLoop(OK);
if (rv == ERR_IO_PENDING)
callback_ = callback;
@@ -389,8 +391,6 @@ LoadState HttpNetworkTransaction::GetLoadState() const {
// TODO(wtc): Define a new LoadState value for the
// STATE_INIT_CONNECTION_COMPLETE state, which delays the HTTP request.
switch (next_state_) {
- case STATE_THROTTLE_COMPLETE:
- return LOAD_STATE_THROTTLED;
case STATE_CREATE_STREAM:
return LOAD_STATE_WAITING_FOR_DELEGATE;
case STATE_CREATE_STREAM_COMPLETE:
@@ -442,23 +442,11 @@ void HttpNetworkTransaction::PopulateNetErrorDetails(
void HttpNetworkTransaction::SetPriority(RequestPriority priority) {
priority_ = priority;
- // TODO(rdsmith): Note that if any code indirectly executed by
- // |stream_request_->SetPriority()| or |stream_->SetPriority()|
- // ever implements a throttling mechanism where changing a request's
- // priority may cause a this or another request to synchronously succeed
- // or fail, that callback could synchronously delete |*this|, causing
- // a crash on return to this code.
- //
- // |throttle_->SetPriority()| has exactly the above attributes, which
- // is why it's the last call in this function.
-
if (stream_request_)
stream_request_->SetPriority(priority);
if (stream_)
stream_->SetPriority(priority);
- if (throttle_)
- throttle_->SetPriority(priority);
// The above call may have resulted in deleting |*this|.
}
@@ -640,18 +628,6 @@ void HttpNetworkTransaction::GetConnectionAttempts(
*out = connection_attempts_;
}
-void HttpNetworkTransaction::OnThrottleUnblocked(
- NetworkThrottleManager::Throttle* throttle) {
- // TODO(rdsmith): This DCHECK is dependent on the only transition
- // being from blocked->unblocked. That is true right now, but may not
- // be so in the future.
- DCHECK_EQ(STATE_THROTTLE_COMPLETE, next_state_);
-
- net_log_.EndEvent(NetLogEventType::HTTP_TRANSACTION_THROTTLED);
-
- DoLoop(OK);
-}
-
bool HttpNetworkTransaction::IsSecureRequest() const {
return request_->url.SchemeIsCryptographic();
}
@@ -720,14 +696,6 @@ int HttpNetworkTransaction::DoLoop(int result) {
State state = next_state_;
next_state_ = STATE_NONE;
switch (state) {
- case STATE_THROTTLE:
- DCHECK_EQ(OK, rv);
- rv = DoThrottle();
- break;
- case STATE_THROTTLE_COMPLETE:
- DCHECK_EQ(OK, rv);
- rv = DoThrottleComplete();
- break;
case STATE_NOTIFY_BEFORE_CREATE_STREAM:
DCHECK_EQ(OK, rv);
rv = DoNotifyBeforeCreateStream();
@@ -843,29 +811,6 @@ int HttpNetworkTransaction::DoLoop(int result) {
return rv;
}
-int HttpNetworkTransaction::DoThrottle() {
- DCHECK(!throttle_);
- throttle_ = session_->throttler()->CreateThrottle(
- this, priority_, (request_->load_flags & LOAD_IGNORE_LIMITS) != 0);
- next_state_ = STATE_THROTTLE_COMPLETE;
-
- if (throttle_->IsBlocked()) {
- net_log_.BeginEvent(NetLogEventType::HTTP_TRANSACTION_THROTTLED);
- return ERR_IO_PENDING;
- }
-
- return OK;
-}
-
-int HttpNetworkTransaction::DoThrottleComplete() {
- DCHECK(throttle_);
- DCHECK(!throttle_->IsBlocked());
-
- next_state_ = STATE_NOTIFY_BEFORE_CREATE_STREAM;
-
- return OK;
-}
-
int HttpNetworkTransaction::DoNotifyBeforeCreateStream() {
next_state_ = STATE_CREATE_STREAM;
bool defer = false;
@@ -901,6 +846,9 @@ int HttpNetworkTransaction::DoCreateStream() {
}
int HttpNetworkTransaction::DoCreateStreamComplete(int result) {
+ // Version interference probes should not result in success.
+ DCHECK(!server_ssl_config_.version_interference_probe || result != OK);
+
// If |result| is ERR_HTTPS_PROXY_TUNNEL_RESPONSE, then
// DoCreateStreamComplete is being called from OnHttpsProxyTunnelResponse,
// which resets the stream request first. Therefore, we have to grab the
@@ -922,6 +870,41 @@ int HttpNetworkTransaction::DoCreateStreamComplete(int result) {
return HandleHttp11Required(result);
}
+ // Perform a TLS 1.3 version interference probe on various connection
+ // errors. The retry will never produce a successful connection but may map
+ // errors to ERR_SSL_VERSION_INTERFERENCE, which signals a probable
+ // version-interfering middlebox.
+ if (IsSecureRequest() && !HasExceededMaxRetries() &&
+ server_ssl_config_.version_max == SSL_PROTOCOL_VERSION_TLS1_3 &&
+ !server_ssl_config_.version_interference_probe) {
+ if (result == ERR_CONNECTION_CLOSED || result == ERR_SSL_PROTOCOL_ERROR ||
+ result == ERR_SSL_VERSION_OR_CIPHER_MISMATCH ||
+ result == ERR_CONNECTION_RESET ||
+ result == ERR_SSL_BAD_RECORD_MAC_ALERT) {
+ // Report the error code for each time a version interference probe is
+ // triggered.
+ base::UmaHistogramSparse("Net.SSLVersionInterferenceProbeTrigger",
+ std::abs(result));
+ net_log_.AddEventWithNetErrorCode(
+ NetLogEventType::SSL_VERSION_INTERFERENCE_PROBE, result);
+
+ retry_attempts_++;
+ server_ssl_config_.version_interference_probe = true;
+ server_ssl_config_.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
+ ssl_version_interference_error_ = result;
+ ResetConnectionAndRequestForResend();
+ return OK;
+ }
+ }
+
+ if (result == ERR_SSL_VERSION_INTERFERENCE) {
+ // Record the error code version interference was detected at.
+ DCHECK(server_ssl_config_.version_interference_probe);
+ DCHECK_NE(OK, ssl_version_interference_error_);
+ base::UmaHistogramSparse("Net.SSLVersionInterferenceError",
+ std::abs(ssl_version_interference_error_));
+ }
+
// Handle possible client certificate errors that may have occurred if the
// stream used SSL for one or more of the layers.
result = HandleSSLClientAuthError(result);
diff --git a/chromium/net/http/http_network_transaction.h b/chromium/net/http/http_network_transaction.h
index 64f4ee8fc70..9f3e95e28ee 100644
--- a/chromium/net/http/http_network_transaction.h
+++ b/chromium/net/http/http_network_transaction.h
@@ -17,15 +17,15 @@
#include "crypto/ec_private_key.h"
#include "net/base/net_error_details.h"
#include "net/base/net_export.h"
-#include "net/base/network_throttle_manager.h"
#include "net/base/request_priority.h"
#include "net/http/http_auth.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_info.h"
#include "net/http/http_stream_factory.h"
+#include "net/http/http_stream_request.h"
#include "net/http/http_transaction.h"
#include "net/log/net_log_with_source.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/socket/connection_attempts.h"
#include "net/ssl/channel_id_service.h"
#include "net/ssl/ssl_config_service.h"
@@ -41,7 +41,6 @@ class BidirectionalStreamImpl;
class HttpAuthController;
class HttpNetworkSession;
class HttpStream;
-class HttpStreamRequest;
class IOBuffer;
class ProxyInfo;
class SSLPrivateKey;
@@ -49,8 +48,7 @@ struct HttpRequestInfo;
class NET_EXPORT_PRIVATE HttpNetworkTransaction
: public HttpTransaction,
- public HttpStreamRequest::Delegate,
- public NetworkThrottleManager::ThrottleDelegate {
+ public HttpStreamRequest::Delegate {
public:
HttpNetworkTransaction(RequestPriority priority,
HttpNetworkSession* session);
@@ -127,11 +125,10 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
void OnQuicBroken() override;
void GetConnectionAttempts(ConnectionAttempts* out) const override;
- // NetworkThrottleManager::Delegate methods:
- void OnThrottleUnblocked(NetworkThrottleManager::Throttle* throttle) override;
-
private:
FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, ResetStateForRestart);
+ FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
+ CreateWebSocketHandshakeStream);
FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateReceived);
FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateSent);
FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateOverflow);
@@ -142,8 +139,6 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
FlowControlNegativeSendWindowSize);
enum State {
- STATE_THROTTLE,
- STATE_THROTTLE_COMPLETE,
STATE_NOTIFY_BEFORE_CREATE_STREAM,
STATE_CREATE_STREAM,
STATE_CREATE_STREAM_COMPLETE,
@@ -190,8 +185,6 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
// argument receive the result from the previous state. If a method returns
// ERR_IO_PENDING, then the result from OnIOComplete will be passed to the
// next state method as the result arg.
- int DoThrottle();
- int DoThrottleComplete();
int DoNotifyBeforeCreateStream();
int DoCreateStream();
int DoCreateStreamComplete(int result);
@@ -300,8 +293,6 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
// Returns true if this transaction is for a WebSocket handshake
bool ForWebSocketHandshake() const;
- void SetStream(HttpStream* stream);
-
void CopyConnectionAttemptsFromStreamRequest();
// Returns true if response "Content-Encoding" headers respect
@@ -347,6 +338,13 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
// SSLClientAuthCache, rather than provided externally by the caller.
bool server_ssl_client_cert_was_cached_;
+ // SSL configuration used for the server and proxy, respectively. Note
+ // |server_ssl_config_| may be updated from the HttpStreamFactory, which will
+ // be applied on retry.
+ //
+ // TODO(davidben): Mutating it is weird and relies on HttpStreamFactory
+ // modifications being idempotent. Address this as part of other work to make
+ // sense of SSLConfig (related to https://crbug.com/488043).
SSLConfig server_ssl_config_;
SSLConfig proxy_ssl_config_;
@@ -414,10 +412,6 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
// Network error details for this transaction.
NetErrorDetails net_error_details_;
- // Communicate lifetime of transaction to the throttler, and
- // throttled state to the transaction.
- std::unique_ptr<NetworkThrottleManager::Throttle> throttle_;
-
// Number of retries made for network errors like ERR_SPDY_PING_FAILED,
// ERR_SPDY_SERVER_REFUSED_STREAM, ERR_QUIC_HANDSHAKE_FAILED and
// ERR_QUIC_PROTOCOL_ERROR. Currently we stop after 3 tries
@@ -430,6 +424,10 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
// Number of times the transaction was restarted via a RestartWith* call.
size_t num_restarts_;
+ // The net::Error which triggered a TLS 1.3 version interference probe, or OK
+ // if none was triggered.
+ int ssl_version_interference_error_;
+
DISALLOW_COPY_AND_ASSIGN(HttpNetworkTransaction);
};
diff --git a/chromium/net/http/http_network_transaction_ssl_unittest.cc b/chromium/net/http/http_network_transaction_ssl_unittest.cc
index e0657bc52e4..b2a63a4494c 100644
--- a/chromium/net/http/http_network_transaction_ssl_unittest.cc
+++ b/chromium/net/http/http_network_transaction_ssl_unittest.cc
@@ -23,7 +23,7 @@
#include "net/http/http_server_properties_impl.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log_with_source.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/socket/socket_test_util.h"
#include "net/ssl/default_channel_id_store.h"
#include "net/test/gtest_util.h"
diff --git a/chromium/net/http/http_network_transaction_unittest.cc b/chromium/net/http/http_network_transaction_unittest.cc
index 54b4ebc7888..50e2a8a4260 100644
--- a/chromium/net/http/http_network_transaction_unittest.cc
+++ b/chromium/net/http/http_network_transaction_unittest.cc
@@ -37,7 +37,6 @@
#include "net/base/load_timing_info.h"
#include "net/base/load_timing_info_test_util.h"
#include "net/base/net_errors.h"
-#include "net/base/network_throttle_manager.h"
#include "net/base/proxy_delegate.h"
#include "net/base/proxy_server.h"
#include "net/base/request_priority.h"
@@ -72,9 +71,9 @@
#include "net/proxy_resolution/mock_proxy_resolver.h"
#include "net/proxy_resolution/proxy_config_service_fixed.h"
#include "net/proxy_resolution/proxy_info.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/proxy_resolution/proxy_resolver.h"
#include "net/proxy_resolution/proxy_resolver_factory.h"
-#include "net/proxy_resolution/proxy_service.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/client_socket_pool.h"
#include "net/socket/client_socket_pool_manager.h"
@@ -91,7 +90,6 @@
#include "net/ssl/default_channel_id_store.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "net/ssl/ssl_config_service.h"
-#include "net/ssl/ssl_config_service_defaults.h"
#include "net/ssl/ssl_info.h"
#include "net/ssl/ssl_private_key.h"
#include "net/test/cert_test_util.h"
@@ -122,105 +120,6 @@ namespace net {
namespace {
-class TestNetworkStreamThrottler : public NetworkThrottleManager {
- public:
- TestNetworkStreamThrottler()
- : throttle_new_requests_(false),
- num_set_priority_calls_(0),
- last_priority_set_(IDLE) {}
-
- ~TestNetworkStreamThrottler() override {
- EXPECT_TRUE(outstanding_throttles_.empty());
- }
-
- // NetworkThrottleManager
- std::unique_ptr<Throttle> CreateThrottle(ThrottleDelegate* delegate,
- RequestPriority priority,
- bool ignore_limits) override {
- auto test_throttle =
- std::make_unique<TestThrottle>(throttle_new_requests_, delegate, this);
- outstanding_throttles_.insert(test_throttle.get());
- return std::move(test_throttle);
- }
-
- void UnthrottleAllRequests() {
- std::set<TestThrottle*> outstanding_throttles_copy(outstanding_throttles_);
- for (auto* throttle : outstanding_throttles_copy) {
- if (throttle->IsBlocked())
- throttle->Unthrottle();
- }
- }
-
- void set_throttle_new_requests(bool throttle_new_requests) {
- throttle_new_requests_ = throttle_new_requests;
- }
-
- // Includes both throttled and unthrottled throttles.
- size_t num_outstanding_requests() const {
- return outstanding_throttles_.size();
- }
-
- int num_set_priority_calls() const { return num_set_priority_calls_; }
- RequestPriority last_priority_set() const { return last_priority_set_; }
- void set_priority_change_closure(
- const base::Closure& priority_change_closure) {
- priority_change_closure_ = priority_change_closure;
- }
-
- private:
- class TestThrottle : public NetworkThrottleManager::Throttle {
- public:
- ~TestThrottle() override { throttler_->OnThrottleDestroyed(this); }
-
- // Throttle
- bool IsBlocked() const override { return throttled_; }
- RequestPriority Priority() const override {
- NOTREACHED();
- return IDLE;
- }
- void SetPriority(RequestPriority priority) override {
- throttler_->SetPriorityCalled(priority);
- }
-
- TestThrottle(bool throttled,
- ThrottleDelegate* delegate,
- TestNetworkStreamThrottler* throttler)
- : throttled_(throttled), delegate_(delegate), throttler_(throttler) {}
-
- void Unthrottle() {
- EXPECT_TRUE(throttled_);
-
- throttled_ = false;
- delegate_->OnThrottleUnblocked(this);
- }
-
- bool throttled_;
- ThrottleDelegate* delegate_;
- TestNetworkStreamThrottler* throttler_;
- };
-
- void OnThrottleDestroyed(TestThrottle* throttle) {
- EXPECT_NE(0u, outstanding_throttles_.count(throttle));
- outstanding_throttles_.erase(throttle);
- }
-
- void SetPriorityCalled(RequestPriority priority) {
- ++num_set_priority_calls_;
- last_priority_set_ = priority;
- if (!priority_change_closure_.is_null())
- priority_change_closure_.Run();
- }
-
- // Includes both throttled and unthrottled throttles.
- std::set<TestThrottle*> outstanding_throttles_;
- bool throttle_new_requests_;
- int num_set_priority_calls_;
- RequestPriority last_priority_set_;
- base::Closure priority_change_closure_;
-
- DISALLOW_COPY_AND_ASSIGN(TestNetworkStreamThrottler);
-};
-
const base::string16 kBar(ASCIIToUTF16("bar"));
const base::string16 kBar2(ASCIIToUTF16("bar2"));
const base::string16 kBar3(ASCIIToUTF16("bar3"));
@@ -360,37 +259,31 @@ std::unique_ptr<HttpNetworkSession> CreateSession(
return SpdySessionDependencies::SpdyCreateSession(session_deps);
}
-// Note that the pointer written into |*throttler| will only be valid
-// for the lifetime of the returned HttpNetworkSession.
-std::unique_ptr<HttpNetworkSession> CreateSessionWithThrottler(
- SpdySessionDependencies* session_deps,
- TestNetworkStreamThrottler** throttler) {
- std::unique_ptr<HttpNetworkSession> session(
- SpdySessionDependencies::SpdyCreateSession(session_deps));
-
- auto owned_throttler = std::make_unique<TestNetworkStreamThrottler>();
- *throttler = owned_throttler.get();
-
- HttpNetworkSessionPeer peer(session.get());
- peer.SetNetworkStreamThrottler(std::move(owned_throttler));
-
- return session;
-}
-
class FailingProxyResolverFactory : public ProxyResolverFactory {
public:
FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
// ProxyResolverFactory override.
- int CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& script_data,
- std::unique_ptr<ProxyResolver>* result,
- const CompletionCallback& callback,
- std::unique_ptr<Request>* request) override {
+ int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
+ std::unique_ptr<ProxyResolver>* result,
+ const CompletionCallback& callback,
+ std::unique_ptr<Request>* request) override {
return ERR_PAC_SCRIPT_FAILED;
}
};
+class TestSSLConfigService : public SSLConfigService {
+ public:
+ explicit TestSSLConfigService(const SSLConfig& config) : config_(config) {}
+
+ void GetSSLConfig(SSLConfig* config) override { *config = config_; }
+
+ private:
+ ~TestSSLConfigService() override = default;
+
+ SSLConfig config_;
+};
+
} // namespace
class HttpNetworkTransactionTest : public PlatformTest {
@@ -577,8 +470,6 @@ class HttpNetworkTransactionTest : public PlatformTest {
void ConnectStatusHelper(const MockRead& status);
- void BypassHostCacheOnRefreshHelper(int load_flags);
-
void CheckErrorIsPassedBack(int error, IoMode mode);
SpdyTestUtil spdy_util_;
@@ -807,6 +698,16 @@ bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
return true;
}
+
+bool CheckNTLMProxyAuth(const AuthChallengeInfo* auth_challenge) {
+ if (!auth_challenge)
+ return false;
+ EXPECT_TRUE(auth_challenge->is_proxy);
+ EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
+ EXPECT_EQ(std::string(), auth_challenge->realm);
+ EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
+ return true;
+}
#endif // defined(NTLM_PORTABLE)
} // namespace
@@ -3166,7 +3067,8 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
// Configure against proxy server "myproxy:70".
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3293,7 +3195,8 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
// Configure against proxy server "myproxy:70".
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3424,7 +3327,8 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
// Configure against proxy server "myproxy:70".
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("myproxy:70");
+ ProxyResolutionService::CreateFixed("myproxy:70",
+ TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3537,7 +3441,8 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
// Configure against proxy server "myproxy:70".
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("myproxy:70");
+ ProxyResolutionService::CreateFixed("myproxy:70",
+ TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3645,7 +3550,8 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
// Configure against proxy server "myproxy:70".
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3772,8 +3678,8 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("myproxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
@@ -3862,8 +3768,8 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("myproxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3922,8 +3828,8 @@ TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("myproxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -4030,8 +3936,8 @@ TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
request.traffic_annotation =
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("myproxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -4094,7 +4000,8 @@ TEST_F(HttpNetworkTransactionTest,
// Configure against proxy server "myproxy:70".
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
auth_handler_factory->set_do_init_from_challenge(true);
@@ -4212,7 +4119,8 @@ TEST_F(HttpNetworkTransactionTest,
// Configure against proxy server "myproxy:70".
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
auth_handler_factory->set_do_init_from_challenge(true);
@@ -4335,7 +4243,8 @@ TEST_F(HttpNetworkTransactionTest,
// Configure against proxy server "myproxy:70".
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
auth_handler_factory->set_do_init_from_challenge(true);
@@ -4434,7 +4343,8 @@ TEST_F(HttpNetworkTransactionTest,
// Configure against proxy server "myproxy:70".
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
auth_handler_factory->set_do_init_from_challenge(true);
@@ -4679,6 +4589,8 @@ class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
std::unique_ptr<Request>* request,
const NetLogWithSource& /*net_log*/) override {
*results = ProxyInfo();
+ results->set_traffic_annotation(
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
if (url.path() == "/socks4") {
results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
return OK;
@@ -4709,11 +4621,10 @@ class SameProxyWithDifferentSchemesProxyResolverFactory
SameProxyWithDifferentSchemesProxyResolverFactory()
: ProxyResolverFactory(false) {}
- int CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
- std::unique_ptr<ProxyResolver>* resolver,
- const CompletionCallback& callback,
- std::unique_ptr<Request>* request) override {
+ int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
+ std::unique_ptr<ProxyResolver>* resolver,
+ const CompletionCallback& callback,
+ std::unique_ptr<Request>* request) override {
*resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
return OK;
}
@@ -4727,11 +4638,12 @@ class SameProxyWithDifferentSchemesProxyResolverFactory
// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
// request to foo.com using proxy.com as an HTTP proxy.
TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
- session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
- std::make_unique<ProxyConfigServiceFixed>(
- ProxyConfig::CreateAutoDetect()),
- std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
- nullptr);
+ session_deps_.proxy_resolution_service =
+ std::make_unique<ProxyResolutionService>(
+ std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
+ ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
+ std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
+ nullptr);
std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
@@ -4895,8 +4807,8 @@ TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("myproxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -5000,7 +4912,8 @@ TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
// Configure against proxy server "myproxy:70".
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -5096,8 +5009,8 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Configure against https proxy server "proxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://proxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -5160,8 +5073,8 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Configure against https proxy server "proxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://proxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -5222,8 +5135,8 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Configure SPDY proxy server "proxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://proxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -5292,8 +5205,8 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Configure against https proxy server "myproxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://myproxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -5387,8 +5300,8 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Configure against https proxy server "proxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://proxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -5472,8 +5385,8 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Configure against https proxy server "proxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://proxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -5561,8 +5474,8 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Configure against https proxy server "proxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://proxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -5612,8 +5525,8 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
TEST_F(HttpNetworkTransactionTest,
HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
// Configure against https proxy server "proxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://proxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(
@@ -5747,8 +5660,8 @@ TEST_F(HttpNetworkTransactionTest,
TEST_F(HttpNetworkTransactionTest,
HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
// Configure against https proxy server "proxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://proxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(
@@ -5873,8 +5786,8 @@ TEST_F(HttpNetworkTransactionTest,
// Proxy to different servers.
TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
// Configure against https proxy server "proxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://proxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(
@@ -5981,8 +5894,8 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Configure against https proxy server "myproxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://myproxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -6078,8 +5991,8 @@ void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("myproxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Since we have proxy, should try to establish tunnel.
@@ -6295,8 +6208,8 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("myproxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
@@ -6976,6 +6889,163 @@ TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
EXPECT_TRUE(data1.AllReadDataConsumed());
EXPECT_TRUE(data1.AllWriteDataConsumed());
}
+
+// Test that, if we have an NTLM proxy and the origin resets the connection, we
+// do no retry forever checking for TLS version interference. This is a
+// regression test for https://crbug.com/823387.
+TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
+ // The NTLM test data expects the proxy to be named 'server'. The origin is
+ // https://origin/.
+ session_deps_.proxy_resolution_service =
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
+
+ SSLConfig config;
+ config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
+ session_deps_.ssl_config_service =
+ base::MakeRefCounted<TestSSLConfigService>(config);
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("https://origin/");
+ request.traffic_annotation =
+ net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
+
+ // Ensure load is not disrupted by flags which suppress behaviour specific
+ // to other auth schemes.
+ request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
+
+ HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
+ MockGetMSTime, MockGenerateRandom, MockGetHostName);
+ std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+
+ // Generate the NTLM messages based on known test data.
+ std::string negotiate_msg;
+ std::string challenge_msg;
+ std::string authenticate_msg;
+ base::Base64Encode(
+ base::StringPiece(
+ reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
+ arraysize(ntlm::test::kExpectedNegotiateMsg)),
+ &negotiate_msg);
+ base::Base64Encode(
+ base::StringPiece(
+ reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
+ arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
+ &challenge_msg);
+ base::Base64Encode(
+ base::StringPiece(
+ reinterpret_cast<const char*>(
+ ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
+ arraysize(
+ ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
+ &authenticate_msg);
+
+ MockWrite data_writes[] = {
+ // The initial CONNECT request.
+ MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
+ "Host: origin:443\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+
+ // After restarting with an identity.
+ MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
+ "Host: origin:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: NTLM "),
+ MockWrite(negotiate_msg.c_str()),
+ // End headers.
+ MockWrite("\r\n\r\n"),
+
+ // The second restart.
+ MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
+ "Host: origin:443\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "Proxy-Authorization: NTLM "),
+ MockWrite(authenticate_msg.c_str()),
+ // End headers.
+ MockWrite("\r\n\r\n"),
+ };
+
+ MockRead data_reads[] = {
+ // The initial NTLM response.
+ MockRead("HTTP/1.1 407 Access Denied\r\n"
+ "Content-Length: 0\r\n"
+ "Proxy-Authenticate: NTLM\r\n\r\n"),
+
+ // The NTLM challenge message.
+ MockRead("HTTP/1.1 407 Access Denied\r\n"
+ "Content-Length: 0\r\n"
+ "Proxy-Authenticate: NTLM "),
+ MockRead(challenge_msg.c_str()),
+ // End headers.
+ MockRead("\r\n\r\n"),
+
+ // Finally the tunnel is established.
+ MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
+ };
+
+ StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
+ arraysize(data_writes));
+ SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
+ StaticSocketDataProvider data2(data_reads, arraysize(data_reads), data_writes,
+ arraysize(data_writes));
+ SSLSocketDataProvider data_ssl2(ASYNC, ERR_CONNECTION_RESET);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
+ session_deps_.socket_factory->AddSocketDataProvider(&data2);
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl2);
+
+ // Start the transaction. The proxy responds with an NTLM authentication
+ // request.
+ TestCompletionCallback callback;
+ HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
+ int rv = callback.GetResult(
+ trans.Start(&request, callback.callback(), NetLogWithSource()));
+
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_FALSE(trans.IsReadyToRestartForAuth());
+ const HttpResponseInfo* response = trans.GetResponseInfo();
+ ASSERT_TRUE(response);
+ EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge.get()));
+
+ // Configure credentials. The proxy responds with the challenge message.
+ rv = callback.GetResult(trans.RestartWithAuth(
+ AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
+ callback.callback()));
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_TRUE(trans.IsReadyToRestartForAuth());
+ response = trans.GetResponseInfo();
+ ASSERT_TRUE(response);
+ EXPECT_FALSE(response->auth_challenge);
+
+ // Restart once more. The tunnel will be established and the the SSL handshake
+ // will reset. The TLS 1.3 version interference probe will then kick in and
+ // restart the process. The proxy responds with another NTLM authentiation
+ // request, but we don't need to provide credentials as the cached ones work/
+ rv = callback.GetResult(
+ trans.RestartWithAuth(AuthCredentials(), callback.callback()));
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_TRUE(trans.IsReadyToRestartForAuth());
+ response = trans.GetResponseInfo();
+ ASSERT_TRUE(response);
+ EXPECT_FALSE(response->auth_challenge);
+
+ // The proxy responds with the NTLM challenge message.
+ rv = callback.GetResult(
+ trans.RestartWithAuth(AuthCredentials(), callback.callback()));
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_TRUE(trans.IsReadyToRestartForAuth());
+ response = trans.GetResponseInfo();
+ ASSERT_TRUE(response);
+ EXPECT_FALSE(response->auth_challenge);
+
+ // Send the NTLM authenticate message. The tunnel is established and the
+ // handshake resets again. We should not retry again.
+ rv = callback.GetResult(
+ trans.RestartWithAuth(AuthCredentials(), callback.callback()));
+ EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
+}
+
#endif // NTLM_PORTABLE
// Test reading a server response which has only headers, and no body.
@@ -7024,8 +7094,8 @@ TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("myproxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -8560,8 +8630,8 @@ TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
// Test HTTPS connections to a site with a bad certificate, going through a
// proxy
TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("myproxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
HttpRequestInfo request;
request.method = "GET";
@@ -8641,7 +8711,8 @@ TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
// Test HTTPS connections to a site, going through an HTTPS proxy
TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
TestNetLog net_log;
session_deps_.net_log = &net_log;
@@ -8706,7 +8777,8 @@ TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
// Test an HTTPS Proxy's ability to redirect a CONNECT request
TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
TestNetLog net_log;
session_deps_.net_log = &net_log;
@@ -8781,8 +8853,8 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://proxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
HttpRequestInfo request;
request.method = "GET";
@@ -8839,8 +8911,8 @@ TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
// Test that an HTTPS proxy's response to a CONNECT request is filtered.
TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://proxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
HttpRequestInfo request;
request.method = "GET";
@@ -8884,8 +8956,8 @@ TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
// Test that a SPDY proxy's response to a CONNECT request is filtered.
TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://proxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
HttpRequestInfo request;
request.method = "GET";
@@ -8949,7 +9021,8 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
// Configure against https proxy server "myproxy:70".
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -9096,7 +9169,8 @@ TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
// Configure against https proxy server "myproxy:443".
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy:443");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
@@ -9210,8 +9284,8 @@ TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
request.traffic_annotation =
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://myproxy:443");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
@@ -9294,8 +9368,8 @@ TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Configure against https proxy server "myproxy:70".
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://myproxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
@@ -9371,8 +9445,8 @@ TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
// Test HTTPS connections to a site with a bad certificate, going through an
// HTTPS proxy
TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://proxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
HttpRequestInfo request;
request.method = "GET";
@@ -9501,8 +9575,8 @@ TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
request.traffic_annotation =
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("myproxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
@@ -9862,7 +9936,8 @@ TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("SOCKS myproxy:1080");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
TestNetLog net_log;
session_deps_.net_log = &net_log;
@@ -9922,7 +9997,8 @@ TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("SOCKS myproxy:1080");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
TestNetLog net_log;
session_deps_.net_log = &net_log;
@@ -9986,8 +10062,8 @@ TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
request.traffic_annotation =
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("socks4://myproxy:1080");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
TestNetLog net_log;
session_deps_.net_log = &net_log;
@@ -10046,7 +10122,8 @@ TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
TestNetLog net_log;
session_deps_.net_log = &net_log;
@@ -10119,7 +10196,8 @@ TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
TestNetLog net_log;
session_deps_.net_log = &net_log;
@@ -10271,7 +10349,8 @@ TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
for (size_t i = 0; i < arraysize(tests); ++i) {
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed(tests[i].proxy_server);
+ ProxyResolutionService::CreateFixed(tests[i].proxy_server,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
std::unique_ptr<HttpNetworkSession> session(
SetupSessionForGroupNameTests(&session_deps_));
@@ -10328,7 +10407,8 @@ TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
for (size_t i = 0; i < arraysize(tests); ++i) {
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed(tests[i].proxy_server);
+ ProxyResolutionService::CreateFixed(tests[i].proxy_server,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
std::unique_ptr<HttpNetworkSession> session(
SetupSessionForGroupNameTests(&session_deps_));
@@ -10396,7 +10476,8 @@ TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
for (size_t i = 0; i < arraysize(tests); ++i) {
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed(tests[i].proxy_server);
+ ProxyResolutionService::CreateFixed(tests[i].proxy_server,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
std::unique_ptr<HttpNetworkSession> session(
SetupSessionForGroupNameTests(&session_deps_));
@@ -10434,8 +10515,8 @@ TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
request.traffic_annotation =
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("myproxy:70;foobar:80");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
// This simulates failure resolving all hostnames; that means we will fail
// connecting to both proxies (myproxy:70 and foobar:80).
@@ -10453,14 +10534,12 @@ TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
}
-// Base test to make sure that when the load flags for a request specify to
-// bypass the cache, the DNS cache is not used.
-void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
- int load_flags) {
+// LOAD_BYPASS_CACHE should trigger the host cache bypass.
+TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) {
// Issue a request, asking to bypass the cache(s).
HttpRequestInfo request_info;
request_info.method = "GET";
- request_info.load_flags = load_flags;
+ request_info.load_flags = LOAD_BYPASS_CACHE;
request_info.url = GURL("http://www.example.org/");
request_info.traffic_annotation =
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
@@ -10513,20 +10592,6 @@ void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
}
-// There are multiple load flags that should trigger the host cache bypass.
-// Test each in isolation:
-TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
- BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
-}
-
-TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
- BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
-}
-
-TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
- BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
-}
-
// Make sure we can handle an error when writing the request.
TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
HttpRequestInfo request;
@@ -10683,8 +10748,8 @@ TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
// Test HTTPS connections going through a proxy that sends extra data.
TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("myproxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
HttpRequestInfo request;
request.method = "GET";
@@ -12246,11 +12311,10 @@ class CapturingProxyResolverFactory : public ProxyResolverFactory {
explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
: ProxyResolverFactory(false), resolver_(resolver) {}
- int CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
- std::unique_ptr<ProxyResolver>* resolver,
- const net::CompletionCallback& callback,
- std::unique_ptr<Request>* request) override {
+ int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
+ std::unique_ptr<ProxyResolver>* resolver,
+ const net::CompletionCallback& callback,
+ std::unique_ptr<Request>* request) override {
*resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
return OK;
}
@@ -12266,8 +12330,8 @@ TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
ProxyConfig proxy_config;
proxy_config.proxy_rules().ParseFromString("myproxy:70");
proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
- auto proxy_config_service =
- std::make_unique<ProxyConfigServiceFixed>(proxy_config);
+ auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
+ ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
CapturingProxyResolver capturing_proxy_resolver;
auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
@@ -12275,9 +12339,10 @@ TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
TestNetLog net_log;
- session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
- std::move(proxy_config_service), std::move(proxy_resolver_factory),
- &net_log);
+ session_deps_.proxy_resolution_service =
+ std::make_unique<ProxyResolutionService>(
+ std::move(proxy_config_service), std::move(proxy_resolver_factory),
+ &net_log);
session_deps_.net_log = &net_log;
@@ -12353,11 +12418,13 @@ TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
proxy_config.set_pac_url(GURL("http://fooproxyurl"));
CapturingProxyResolver capturing_proxy_resolver;
- session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
- std::make_unique<ProxyConfigServiceFixed>(proxy_config),
- std::make_unique<CapturingProxyResolverFactory>(
- &capturing_proxy_resolver),
- nullptr);
+ session_deps_.proxy_resolution_service =
+ std::make_unique<ProxyResolutionService>(
+ std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
+ proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
+ std::make_unique<CapturingProxyResolverFactory>(
+ &capturing_proxy_resolver),
+ nullptr);
TestNetLog net_log;
session_deps_.net_log = &net_log;
@@ -13397,9 +13464,11 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
}
if (test_config.proxy_url) {
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed(test_config.proxy_url);
+ ProxyResolutionService::CreateFixed(test_config.proxy_url,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
} else {
- session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
+ session_deps_.proxy_resolution_service =
+ ProxyResolutionService::CreateDirect();
}
HttpRequestInfo request;
@@ -13492,7 +13561,8 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
HttpAuthHandlerMock::Factory* auth_factory(
new HttpAuthHandlerMock::Factory());
session_deps_.http_auth_handler_factory.reset(auth_factory);
- session_deps_.proxy_resolution_service = ProxyResolutionService::CreateDirect();
+ session_deps_.proxy_resolution_service =
+ ProxyResolutionService::CreateDirect();
session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
session_deps_.host_resolver->set_synchronous_mode(true);
@@ -13889,7 +13959,8 @@ TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
// Test a basic GET request through a proxy.
TEST_F(HttpNetworkTransactionTest, ProxyGet) {
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -13956,7 +14027,8 @@ TEST_F(HttpNetworkTransactionTest, ProxyGet) {
// Test a basic HTTPS GET request through a proxy.
TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -14041,7 +14113,8 @@ TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
// literal host.
TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -14118,8 +14191,8 @@ TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
// Test a basic HTTPS GET request through a proxy, but the server hangs up
// while establishing the tunnel.
TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("myproxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -14491,8 +14564,8 @@ TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
// The test is repeated twice, first for connecting to an HTTPS endpoint,
// then for connecting to an HTTP endpoint.
TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
- session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixed("https://proxy:70");
+ session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
+ "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
@@ -15540,7 +15613,8 @@ TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
data1.set_connect_data(connect_data1);
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("HTTPS proxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
TestNetLog log;
session_deps_.net_log = &log;
SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
@@ -15663,9 +15737,11 @@ TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
// all others direct.
ProxyConfig proxy_config;
proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
- session_deps_.proxy_resolution_service = std::make_unique<ProxyResolutionService>(
- std::make_unique<ProxyConfigServiceFixed>(proxy_config), nullptr,
- nullptr);
+ session_deps_.proxy_resolution_service =
+ std::make_unique<ProxyResolutionService>(
+ std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
+ proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
+ nullptr, nullptr);
SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
ssl1.next_proto = kProtoHTTP2;
@@ -15833,10 +15909,9 @@ TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
// Use a separate test instance for the separate SpdySession that will be
// created.
SpdyTestUtil spdy_util_2;
- auto spdy1_data = std::make_unique<SequencedSocketData>(
- spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
- arraysize(spdy1_writes));
- session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
+ SequencedSocketData spdy1_data(spdy1_reads, arraysize(spdy1_reads),
+ spdy1_writes, arraysize(spdy1_writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
SpdySerializedFrame host2_req(
spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
@@ -15851,10 +15926,9 @@ TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
};
- auto spdy2_data = std::make_unique<SequencedSocketData>(
- spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
- arraysize(spdy2_writes));
- session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
+ SequencedSocketData spdy2_data(spdy2_reads, arraysize(spdy2_reads),
+ spdy2_writes, arraysize(spdy2_writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
MockWrite http_write[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -16229,342 +16303,6 @@ TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
EXPECT_EQ("bar", foo);
}
-namespace {
-
-// Fake HttpStream that simply records calls to SetPriority().
-class FakeStream : public HttpStream,
- public base::SupportsWeakPtr<FakeStream> {
- public:
- explicit FakeStream(RequestPriority priority) : priority_(priority) {}
- ~FakeStream() override = default;
-
- RequestPriority priority() const { return priority_; }
-
- int InitializeStream(const HttpRequestInfo* request_info,
- bool can_send_early,
- RequestPriority priority,
- const NetLogWithSource& net_log,
- CompletionOnceCallback callback) override {
- return ERR_IO_PENDING;
- }
-
- int SendRequest(const HttpRequestHeaders& request_headers,
- HttpResponseInfo* response,
- CompletionOnceCallback callback) override {
- ADD_FAILURE();
- return ERR_UNEXPECTED;
- }
-
- int ReadResponseHeaders(CompletionOnceCallback callback) override {
- ADD_FAILURE();
- return ERR_UNEXPECTED;
- }
-
- int ReadResponseBody(IOBuffer* buf,
- int buf_len,
- CompletionOnceCallback callback) override {
- ADD_FAILURE();
- return ERR_UNEXPECTED;
- }
-
- void Close(bool not_reusable) override {}
-
- bool IsResponseBodyComplete() const override {
- ADD_FAILURE();
- return false;
- }
-
- bool IsConnectionReused() const override {
- ADD_FAILURE();
- return false;
- }
-
- void SetConnectionReused() override { ADD_FAILURE(); }
-
- bool CanReuseConnection() const override { return false; }
-
- int64_t GetTotalReceivedBytes() const override {
- ADD_FAILURE();
- return 0;
- }
-
- int64_t GetTotalSentBytes() const override {
- ADD_FAILURE();
- return 0;
- }
-
- bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
- ADD_FAILURE();
- return false;
- }
-
- bool GetAlternativeService(
- AlternativeService* alternative_service) const override {
- ADD_FAILURE();
- return false;
- }
-
- void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
-
- void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
- ADD_FAILURE();
- }
-
- bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
-
- Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
- TokenBindingType tb_type,
- std::vector<uint8_t>* out) override {
- ADD_FAILURE();
- return ERR_NOT_IMPLEMENTED;
- }
-
- void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
-
- void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
-
- void SetPriority(RequestPriority priority) override { priority_ = priority; }
-
- HttpStream* RenewStreamForAuth() override { return NULL; }
-
- void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
-
- private:
- RequestPriority priority_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeStream);
-};
-
-// Fake HttpStreamRequest that simply records calls to SetPriority()
-// and vends FakeStreams with its current priority.
-class FakeStreamRequest : public HttpStreamRequest,
- public base::SupportsWeakPtr<FakeStreamRequest> {
- public:
- FakeStreamRequest(RequestPriority priority,
- HttpStreamRequest::Delegate* delegate)
- : priority_(priority),
- delegate_(delegate),
- websocket_stream_create_helper_(NULL) {}
-
- FakeStreamRequest(RequestPriority priority,
- HttpStreamRequest::Delegate* delegate,
- WebSocketHandshakeStreamBase::CreateHelper* create_helper)
- : priority_(priority),
- delegate_(delegate),
- websocket_stream_create_helper_(create_helper) {}
-
- ~FakeStreamRequest() override = default;
-
- RequestPriority priority() const { return priority_; }
-
- const WebSocketHandshakeStreamBase::CreateHelper*
- websocket_stream_create_helper() const {
- return websocket_stream_create_helper_;
- }
-
- // Create a new FakeStream and pass it to the request's
- // delegate. Returns a weak pointer to the FakeStream.
- base::WeakPtr<FakeStream> FinishStreamRequest() {
- auto fake_stream = std::make_unique<FakeStream>(priority_);
- // Do this before calling OnStreamReady() as OnStreamReady() may
- // immediately delete |fake_stream|.
- base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
- delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
- return weak_stream;
- }
-
- int RestartTunnelWithProxyAuth() override {
- ADD_FAILURE();
- return ERR_UNEXPECTED;
- }
-
- LoadState GetLoadState() const override {
- ADD_FAILURE();
- return LoadState();
- }
-
- void SetPriority(RequestPriority priority) override { priority_ = priority; }
-
- bool was_alpn_negotiated() const override { return false; }
-
- NextProto negotiated_protocol() const override { return kProtoUnknown; }
-
- bool using_spdy() const override { return false; }
-
- const ConnectionAttempts& connection_attempts() const override {
- static ConnectionAttempts no_attempts;
- return no_attempts;
- }
-
- private:
- RequestPriority priority_;
- HttpStreamRequest::Delegate* const delegate_;
- WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
-};
-
-// Fake HttpStreamFactory that vends FakeStreamRequests.
-class FakeStreamFactory : public HttpStreamFactory {
- public:
- FakeStreamFactory() = default;
- ~FakeStreamFactory() override = default;
-
- // Returns a WeakPtr<> to the last HttpStreamRequest returned by
- // RequestStream() (which may be NULL if it was destroyed already).
- base::WeakPtr<FakeStreamRequest> last_stream_request() {
- return last_stream_request_;
- }
-
- std::unique_ptr<HttpStreamRequest> RequestStream(
- const HttpRequestInfo& info,
- RequestPriority priority,
- const SSLConfig& server_ssl_config,
- const SSLConfig& proxy_ssl_config,
- HttpStreamRequest::Delegate* delegate,
- bool enable_ip_based_pooling,
- bool enable_alternative_services,
- const NetLogWithSource& net_log) override {
- auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
- last_stream_request_ = fake_request->AsWeakPtr();
- return std::move(fake_request);
- }
-
- std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
- const HttpRequestInfo& info,
- RequestPriority priority,
- const SSLConfig& server_ssl_config,
- const SSLConfig& proxy_ssl_config,
- HttpStreamRequest::Delegate* delegate,
- bool enable_ip_based_pooling,
- bool enable_alternative_services,
- const NetLogWithSource& net_log) override {
- NOTREACHED();
- return nullptr;
- }
-
- std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
- const HttpRequestInfo& info,
- RequestPriority priority,
- const SSLConfig& server_ssl_config,
- const SSLConfig& proxy_ssl_config,
- HttpStreamRequest::Delegate* delegate,
- WebSocketHandshakeStreamBase::CreateHelper* create_helper,
- bool enable_ip_based_pooling,
- bool enable_alternative_services,
- const NetLogWithSource& net_log) override {
- auto fake_request =
- std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
- last_stream_request_ = fake_request->AsWeakPtr();
- return std::move(fake_request);
- }
-
- void PreconnectStreams(int num_streams,
- const HttpRequestInfo& info) override {
- ADD_FAILURE();
- }
-
- const HostMappingRules* GetHostMappingRules() const override {
- ADD_FAILURE();
- return NULL;
- }
-
- void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
- const std::string& parent_absolute_name) const override {
- ADD_FAILURE();
- }
-
- private:
- base::WeakPtr<FakeStreamRequest> last_stream_request_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
-};
-
-} // namespace
-
-// Make sure that HttpNetworkTransaction passes on its priority to its
-// stream request on start.
-TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
- std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
- HttpNetworkSessionPeer peer(session.get());
- FakeStreamFactory* fake_factory = new FakeStreamFactory();
- peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
-
- HttpRequestInfo request;
- HttpNetworkTransaction trans(LOW, session.get());
-
- request.traffic_annotation =
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
-
- ASSERT_FALSE(fake_factory->last_stream_request());
-
- TestCompletionCallback callback;
- EXPECT_EQ(ERR_IO_PENDING,
- trans.Start(&request, callback.callback(), NetLogWithSource()));
-
- base::WeakPtr<FakeStreamRequest> fake_request =
- fake_factory->last_stream_request();
- ASSERT_TRUE(fake_request);
- EXPECT_EQ(LOW, fake_request->priority());
-}
-
-// Make sure that HttpNetworkTransaction passes on its priority
-// updates to its stream request.
-TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
- std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
- HttpNetworkSessionPeer peer(session.get());
- FakeStreamFactory* fake_factory = new FakeStreamFactory();
- peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
-
- HttpRequestInfo request;
- HttpNetworkTransaction trans(LOW, session.get());
-
- request.traffic_annotation =
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
-
- TestCompletionCallback callback;
- EXPECT_EQ(ERR_IO_PENDING,
- trans.Start(&request, callback.callback(), NetLogWithSource()));
-
- base::WeakPtr<FakeStreamRequest> fake_request =
- fake_factory->last_stream_request();
- ASSERT_TRUE(fake_request);
- EXPECT_EQ(LOW, fake_request->priority());
-
- trans.SetPriority(LOWEST);
- ASSERT_TRUE(fake_request);
- EXPECT_EQ(LOWEST, fake_request->priority());
-}
-
-// Make sure that HttpNetworkTransaction passes on its priority
-// updates to its stream.
-TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
- std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
- HttpNetworkSessionPeer peer(session.get());
- FakeStreamFactory* fake_factory = new FakeStreamFactory();
- peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
-
- HttpRequestInfo request;
- HttpNetworkTransaction trans(LOW, session.get());
-
- request.traffic_annotation =
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
-
- TestCompletionCallback callback;
- EXPECT_EQ(ERR_IO_PENDING,
- trans.Start(&request, callback.callback(), NetLogWithSource()));
-
- base::WeakPtr<FakeStreamRequest> fake_request =
- fake_factory->last_stream_request();
- ASSERT_TRUE(fake_request);
- base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
- ASSERT_TRUE(fake_stream);
- EXPECT_EQ(LOW, fake_stream->priority());
-
- trans.SetPriority(LOWEST);
- EXPECT_EQ(LOWEST, fake_stream->priority());
-}
-
// Tests that when a used socket is returned to the SSL socket pool, it's closed
// if the transport socket pool is stalled on the global socket limit.
TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
@@ -17228,38 +16966,61 @@ void AddWebSocketHeaders(HttpRequestHeaders* headers) {
} // namespace
TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
- // The same logic needs to be tested for both ws: and wss: schemes, but this
- // test is already parameterised on NextProto, so it uses a loop to verify
- // that the different schemes work.
- std::string test_cases[] = {"ws://www.example.org/",
- "wss://www.example.org/"};
- for (size_t i = 0; i < arraysize(test_cases); ++i) {
- std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
- HttpNetworkSessionPeer peer(session.get());
- FakeStreamFactory* fake_factory = new FakeStreamFactory();
- peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
+ for (bool secure : {true, false}) {
+ MockWrite data_writes[] = {
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: Upgrade\r\n"
+ "Upgrade: websocket\r\n"
+ "Origin: http://www.example.org\r\n"
+ "Sec-WebSocket-Version: 13\r\n"
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
+ "Sec-WebSocket-Extensions: permessage-deflate; "
+ "client_max_window_bits\r\n\r\n")};
+
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 101 Switching Protocols\r\n"
+ "Upgrade: websocket\r\n"
+ "Connection: Upgrade\r\n"
+ "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
+
+ StaticSocketDataProvider data(data_reads, arraysize(data_reads),
+ data_writes, arraysize(data_writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+ SSLSocketDataProvider ssl(ASYNC, OK);
+ if (secure)
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
HttpRequestInfo request;
request.method = "GET";
- request.url = GURL(test_cases[i]);
+ request.url =
+ GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
+ AddWebSocketHeaders(&request.extra_headers);
request.traffic_annotation =
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
- TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
+ TestWebSocketHandshakeStreamCreateHelper
+ websocket_handshake_stream_create_helper;
+ std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
HttpNetworkTransaction trans(LOW, session.get());
trans.SetWebSocketHandshakeStreamCreateHelper(
- &websocket_stream_create_helper);
+ &websocket_handshake_stream_create_helper);
TestCompletionCallback callback;
- EXPECT_EQ(ERR_IO_PENDING,
- trans.Start(&request, callback.callback(), NetLogWithSource()));
+ int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
- base::WeakPtr<FakeStreamRequest> fake_request =
- fake_factory->last_stream_request();
- ASSERT_TRUE(fake_request);
- EXPECT_EQ(&websocket_stream_create_helper,
- fake_request->websocket_stream_create_helper());
+ const HttpStreamRequest* stream_request = trans.stream_request_.get();
+ ASSERT_TRUE(stream_request);
+ EXPECT_EQ(&websocket_handshake_stream_create_helper,
+ stream_request->websocket_handshake_stream_create_helper());
+
+ rv = callback.WaitForResult();
+ EXPECT_THAT(rv, IsOk());
+
+ EXPECT_TRUE(data.AllReadDataConsumed());
+ EXPECT_TRUE(data.AllWriteDataConsumed());
}
}
@@ -17275,7 +17036,8 @@ TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
// Configure against proxy server "myproxy:70".
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -17382,7 +17144,8 @@ TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
// Configure against proxy server "myproxy:70".
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -17595,306 +17358,6 @@ TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
trans.GetTotalReceivedBytes());
}
-// Confirm that transactions whose throttle is created in (and stays in)
-// the unthrottled state are not blocked.
-TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
- TestNetworkStreamThrottler* throttler(nullptr);
- std::unique_ptr<HttpNetworkSession> session(
- CreateSessionWithThrottler(&session_deps_, &throttler));
-
- // Send a simple request and make sure it goes through.
- HttpRequestInfo request;
- request.method = "GET";
- request.url = GURL("http://www.example.org/");
- request.traffic_annotation =
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
-
- auto trans =
- std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
-
- MockWrite data_writes[] = {
- MockWrite("GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
- };
- MockRead data_reads[] = {
- MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
- MockRead(SYNCHRONOUS, OK),
- };
- StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
- arraysize(data_writes));
- session_deps_.socket_factory->AddSocketDataProvider(&reads);
-
- TestCompletionCallback callback;
- trans->Start(&request, callback.callback(), NetLogWithSource());
- EXPECT_EQ(OK, callback.WaitForResult());
-}
-
-// Confirm requests can be blocked by a throttler, and are resumed
-// when the throttle is unblocked.
-TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
- TestNetworkStreamThrottler* throttler(nullptr);
- std::unique_ptr<HttpNetworkSession> session(
- CreateSessionWithThrottler(&session_deps_, &throttler));
-
- // Send a simple request and make sure it goes through.
- HttpRequestInfo request;
- request.method = "GET";
- request.url = GURL("http://www.example.org/");
- request.traffic_annotation =
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
-
- MockWrite data_writes[] = {
- MockWrite("GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
- };
- MockRead data_reads[] = {
- MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
- MockRead(SYNCHRONOUS, OK),
- };
- StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
- arraysize(data_writes));
- session_deps_.socket_factory->AddSocketDataProvider(&reads);
-
- // Start a request that will be throttled at start; confirm it
- // doesn't complete.
- throttler->set_throttle_new_requests(true);
- auto trans =
- std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
-
- TestCompletionCallback callback;
- int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
- EXPECT_FALSE(callback.have_result());
-
- // Confirm the request goes on to complete when unthrottled.
- throttler->UnthrottleAllRequests();
- base::RunLoop().RunUntilIdle();
- ASSERT_TRUE(callback.have_result());
- EXPECT_EQ(OK, callback.WaitForResult());
-}
-
-// Destroy a request while it's throttled.
-TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
- TestNetworkStreamThrottler* throttler(nullptr);
- std::unique_ptr<HttpNetworkSession> session(
- CreateSessionWithThrottler(&session_deps_, &throttler));
-
- // Send a simple request and make sure it goes through.
- HttpRequestInfo request;
- request.method = "GET";
- request.url = GURL("http://www.example.org/");
- request.traffic_annotation =
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
-
- MockWrite data_writes[] = {
- MockWrite("GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
- };
- MockRead data_reads[] = {
- MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
- MockRead(SYNCHRONOUS, OK),
- };
- StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
- arraysize(data_writes));
- session_deps_.socket_factory->AddSocketDataProvider(&reads);
-
- // Start a request that will be throttled at start; confirm it
- // doesn't complete.
- throttler->set_throttle_new_requests(true);
- auto trans =
- std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
-
- TestCompletionCallback callback;
- int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
- EXPECT_FALSE(callback.have_result());
-
- EXPECT_EQ(1u, throttler->num_outstanding_requests());
- trans.reset();
- EXPECT_EQ(0u, throttler->num_outstanding_requests());
-}
-
-// Confirm the throttler receives SetPriority calls.
-TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
- TestNetworkStreamThrottler* throttler(nullptr);
- std::unique_ptr<HttpNetworkSession> session(
- CreateSessionWithThrottler(&session_deps_, &throttler));
-
- // Send a simple request and make sure it goes through.
- HttpRequestInfo request;
- request.method = "GET";
- request.url = GURL("http://www.example.org/");
- request.traffic_annotation =
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
-
- MockWrite data_writes[] = {
- MockWrite("GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
- };
- MockRead data_reads[] = {
- MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
- MockRead(SYNCHRONOUS, OK),
- };
- StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
- arraysize(data_writes));
- session_deps_.socket_factory->AddSocketDataProvider(&reads);
-
- throttler->set_throttle_new_requests(true);
- auto trans = std::make_unique<HttpNetworkTransaction>(IDLE, session.get());
- // Start the transaction to associate a throttle with it.
- TestCompletionCallback callback;
- int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(0, throttler->num_set_priority_calls());
- trans->SetPriority(LOW);
- EXPECT_EQ(1, throttler->num_set_priority_calls());
- EXPECT_EQ(LOW, throttler->last_priority_set());
-
- throttler->UnthrottleAllRequests();
- base::RunLoop().RunUntilIdle();
- ASSERT_TRUE(callback.have_result());
- EXPECT_EQ(OK, callback.WaitForResult());
-}
-
-// Confirm that unthrottling from a SetPriority call by the
-// throttler works properly.
-TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
- TestNetworkStreamThrottler* throttler(nullptr);
- std::unique_ptr<HttpNetworkSession> session(
- CreateSessionWithThrottler(&session_deps_, &throttler));
-
- // Send a simple request and make sure it goes through.
- HttpRequestInfo request;
- request.method = "GET";
- request.url = GURL("http://www.example.org/");
- request.traffic_annotation =
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
-
- MockWrite data_writes[] = {
- MockWrite("GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
- };
- MockRead data_reads[] = {
- MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
- MockRead(SYNCHRONOUS, OK),
- };
- StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
- arraysize(data_writes));
- session_deps_.socket_factory->AddSocketDataProvider(&reads);
-
- StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
- data_writes, arraysize(data_writes));
- session_deps_.socket_factory->AddSocketDataProvider(&reads1);
-
- // Start a request that will be throttled at start; confirm it
- // doesn't complete.
- throttler->set_throttle_new_requests(true);
- auto trans =
- std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
-
- TestCompletionCallback callback;
- int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
- EXPECT_FALSE(callback.have_result());
-
- // Create a new request, call SetPriority on it to unthrottle,
- // and make sure that allows the original request to complete.
- auto trans1 = std::make_unique<HttpNetworkTransaction>(LOW, session.get());
- throttler->set_priority_change_closure(
- base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
- base::Unretained(throttler)));
-
- // Start the transaction to associate a throttle with it.
- TestCompletionCallback callback1;
- rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- trans1->SetPriority(IDLE);
-
- base::RunLoop().RunUntilIdle();
- ASSERT_TRUE(callback.have_result());
- EXPECT_EQ(OK, callback.WaitForResult());
- ASSERT_TRUE(callback1.have_result());
- EXPECT_EQ(OK, callback1.WaitForResult());
-}
-
-// Transaction will be destroyed when the unique_ptr goes out of scope.
-void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
-
-// Confirm that destroying a transaction from a SetPriority call by the
-// throttler works properly.
-TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
- TestNetworkStreamThrottler* throttler(nullptr);
- std::unique_ptr<HttpNetworkSession> session(
- CreateSessionWithThrottler(&session_deps_, &throttler));
-
- // Send a simple request and make sure it goes through.
- HttpRequestInfo request;
- request.method = "GET";
- request.url = GURL("http://www.example.org/");
- request.traffic_annotation =
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
-
- MockWrite data_writes[] = {
- MockWrite("GET / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n\r\n"),
- };
- MockRead data_reads[] = {
- MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
- MockRead(SYNCHRONOUS, OK),
- };
- StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
- arraysize(data_writes));
- session_deps_.socket_factory->AddSocketDataProvider(&reads);
-
- StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
- data_writes, arraysize(data_writes));
- session_deps_.socket_factory->AddSocketDataProvider(&reads1);
-
- // Start a request that will be throttled at start; confirm it
- // doesn't complete.
- throttler->set_throttle_new_requests(true);
- auto trans =
- std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
-
- TestCompletionCallback callback;
- int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
- EXPECT_FALSE(callback.have_result());
-
- // Arrange for the set priority call on the above transaction to delete
- // the transaction.
- HttpNetworkTransaction* trans_ptr(trans.get());
- throttler->set_priority_change_closure(
- base::Bind(&DestroyTransaction, base::Passed(&trans)));
-
- // Call it and check results (partially a "doesn't crash" test).
- trans_ptr->SetPriority(IDLE);
- trans_ptr = nullptr; // No longer a valid pointer.
-
- base::RunLoop().RunUntilIdle();
- ASSERT_FALSE(callback.have_result());
-}
-
#if !defined(OS_IOS)
TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
const std::string https_url = "https://www.example.com";
@@ -18015,7 +17478,8 @@ TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
proxy_config.set_pac_mandatory(true);
MockAsyncProxyResolver resolver;
session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
- std::make_unique<ProxyConfigServiceFixed>(proxy_config),
+ std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
+ proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
std::make_unique<FailingProxyResolverFactory>(), nullptr));
HttpRequestInfo request;
@@ -18043,7 +17507,8 @@ TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
new MockAsyncProxyResolverFactory(false);
MockAsyncProxyResolver resolver;
session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
- std::make_unique<ProxyConfigServiceFixed>(proxy_config),
+ std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
+ proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
base::WrapUnique(proxy_resolver_factory), nullptr));
HttpRequestInfo request;
request.method = "GET";
@@ -18066,7 +17531,8 @@ TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("QUIC myproxy.org:443");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
session_deps_.enable_quic = false;
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
diff --git a/chromium/net/http/http_proxy_client_socket.cc b/chromium/net/http/http_proxy_client_socket.cc
index 813970c8b80..ec44a6cb16a 100644
--- a/chromium/net/http/http_proxy_client_socket.cc
+++ b/chromium/net/http/http_proxy_client_socket.cc
@@ -23,7 +23,6 @@
#include "net/log/net_log.h"
#include "net/log/net_log_event_type.h"
#include "net/socket/client_socket_handle.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"
namespace net {
@@ -36,7 +35,8 @@ HttpProxyClientSocket::HttpProxyClientSocket(
bool tunnel,
bool using_spdy,
NextProto negotiated_protocol,
- bool is_https_proxy)
+ bool is_https_proxy,
+ const NetworkTrafficAnnotationTag& traffic_annotation)
: io_callback_(base::Bind(&HttpProxyClientSocket::OnIOComplete,
base::Unretained(this))),
next_state_(STATE_NONE),
@@ -48,6 +48,7 @@ HttpProxyClientSocket::HttpProxyClientSocket(
negotiated_protocol_(negotiated_protocol),
is_https_proxy_(is_https_proxy),
redirect_has_load_timing_info_(false),
+ traffic_annotation_(traffic_annotation),
net_log_(transport_->socket()->NetLog()) {
// Synthesize the bits of a request that we actually use.
request_.url = GURL("https://" + endpoint.ToString());
@@ -418,10 +419,9 @@ int HttpProxyClientSocket::DoSendRequest() {
parser_buf_ = new GrowableIOBuffer();
http_stream_parser_.reset(new HttpStreamParser(
transport_.get(), &request_, parser_buf_.get(), net_log_));
- // TODO(crbug.com/656607): Add propoer annotation.
return http_stream_parser_->SendRequest(request_line_, request_headers_,
- NO_TRAFFIC_ANNOTATION_BUG_656607,
- &response_, io_callback_);
+ traffic_annotation_, &response_,
+ io_callback_);
}
int HttpProxyClientSocket::DoSendRequestComplete(int result) {
diff --git a/chromium/net/http/http_proxy_client_socket.h b/chromium/net/http/http_proxy_client_socket.h
index 382131656c4..ac11966d40e 100644
--- a/chromium/net/http/http_proxy_client_socket.h
+++ b/chromium/net/http/http_proxy_client_socket.h
@@ -46,7 +46,8 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocket : public ProxyClientSocket {
bool tunnel,
bool using_spdy,
NextProto negotiated_protocol,
- bool is_https_proxy);
+ bool is_https_proxy,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
// On destruction Disconnect() is called.
~HttpProxyClientSocket() override;
@@ -162,6 +163,9 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocket : public ProxyClientSocket {
bool redirect_has_load_timing_info_;
LoadTimingInfo redirect_load_timing_info_;
+ // Network traffic annotation for handshaking and setup.
+ const NetworkTrafficAnnotationTag traffic_annotation_;
+
const NetLogWithSource net_log_;
DISALLOW_COPY_AND_ASSIGN(HttpProxyClientSocket);
diff --git a/chromium/net/http/http_proxy_client_socket_fuzzer.cc b/chromium/net/http/http_proxy_client_socket_fuzzer.cc
index ac9702ab767..e74ef307fbb 100644
--- a/chromium/net/http/http_proxy_client_socket_fuzzer.cc
+++ b/chromium/net/http/http_proxy_client_socket_fuzzer.cc
@@ -26,6 +26,7 @@
#include "net/socket/client_socket_handle.h"
#include "net/socket/fuzzed_socket.h"
#include "net/socket/next_proto.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
// Fuzzer for HttpProxyClientSocket only tests establishing a connection when
// using the proxy as a tunnel.
@@ -66,7 +67,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
net::HttpProxyClientSocket socket(
std::move(socket_handle), "Bond/007", net::HostPortPair("foo", 80),
auth_controller.get(), true /* tunnel */, false /* using_spdy */,
- net::kProtoUnknown, is_https_proxy);
+ net::kProtoUnknown, is_https_proxy, TRAFFIC_ANNOTATION_FOR_TESTS);
int result = socket.Connect(callback.callback());
result = callback.GetResult(result);
diff --git a/chromium/net/http/http_proxy_client_socket_pool.cc b/chromium/net/http/http_proxy_client_socket_pool.cc
index c8c434d98e7..9a8e757454c 100644
--- a/chromium/net/http/http_proxy_client_socket_pool.cc
+++ b/chromium/net/http/http_proxy_client_socket_pool.cc
@@ -85,7 +85,8 @@ HttpProxySocketParams::HttpProxySocketParams(
SpdySessionPool* spdy_session_pool,
QuicStreamFactory* quic_stream_factory,
bool is_trusted_proxy,
- bool tunnel)
+ bool tunnel,
+ const NetworkTrafficAnnotationTag traffic_annotation)
: transport_params_(transport_params),
ssl_params_(ssl_params),
quic_version_(quic_version),
@@ -96,7 +97,8 @@ HttpProxySocketParams::HttpProxySocketParams(
http_auth_cache_(tunnel ? http_auth_cache : NULL),
http_auth_handler_factory_(tunnel ? http_auth_handler_factory : NULL),
is_trusted_proxy_(is_trusted_proxy),
- tunnel_(tunnel) {
+ tunnel_(tunnel),
+ traffic_annotation_(traffic_annotation) {
// If doing a QUIC proxy, |quic_version| must not be QUIC_VERSION_UNSUPPORTED,
// and |ssl_params| must be valid while |transport_params| is null.
// Otherwise, |quic_version| must be QUIC_VERSION_UNSUPPORTED, and exactly
@@ -159,6 +161,7 @@ HttpProxyConnectJob::HttpProxyConnectJob(
params->quic_stream_factory(),
params->is_trusted_proxy(),
params->tunnel(),
+ params->traffic_annotation(),
this->net_log())) {}
HttpProxyConnectJob::~HttpProxyConnectJob() = default;
diff --git a/chromium/net/http/http_proxy_client_socket_pool.h b/chromium/net/http/http_proxy_client_socket_pool.h
index 940638e60b3..502aac7c51f 100644
--- a/chromium/net/http/http_proxy_client_socket_pool.h
+++ b/chromium/net/http/http_proxy_client_socket_pool.h
@@ -23,6 +23,7 @@
#include "net/socket/client_socket_pool_base.h"
#include "net/socket/ssl_client_socket.h"
#include "net/spdy/chromium/spdy_session.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -57,7 +58,8 @@ class NET_EXPORT_PRIVATE HttpProxySocketParams
SpdySessionPool* spdy_session_pool,
QuicStreamFactory* quic_stream_factory,
bool is_trusted_proxy,
- bool tunnel);
+ bool tunnel,
+ const NetworkTrafficAnnotationTag traffic_annotation);
const scoped_refptr<TransportSocketParams>& transport_params() const {
return transport_params_;
@@ -81,6 +83,9 @@ class NET_EXPORT_PRIVATE HttpProxySocketParams
const HostResolver::RequestInfo& destination() const;
bool is_trusted_proxy() const { return is_trusted_proxy_; }
bool tunnel() const { return tunnel_; }
+ const NetworkTrafficAnnotationTag traffic_annotation() const {
+ return traffic_annotation_;
+ }
private:
friend class base::RefCounted<HttpProxySocketParams>;
@@ -97,6 +102,7 @@ class NET_EXPORT_PRIVATE HttpProxySocketParams
HttpAuthHandlerFactory* const http_auth_handler_factory_;
const bool is_trusted_proxy_;
const bool tunnel_;
+ const NetworkTrafficAnnotationTag traffic_annotation_;
DISALLOW_COPY_AND_ASSIGN(HttpProxySocketParams);
};
diff --git a/chromium/net/http/http_proxy_client_socket_pool_unittest.cc b/chromium/net/http/http_proxy_client_socket_pool_unittest.cc
index b24d821245b..cbc56f260be 100644
--- a/chromium/net/http/http_proxy_client_socket_pool_unittest.cc
+++ b/chromium/net/http/http_proxy_client_socket_pool_unittest.cc
@@ -32,6 +32,7 @@
#include "net/spdy/chromium/spdy_test_util_common.h"
#include "net/spdy/core/spdy_protocol.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -173,7 +174,7 @@ class HttpProxyClientSocketPoolTest
HostPortPair("www.google.com", tunnel ? 443 : 80),
session_->http_auth_cache(), session_->http_auth_handler_factory(),
session_->spdy_session_pool(), session_->quic_stream_factory(),
- /*is_trusted_proxy=*/false, tunnel);
+ /*is_trusted_proxy=*/false, tunnel, TRAFFIC_ANNOTATION_FOR_TESTS);
}
scoped_refptr<HttpProxySocketParams> CreateTunnelParams() {
diff --git a/chromium/net/http/http_proxy_client_socket_unittest.cc b/chromium/net/http/http_proxy_client_socket_unittest.cc
index dd35006cebe..6b9706711ad 100644
--- a/chromium/net/http/http_proxy_client_socket_unittest.cc
+++ b/chromium/net/http/http_proxy_client_socket_unittest.cc
@@ -11,6 +11,7 @@
#include "net/socket/next_proto.h"
#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -29,7 +30,8 @@ TEST(HttpProxyClientSocketTest, Tag) {
// non-owning pointer to it.
connection->SetSocket(std::unique_ptr<StreamSocket>(tagging_sock));
HttpProxyClientSocket socket(std::move(connection), "", HostPortPair(),
- nullptr, false, false, NextProto(), false);
+ nullptr, false, false, NextProto(), false,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_EQ(tagging_sock->tag(), SocketTag());
#if defined(OS_ANDROID)
diff --git a/chromium/net/http/http_proxy_client_socket_wrapper.cc b/chromium/net/http/http_proxy_client_socket_wrapper.cc
index 77d911f5f6d..f44bf42bacd 100644
--- a/chromium/net/http/http_proxy_client_socket_wrapper.cc
+++ b/chromium/net/http/http_proxy_client_socket_wrapper.cc
@@ -51,6 +51,7 @@ HttpProxyClientSocketWrapper::HttpProxyClientSocketWrapper(
QuicStreamFactory* quic_stream_factory,
bool is_trusted_proxy,
bool tunnel,
+ const NetworkTrafficAnnotationTag& traffic_annotation,
const NetLogWithSource& net_log)
: next_state_(STATE_NONE),
group_name_(group_name),
@@ -82,7 +83,8 @@ HttpProxyClientSocketWrapper::HttpProxyClientSocketWrapper(
: nullptr),
net_log_(NetLogWithSource::Make(
net_log.net_log(),
- NetLogSourceType::PROXY_CLIENT_SOCKET_WRAPPER)) {
+ NetLogSourceType::PROXY_CLIENT_SOCKET_WRAPPER)),
+ traffic_annotation_(traffic_annotation) {
net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE,
net_log.source().ToEventParametersCallback());
// If doing a QUIC proxy, |quic_version| must not be QUIC_VERSION_UNSUPPORTED,
@@ -570,7 +572,7 @@ int HttpProxyClientSocketWrapper::DoHttpProxyConnect() {
transport_socket_.reset(new HttpProxyClientSocket(
std::move(transport_socket_handle_), user_agent_, endpoint_,
http_auth_controller_.get(), tunnel_, using_spdy_, negotiated_protocol_,
- ssl_params_.get() != nullptr));
+ ssl_params_.get() != nullptr, traffic_annotation_));
return transport_socket_->Connect(base::Bind(
&HttpProxyClientSocketWrapper::OnIOComplete, base::Unretained(this)));
}
@@ -608,14 +610,13 @@ int HttpProxyClientSocketWrapper::DoSpdyProxyCreateStream() {
}
next_state_ = STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE;
- // TODO(https://crbug.com/656607): Add proper annotation here.
return spdy_stream_request_.StartRequest(
SPDY_BIDIRECTIONAL_STREAM, spdy_session,
GURL("https://" + endpoint_.ToString()), priority_, initial_socket_tag_,
spdy_session->net_log(),
base::Bind(&HttpProxyClientSocketWrapper::OnIOComplete,
base::Unretained(this)),
- NO_TRAFFIC_ANNOTATION_BUG_656607);
+ traffic_annotation_);
}
int HttpProxyClientSocketWrapper::DoSpdyProxyCreateStreamComplete(int result) {
@@ -653,12 +654,11 @@ int HttpProxyClientSocketWrapper::DoQuicProxyCreateStream(int result) {
next_state_ = STATE_QUIC_PROXY_CREATE_STREAM_COMPLETE;
quic_session_ = quic_stream_request_.ReleaseSessionHandle();
- // TODO(https://crbug.com/656607): Add proper annotation here.
return quic_session_->RequestStream(
false,
base::Bind(&HttpProxyClientSocketWrapper::OnIOComplete,
base::Unretained(this)),
- NO_TRAFFIC_ANNOTATION_BUG_656607);
+ traffic_annotation_);
}
int HttpProxyClientSocketWrapper::DoQuicProxyCreateStreamComplete(int result) {
diff --git a/chromium/net/http/http_proxy_client_socket_wrapper.h b/chromium/net/http/http_proxy_client_socket_wrapper.h
index 901b8ad8b3d..2e301b91072 100644
--- a/chromium/net/http/http_proxy_client_socket_wrapper.h
+++ b/chromium/net/http/http_proxy_client_socket_wrapper.h
@@ -75,6 +75,7 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper
QuicStreamFactory* quic_stream_factory,
bool is_trusted_proxy,
bool tunnel,
+ const NetworkTrafficAnnotationTag& traffic_annotation,
const NetLogWithSource& net_log);
// On destruction Disconnect() is called.
@@ -228,6 +229,9 @@ class NET_EXPORT_PRIVATE HttpProxyClientSocketWrapper
base::OneShotTimer connect_timer_;
+ // Network traffic annotation for handshaking and setup.
+ const NetworkTrafficAnnotationTag traffic_annotation_;
+
// Time when the connection to the proxy was started.
base::TimeTicks connect_start_time_;
diff --git a/chromium/net/http/http_proxy_client_socket_wrapper_unittest.cc b/chromium/net/http/http_proxy_client_socket_wrapper_unittest.cc
index 6cb23159dd9..81db6b1a542 100644
--- a/chromium/net/http/http_proxy_client_socket_wrapper_unittest.cc
+++ b/chromium/net/http/http_proxy_client_socket_wrapper_unittest.cc
@@ -29,6 +29,7 @@
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -277,7 +278,8 @@ TEST_P(HttpProxyClientSocketWrapperTest, QuicProxy) {
/*transport_params=*/nullptr, ssl_params, quic_version_, kUserAgent,
endpoint_host_port_, &http_auth_cache_, http_auth_handler_factory_.get(),
/*spdy_session_pool=*/nullptr, quic_stream_factory_.get(),
- /*is_trusted_proxy=*/false, /*tunnel=*/true, net_log_));
+ /*is_trusted_proxy=*/false, /*tunnel=*/true, TRAFFIC_ANNOTATION_FOR_TESTS,
+ net_log_));
TestCompletionCallback callback;
client_socket_wrapper_->Connect(callback.callback());
@@ -326,7 +328,8 @@ TEST_P(HttpProxyClientSocketWrapperTest, QuicProxySocketTag) {
/*transport_params=*/nullptr, ssl_params, quic_version_, kUserAgent,
endpoint_host_port_, &http_auth_cache_, http_auth_handler_factory_.get(),
/*spdy_session_pool=*/nullptr, quic_stream_factory_.get(),
- /*is_trusted_proxy=*/false, /*tunnel=*/true, net_log_));
+ /*is_trusted_proxy=*/false, /*tunnel=*/true, TRAFFIC_ANNOTATION_FOR_TESTS,
+ net_log_));
TestCompletionCallback callback;
client_socket_wrapper_->Connect(callback.callback());
diff --git a/chromium/net/http/http_response_body_drainer_unittest.cc b/chromium/net/http/http_response_body_drainer_unittest.cc
index 5ef18d73e41..ab7e7c505d2 100644
--- a/chromium/net/http/http_response_body_drainer_unittest.cc
+++ b/chromium/net/http/http_response_body_drainer_unittest.cc
@@ -28,7 +28,7 @@
#include "net/http/http_server_properties_impl.h"
#include "net/http/http_stream.h"
#include "net/http/transport_security_state.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/net/http/http_response_info.cc b/chromium/net/http/http_response_info.cc
index 106f59ecb69..8656d3ff37a 100644
--- a/chromium/net/http/http_response_info.cc
+++ b/chromium/net/http/http_response_info.cc
@@ -191,6 +191,8 @@ bool HttpResponseInfo::InitFromPickle(const base::Pickle& pickle,
ssl_info.connection_status = connection_status;
}
+ // Signed Certificate Timestamps are no longer persisted to the cache, so
+ // ignore them when reading them out.
if (flags & RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS) {
int num_scts;
if (!iter.ReadInt(&num_scts))
@@ -201,11 +203,6 @@ bool HttpResponseInfo::InitFromPickle(const base::Pickle& pickle,
uint16_t status;
if (!sct.get() || !iter.ReadUInt16(&status))
return false;
- if (!net::ct::IsValidSCTStatus(status))
- return false;
- ssl_info.signed_certificate_timestamps.push_back(
- SignedCertificateTimestampAndStatus(
- sct, static_cast<ct::SCTVerifyStatus>(status)));
}
}
@@ -305,8 +302,6 @@ void HttpResponseInfo::Persist(base::Pickle* pickle,
flags |= RESPONSE_INFO_USE_HTTP_AUTHENTICATION;
if (unused_since_prefetch)
flags |= RESPONSE_INFO_UNUSED_SINCE_PREFETCH;
- if (!ssl_info.signed_certificate_timestamps.empty())
- flags |= RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS;
if (ssl_info.pkp_bypassed)
flags |= RESPONSE_INFO_PKP_BYPASSED;
@@ -335,15 +330,6 @@ void HttpResponseInfo::Persist(base::Pickle* pickle,
pickle->WriteInt(ssl_info.security_bits);
if (ssl_info.connection_status != 0)
pickle->WriteInt(ssl_info.connection_status);
- if (!ssl_info.signed_certificate_timestamps.empty()) {
- pickle->WriteInt(ssl_info.signed_certificate_timestamps.size());
- for (SignedCertificateTimestampAndStatusList::const_iterator it =
- ssl_info.signed_certificate_timestamps.begin(); it !=
- ssl_info.signed_certificate_timestamps.end(); ++it) {
- it->sct->Persist(pickle);
- pickle->WriteUInt16(static_cast<uint16_t>(it->status));
- }
- }
}
if (vary_data.is_valid())
diff --git a/chromium/net/http/http_response_info_unittest.cc b/chromium/net/http/http_response_info_unittest.cc
index b8aadbb4a3f..d880cffbd09 100644
--- a/chromium/net/http/http_response_info_unittest.cc
+++ b/chromium/net/http/http_response_info_unittest.cc
@@ -72,35 +72,6 @@ TEST_F(HttpResponseInfoTest, PKPBypassPersistFalse) {
EXPECT_FALSE(restored_response_info.ssl_info.pkp_bypassed);
}
-TEST_F(HttpResponseInfoTest, FailsInitFromPickleWithInvalidSCTStatus) {
- // A valid certificate is needed for ssl_info.is_valid() to be true
- // so that the SCTs would be serialized.
- response_info_.ssl_info.cert =
- ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
-
- scoped_refptr<ct::SignedCertificateTimestamp> sct;
- ct::GetX509CertSCT(&sct);
-
- response_info_.ssl_info.signed_certificate_timestamps.push_back(
- SignedCertificateTimestampAndStatus(
- sct, ct::SCTVerifyStatus::SCT_STATUS_LOG_UNKNOWN));
-
- base::Pickle pickle;
- response_info_.Persist(&pickle, false, false);
- bool truncated = false;
- net::HttpResponseInfo restored_response_info;
- EXPECT_TRUE(restored_response_info.InitFromPickle(pickle, &truncated));
-
- response_info_.ssl_info.signed_certificate_timestamps.push_back(
- SignedCertificateTimestampAndStatus(sct,
- static_cast<ct::SCTVerifyStatus>(2)));
- base::Pickle pickle_invalid;
- response_info_.Persist(&pickle_invalid, false, false);
- net::HttpResponseInfo restored_invalid_response;
- EXPECT_FALSE(
- restored_invalid_response.InitFromPickle(pickle_invalid, &truncated));
-}
-
// Test that key_exchange_group is preserved for ECDHE ciphers.
TEST_F(HttpResponseInfoTest, KeyExchangeGroupECDHE) {
response_info_.ssl_info.cert =
diff --git a/chromium/net/http/http_server_properties_impl.cc b/chromium/net/http/http_server_properties_impl.cc
index 14e8ad677ba..6e915cf2595 100644
--- a/chromium/net/http/http_server_properties_impl.cc
+++ b/chromium/net/http/http_server_properties_impl.cc
@@ -22,8 +22,9 @@
namespace net {
-HttpServerPropertiesImpl::HttpServerPropertiesImpl(base::TickClock* tick_clock,
- base::Clock* clock)
+HttpServerPropertiesImpl::HttpServerPropertiesImpl(
+ const base::TickClock* tick_clock,
+ base::Clock* clock)
: tick_clock_(tick_clock ? tick_clock
: base::DefaultTickClock::GetInstance()),
clock_(clock ? clock : base::DefaultClock::GetInstance()),
diff --git a/chromium/net/http/http_server_properties_impl.h b/chromium/net/http/http_server_properties_impl.h
index e3d15e98aa2..ce89063a38b 100644
--- a/chromium/net/http/http_server_properties_impl.h
+++ b/chromium/net/http/http_server_properties_impl.h
@@ -43,7 +43,8 @@ class NET_EXPORT HttpServerPropertiesImpl
// used.
// |clock| is used for converting base::TimeTicks to base::Time for
// wherever base::Time is preferable.
- HttpServerPropertiesImpl(base::TickClock* tick_clock, base::Clock* clock);
+ HttpServerPropertiesImpl(const base::TickClock* tick_clock,
+ base::Clock* clock);
// Default clock will be used.
HttpServerPropertiesImpl();
@@ -180,8 +181,8 @@ class NET_EXPORT HttpServerPropertiesImpl
// have an entry associated with |server|, the method will add one.
void UpdateCanonicalServerInfoMap(const QuicServerId& server);
- base::TickClock* tick_clock_; // Unowned
- base::Clock* clock_; // Unowned
+ const base::TickClock* tick_clock_; // Unowned
+ base::Clock* clock_; // Unowned
SpdyServersMap spdy_servers_map_;
Http11ServerHostPortSet http11_servers_;
diff --git a/chromium/net/http/http_server_properties_impl_unittest.cc b/chromium/net/http/http_server_properties_impl_unittest.cc
index ef8e7643e1f..1b244b28d52 100644
--- a/chromium/net/http/http_server_properties_impl_unittest.cc
+++ b/chromium/net/http/http_server_properties_impl_unittest.cc
@@ -67,7 +67,7 @@ class HttpServerPropertiesImplTest : public testing::Test {
HttpServerPropertiesImplTest()
: test_task_runner_(new base::TestMockTimeTaskRunner()),
test_tick_clock_(test_task_runner_->GetMockTickClock()),
- impl_(test_tick_clock_.get(), &test_clock_) {
+ impl_(test_tick_clock_, &test_clock_) {
// Set |test_clock_| to some random time.
test_clock_.Advance(base::TimeDelta::FromSeconds(12345));
}
@@ -98,7 +98,7 @@ class HttpServerPropertiesImplTest : public testing::Test {
scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_;
- std::unique_ptr<base::TickClock> test_tick_clock_;
+ const base::TickClock* test_tick_clock_;
base::SimpleTestClock test_clock_;
HttpServerPropertiesImpl impl_;
diff --git a/chromium/net/http/http_server_properties_manager.cc b/chromium/net/http/http_server_properties_manager.cc
index 4dbb4577189..5bacee1d02e 100644
--- a/chromium/net/http/http_server_properties_manager.cc
+++ b/chromium/net/http/http_server_properties_manager.cc
@@ -106,7 +106,7 @@ HttpServerPropertiesManager::PrefDelegate::~PrefDelegate() = default;
HttpServerPropertiesManager::HttpServerPropertiesManager(
std::unique_ptr<PrefDelegate> pref_delegate,
NetLog* net_log,
- base::TickClock* clock)
+ const base::TickClock* clock)
: pref_delegate_(std::move(pref_delegate)),
clock_(clock ? clock : base::DefaultTickClock::GetInstance()),
net_log_(
diff --git a/chromium/net/http/http_server_properties_manager.h b/chromium/net/http/http_server_properties_manager.h
index 5f346262100..001392041c9 100644
--- a/chromium/net/http/http_server_properties_manager.h
+++ b/chromium/net/http/http_server_properties_manager.h
@@ -76,7 +76,7 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
// be used.
HttpServerPropertiesManager(std::unique_ptr<PrefDelegate> pref_delegate,
NetLog* net_log,
- base::TickClock* clock = nullptr);
+ const base::TickClock* clock = nullptr);
~HttpServerPropertiesManager() override;
@@ -267,7 +267,7 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
// result of them being changed by the changes just made by this class.
bool setting_prefs_ = false;
- base::TickClock* clock_; // Unowned
+ const base::TickClock* clock_; // Unowned
// Set to true once the initial prefs have been loaded.
bool is_initialized_ = false;
diff --git a/chromium/net/http/http_server_properties_manager_unittest.cc b/chromium/net/http/http_server_properties_manager_unittest.cc
index 20e835cf060..30f9fe0afc8 100644
--- a/chromium/net/http/http_server_properties_manager_unittest.cc
+++ b/chromium/net/http/http_server_properties_manager_unittest.cc
@@ -114,8 +114,7 @@ class HttpServerPropertiesManagerTest : public testing::TestWithParam<int> {
advertised_versions_ = HttpNetworkSession::Params().quic_supported_versions;
pref_delegate_ = new MockPrefDelegate;
- clock_ = test_task_runner_->GetMockTickClock();
- net_test_task_runner_clock_ = clock_.get();
+ net_test_task_runner_clock_ = test_task_runner_->GetMockTickClock();
http_server_props_manager_ = std::make_unique<HttpServerPropertiesManager>(
base::WrapUnique(pref_delegate_), /*net_log=*/nullptr,
net_test_task_runner_clock_);
@@ -151,11 +150,7 @@ class HttpServerPropertiesManagerTest : public testing::TestWithParam<int> {
// Overrides the main thread's message loop with a mock tick clock.
base::ScopedMockTimeMessageLoopTaskRunner test_task_runner_;
- // TODO(tzik): Remove |clock_| after updating GetMockTickClock to own the
- // instance.
- std::unique_ptr<base::TickClock> clock_;
-
- base::TickClock* net_test_task_runner_clock_;
+ const base::TickClock* net_test_task_runner_clock_;
private:
DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesManagerTest);
diff --git a/chromium/net/http/http_status_code_list.h b/chromium/net/http/http_status_code_list.h
index 75c2304c5bd..53f633cbbf6 100644
--- a/chromium/net/http/http_status_code_list.h
+++ b/chromium/net/http/http_status_code_list.h
@@ -3,8 +3,10 @@
// found in the LICENSE file.
// This file intentionally does not have header guards, it's included
-// inside a macro to generate enum.
-//
+// inside a macro to generate enum. The following line silences a
+// presubmit warning that would otherwise be triggered by this:
+// no-include-guard-because-multiply-included
+
// This file contains the list of HTTP status codes. Taken from IANA HTTP Status
// Code Registry.
// http://www.iana.org/assignments/http-status-codes/http-status-codes.xml
diff --git a/chromium/net/http/http_stream_factory.h b/chromium/net/http/http_stream_factory.h
index fe5d77ad9be..a70896cb9c0 100644
--- a/chromium/net/http/http_stream_factory.h
+++ b/chromium/net/http/http_stream_factory.h
@@ -16,8 +16,11 @@
#include "net/base/load_states.h"
#include "net/base/net_export.h"
#include "net/base/request_priority.h"
+#include "net/http/http_request_info.h"
#include "net/http/http_server_properties.h"
-#include "net/socket/connection_attempts.h"
+#include "net/http/http_stream_request.h"
+#include "net/log/net_log_with_source.h"
+#include "net/ssl/ssl_config.h"
// This file can be included from net/http even though
// it is in net/websockets because it doesn't
// introduce any link dependency to net/websockets.
@@ -31,164 +34,9 @@ class ProcessMemoryDump;
namespace net {
-class BidirectionalStreamImpl;
class HostMappingRules;
-class HttpAuthController;
class HttpNetworkSession;
class HttpResponseHeaders;
-class HttpResponseInfo;
-class HttpStream;
-class NetLogWithSource;
-class ProxyInfo;
-class SSLCertRequestInfo;
-class SSLInfo;
-struct HttpRequestInfo;
-struct SSLConfig;
-
-// The HttpStreamRequest is the client's handle to the worker object which
-// handles the creation of an HttpStream. While the HttpStream is being
-// created, this object is the creator's handle for interacting with the
-// HttpStream creation process. The request is cancelled by deleting it, after
-// which no callbacks will be invoked.
-class NET_EXPORT_PRIVATE HttpStreamRequest {
- public:
- // Indicates which type of stream is requested.
- enum StreamType {
- BIDIRECTIONAL_STREAM,
- HTTP_STREAM,
- };
-
- // The HttpStreamRequest::Delegate is a set of callback methods for a
- // HttpStreamRequestJob. Generally, only one of these methods will be
- // called as a result of a stream request.
- class NET_EXPORT_PRIVATE Delegate {
- public:
- virtual ~Delegate() {}
-
- // This is the success case for RequestStream.
- // |stream| is now owned by the delegate.
- // |used_ssl_config| indicates the actual SSL configuration used for this
- // stream, since the HttpStreamRequest may have modified the configuration
- // during stream processing.
- // |used_proxy_info| indicates the actual ProxyInfo used for this stream,
- // since the HttpStreamRequest performs the proxy resolution.
- virtual void OnStreamReady(const SSLConfig& used_ssl_config,
- const ProxyInfo& used_proxy_info,
- std::unique_ptr<HttpStream> stream) = 0;
-
- // This is the success case for RequestWebSocketHandshakeStream.
- // |stream| is now owned by the delegate.
- // |used_ssl_config| indicates the actual SSL configuration used for this
- // stream, since the HttpStreamRequest may have modified the configuration
- // during stream processing.
- // |used_proxy_info| indicates the actual ProxyInfo used for this stream,
- // since the HttpStreamRequest performs the proxy resolution.
- virtual void OnWebSocketHandshakeStreamReady(
- const SSLConfig& used_ssl_config,
- const ProxyInfo& used_proxy_info,
- std::unique_ptr<WebSocketHandshakeStreamBase> stream) = 0;
-
- virtual void OnBidirectionalStreamImplReady(
- const SSLConfig& used_ssl_config,
- const ProxyInfo& used_proxy_info,
- std::unique_ptr<BidirectionalStreamImpl> stream) = 0;
-
- // This is the failure to create a stream case.
- // |used_ssl_config| indicates the actual SSL configuration used for this
- // stream, since the HttpStreamRequest may have modified the configuration
- // during stream processing.
- virtual void OnStreamFailed(int status,
- const NetErrorDetails& net_error_details,
- const SSLConfig& used_ssl_config) = 0;
-
- // Called when we have a certificate error for the request.
- // |used_ssl_config| indicates the actual SSL configuration used for this
- // stream, since the HttpStreamRequest may have modified the configuration
- // during stream processing.
- virtual void OnCertificateError(int status,
- const SSLConfig& used_ssl_config,
- const SSLInfo& ssl_info) = 0;
-
- // This is the failure case where we need proxy authentication during
- // proxy tunnel establishment. For the tunnel case, we were unable to
- // create the HttpStream, so the caller provides the auth and then resumes
- // the HttpStreamRequest.
- //
- // For the non-tunnel case, the caller will discover the authentication
- // failure when reading response headers. At that point, it will handle the
- // authentication failure and restart the HttpStreamRequest entirely.
- //
- // Ownership of |auth_controller| and |proxy_response| are owned
- // by the HttpStreamRequest. |proxy_response| is not guaranteed to be usable
- // after the lifetime of this callback. The delegate may take a reference
- // to |auth_controller| if it is needed beyond the lifetime of this
- // callback.
- //
- // |used_ssl_config| indicates the actual SSL configuration used for this
- // stream, since the HttpStreamRequest may have modified the configuration
- // during stream processing.
- virtual void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response,
- const SSLConfig& used_ssl_config,
- const ProxyInfo& used_proxy_info,
- HttpAuthController* auth_controller) = 0;
-
- // This is the failure for SSL Client Auth
- // Ownership of |cert_info| is retained by the HttpStreamRequest. The
- // delegate may take a reference if it needs the cert_info beyond the
- // lifetime of this callback.
- virtual void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
- SSLCertRequestInfo* cert_info) = 0;
-
- // This is the failure of the CONNECT request through an HTTPS proxy.
- // Headers can be read from |response_info|, while the body can be read
- // from |stream|.
- //
- // |used_ssl_config| indicates the actual SSL configuration used for this
- // stream, since the HttpStreamRequest may have modified the configuration
- // during stream processing.
- //
- // |used_proxy_info| indicates the actual ProxyInfo used for this stream,
- // since the HttpStreamRequest performs the proxy resolution.
- //
- // Ownership of |stream| is transferred to the delegate.
- virtual void OnHttpsProxyTunnelResponse(
- const HttpResponseInfo& response_info,
- const SSLConfig& used_ssl_config,
- const ProxyInfo& used_proxy_info,
- std::unique_ptr<HttpStream> stream) = 0;
-
- // Called when finding all QUIC alternative services are marked broken for
- // the origin in this request which advertises supporting QUIC.
- virtual void OnQuicBroken() = 0;
- };
-
- virtual ~HttpStreamRequest() {}
-
- // When a HttpStream creation process is stalled due to necessity
- // of Proxy authentication credentials, the delegate OnNeedsProxyAuth
- // will have been called. It now becomes the delegate's responsibility
- // to collect the necessary credentials, and then call this method to
- // resume the HttpStream creation process.
- virtual int RestartTunnelWithProxyAuth() = 0;
-
- // Called when the priority of the parent transaction changes.
- virtual void SetPriority(RequestPriority priority) = 0;
-
- // Returns the LoadState for the request.
- virtual LoadState GetLoadState() const = 0;
-
- // Returns true if TLS/ALPN was negotiated for this stream.
- virtual bool was_alpn_negotiated() const = 0;
-
- // Protocol negotiated with the server.
- virtual NextProto negotiated_protocol() const = 0;
-
- // Returns true if this stream is being fetched over SPDY.
- virtual bool using_spdy() const = 0;
-
- // Returns socket-layer connection attempts made for this stream request.
- virtual const ConnectionAttempts& connection_attempts() const = 0;
-};
// The HttpStreamFactory defines an interface for creating usable HttpStreams.
class NET_EXPORT HttpStreamFactory {
diff --git a/chromium/net/http/http_stream_factory_impl.cc b/chromium/net/http/http_stream_factory_impl.cc
index 1374a69be2d..3a4c197b0f8 100644
--- a/chromium/net/http/http_stream_factory_impl.cc
+++ b/chromium/net/http/http_stream_factory_impl.cc
@@ -19,7 +19,6 @@
#include "net/http/http_server_properties.h"
#include "net/http/http_stream_factory_impl_job.h"
#include "net/http/http_stream_factory_impl_job_controller.h"
-#include "net/http/http_stream_factory_impl_request.h"
#include "net/http/transport_security_state.h"
#include "net/proxy_resolution/proxy_info.h"
#include "net/quic/core/quic_server_id.h"
@@ -120,9 +119,6 @@ void HttpStreamFactoryImpl::PreconnectStreams(
SSLConfig server_ssl_config;
SSLConfig proxy_ssl_config;
session_->GetSSLConfig(request_info, &server_ssl_config, &proxy_ssl_config);
- // All preconnects should perform EV certificate verification.
- server_ssl_config.verify_ev_cert = true;
- proxy_ssl_config.verify_ev_cert = true;
auto job_controller = std::make_unique<JobController>(
this, nullptr, session_, job_factory_.get(), request_info,
diff --git a/chromium/net/http/http_stream_factory_impl.h b/chromium/net/http/http_stream_factory_impl.h
index d34696ba32c..aa8c5d15c9d 100644
--- a/chromium/net/http/http_stream_factory_impl.h
+++ b/chromium/net/http/http_stream_factory_impl.h
@@ -10,6 +10,7 @@
#include <map>
#include <memory>
#include <set>
+#include <string>
#include "base/gtest_prod_util.h"
#include "base/macros.h"
@@ -20,6 +21,7 @@
#include "net/base/proxy_server.h"
#include "net/base/request_priority.h"
#include "net/http/http_stream_factory.h"
+#include "net/http/http_stream_request.h"
#include "net/log/net_log_source.h"
#include "net/socket/ssl_client_socket.h"
#include "net/spdy/chromium/spdy_session_key.h"
@@ -35,7 +37,6 @@ class NET_EXPORT_PRIVATE HttpStreamFactoryImpl : public HttpStreamFactory {
class NET_EXPORT_PRIVATE Job;
class NET_EXPORT_PRIVATE JobController;
class NET_EXPORT_PRIVATE JobFactory;
- class NET_EXPORT_PRIVATE Request;
HttpStreamFactoryImpl(HttpNetworkSession* session);
~HttpStreamFactoryImpl() override;
@@ -83,8 +84,7 @@ class NET_EXPORT_PRIVATE HttpStreamFactoryImpl : public HttpStreamFactory {
};
private:
- FRIEND_TEST_ALL_PREFIXES(HttpStreamFactoryImplRequestTest, SetPriority);
- FRIEND_TEST_ALL_PREFIXES(HttpStreamFactoryImplRequestTest, DelayMainJob);
+ FRIEND_TEST_ALL_PREFIXES(HttpStreamRequestTest, SetPriority);
friend class HttpStreamFactoryImplPeer;
diff --git a/chromium/net/http/http_stream_factory_impl_job.cc b/chromium/net/http/http_stream_factory_impl_job.cc
index b65df255f4c..28e6bb4dd23 100644
--- a/chromium/net/http/http_stream_factory_impl_job.cc
+++ b/chromium/net/http/http_stream_factory_impl_job.cc
@@ -34,7 +34,8 @@
#include "net/http/http_request_info.h"
#include "net/http/http_server_properties.h"
#include "net/http/http_stream_factory.h"
-#include "net/http/http_stream_factory_impl_request.h"
+#include "net/http/proxy_fallback.h"
+#include "net/log/net_log.h"
#include "net/log/net_log_capture_mode.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_source.h"
@@ -255,6 +256,11 @@ HttpStreamFactoryImpl::Job::Job(Delegate* delegate,
if (job_type_ == PRECONNECT || is_websocket_) {
DCHECK(request_info_.socket_tag == SocketTag());
}
+ if (is_websocket_) {
+ DCHECK(origin_url_.SchemeIsWSOrWSS());
+ } else {
+ DCHECK(!origin_url_.SchemeIsWSOrWSS());
+ }
}
HttpStreamFactoryImpl::Job::~Job() {
@@ -1048,8 +1054,14 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) {
net_log_.AddEvent(
NetLogEventType::HTTP_STREAM_REQUEST_PROTO,
base::Bind(&NetLogHttpStreamProtoCallback, negotiated_protocol_));
- if (negotiated_protocol_ == kProtoHTTP2)
+ if (negotiated_protocol_ == kProtoHTTP2) {
+ if (is_websocket_) {
+ // WebSocket is not supported over a fresh HTTP/2 connection.
+ return ERR_NOT_IMPLEMENTED;
+ }
+
using_spdy_ = true;
+ }
}
}
} else if (proxy_info_.is_https() && connection_->socket() &&
@@ -1075,7 +1087,7 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) {
// complete the auth (or read the response body). The tunnel restart code
// is careful to remove it before returning control to the rest of this
// class.
- connection_.reset(connection_->release_pending_http_proxy_connection());
+ connection_ = connection_->release_pending_http_proxy_connection();
return result;
}
@@ -1203,7 +1215,8 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
DCHECK(delegate_->websocket_handshake_stream_create_helper());
websocket_stream_ =
delegate_->websocket_handshake_stream_create_helper()
- ->CreateBasicStream(std::move(connection_), using_proxy);
+ ->CreateBasicStream(std::move(connection_), using_proxy,
+ session_->websocket_endpoint_lock_manager());
} else {
stream_ = std::make_unique<HttpBasicStream>(
std::move(connection_), using_proxy,
@@ -1217,6 +1230,12 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
// It is possible that a pushed stream has been opened by a server since last
// time Job checked above.
if (!existing_spdy_session_) {
+ // WebSocket over HTTP/2 is only allowed to use existing HTTP/2 connections.
+ // Therefore |using_spdy_| could not have been set unless a connection had
+ // already been found.
+ // TODO(bnc): Change to DCHECK once https://crbug.com/819101 is fixed.
+ CHECK(!try_websocket_over_http2_);
+
session_->spdy_session_pool()->push_promise_index()->ClaimPushedStream(
spdy_session_key_, origin_url_, request_info_, &existing_spdy_session_,
&pushed_stream_id_);
@@ -1358,52 +1377,15 @@ void HttpStreamFactoryImpl::Job::InitSSLConfig(SSLConfig* ssl_config,
ssl_config->false_start_enabled = false;
}
- if (request_info_.load_flags & LOAD_VERIFY_EV_CERT)
- ssl_config->verify_ev_cert = true;
-
// Disable Channel ID if privacy mode is enabled.
if (request_info_.privacy_mode == PRIVACY_MODE_ENABLED)
ssl_config->channel_id_enabled = false;
}
int HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError(int error) {
- switch (error) {
- case ERR_PROXY_CONNECTION_FAILED:
- case ERR_NAME_NOT_RESOLVED:
- case ERR_INTERNET_DISCONNECTED:
- case ERR_ADDRESS_UNREACHABLE:
- case ERR_CONNECTION_CLOSED:
- case ERR_CONNECTION_TIMED_OUT:
- case ERR_CONNECTION_RESET:
- case ERR_CONNECTION_REFUSED:
- case ERR_CONNECTION_ABORTED:
- case ERR_TIMED_OUT:
- case ERR_TUNNEL_CONNECTION_FAILED:
- case ERR_SOCKS_CONNECTION_FAILED:
- // ERR_PROXY_CERTIFICATE_INVALID can happen in the case of trying to talk to
- // a proxy using SSL, and ending up talking to a captive portal that
- // supports SSL instead.
- case ERR_PROXY_CERTIFICATE_INVALID:
- case ERR_QUIC_PROTOCOL_ERROR:
- case ERR_QUIC_HANDSHAKE_FAILED:
- case ERR_MSG_TOO_BIG:
- // ERR_SSL_PROTOCOL_ERROR can happen when trying to talk SSL to a non-SSL
- // server (like a captive portal).
- case ERR_SSL_PROTOCOL_ERROR:
- break;
- case ERR_SOCKS_CONNECTION_HOST_UNREACHABLE:
- // Remap the SOCKS-specific "host unreachable" error to a more
- // generic error code (this way consumers like the link doctor
- // know to substitute their error page).
- //
- // Note that if the host resolving was done by the SOCKS5 proxy, we can't
- // differentiate between a proxy-side "host not found" versus a proxy-side
- // "address unreachable" error, and will report both of these failures as
- // ERR_ADDRESS_UNREACHABLE.
- return ERR_ADDRESS_UNREACHABLE;
- default:
- return error;
- }
+ // Check if the error was a proxy failure.
+ if (!CanFalloverToNextProxy(&error))
+ return error;
// Alternative proxy server job should not use fallback proxies, and instead
// return. This would resume the main job (if possible) which may try the
diff --git a/chromium/net/http/http_stream_factory_impl_job.h b/chromium/net/http/http_stream_factory_impl_job.h
index 2cee70516ea..3dd4f48398e 100644
--- a/chromium/net/http/http_stream_factory_impl_job.h
+++ b/chromium/net/http/http_stream_factory_impl_job.h
@@ -21,8 +21,9 @@
#include "net/http/http_auth_controller.h"
#include "net/http/http_request_info.h"
#include "net/http/http_stream_factory_impl.h"
+#include "net/http/http_stream_request.h"
#include "net/log/net_log_with_source.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/quic/chromium/quic_stream_factory.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/client_socket_pool_manager.h"
@@ -47,8 +48,8 @@ class SpdySessionPool;
class NetLog;
struct SSLConfig;
-// An HttpStreamRequestImpl exists for each stream which is in progress of being
-// created for the StreamFactory.
+// An HttpStreamRequest exists for each stream which is in progress of being
+// created for the HttpStreamFactory.
class HttpStreamFactoryImpl::Job {
public:
// For jobs issued simultaneously to an HTTP/2 supported server, a delay is
@@ -56,7 +57,7 @@ class HttpStreamFactoryImpl::Job {
// crbug.com/718576
static const int kHTTP2ThrottleMs = 300;
- // Delegate to report Job's status to Request and HttpStreamFactory.
+ // Delegate to report Job's status to HttpStreamRequest and HttpStreamFactory.
class NET_EXPORT_PRIVATE Delegate {
public:
virtual ~Delegate() {}
@@ -82,7 +83,7 @@ class HttpStreamFactoryImpl::Job {
int status,
const SSLConfig& used_ssl_config) = 0;
- // Invoked when |job| has a certificate error for the Request.
+ // Invoked when |job| has a certificate error for the HttpStreamRequest.
virtual void OnCertificateError(Job* job,
int status,
const SSLConfig& used_ssl_config,
@@ -113,8 +114,8 @@ class HttpStreamFactoryImpl::Job {
// contained in |proxy_info| can be skipped.
virtual bool OnInitConnection(const ProxyInfo& proxy_info) = 0;
- // Invoked to notify the Request and Factory of the readiness of new
- // SPDY session.
+ // Invoked to notify the HttpStreamRequest and HttpStreamFactory of the
+ // readiness of new SPDY session.
virtual void OnNewSpdySessionReady(
Job* job,
const base::WeakPtr<SpdySession>& spdy_session) = 0;
@@ -123,7 +124,7 @@ class HttpStreamFactoryImpl::Job {
virtual void OnPreconnectsComplete(Job* job) = 0;
// Invoked to record connection attempts made by the socket layer to
- // Request if |job| is associated with Request.
+ // HttpStreamRequest if |job| is associated with HttpStreamRequest.
virtual void AddConnectionAttemptsToRequest(
Job* job,
const ConnectionAttempts& attempts) = 0;
@@ -136,9 +137,9 @@ class HttpStreamFactoryImpl::Job {
virtual bool ShouldWait(Job* job) = 0;
// Called when |job| determines the appropriate |spdy_session_key| for the
- // Request. Note that this does not mean that SPDY is necessarily supported
- // for this SpdySessionKey, since we may need to wait for NPN to complete
- // before knowing if SPDY is available.
+ // HttpStreamRequest. Note that this does not mean that HTTP/2 is
+ // necessarily supported for this SpdySessionKey, since we may need to wait
+ // for ALPN negotiation to complete before knowing if HTTP/2 is available.
virtual void SetSpdySessionKey(Job* job,
const SpdySessionKey& spdy_session_key) = 0;
@@ -224,8 +225,6 @@ class HttpStreamFactoryImpl::Job {
std::unique_ptr<HttpStream> ReleaseStream() { return std::move(stream_); }
- void SetStream(HttpStream* http_stream) { stream_.reset(http_stream); }
-
std::unique_ptr<BidirectionalStreamImpl> ReleaseBidirectionalStream() {
return std::move(bidirectional_stream_impl_);
}
diff --git a/chromium/net/http/http_stream_factory_impl_job_controller.cc b/chromium/net/http/http_stream_factory_impl_job_controller.cc
index 14e494d3510..33f6e0a23a2 100644
--- a/chromium/net/http/http_stream_factory_impl_job_controller.cc
+++ b/chromium/net/http/http_stream_factory_impl_job_controller.cc
@@ -17,6 +17,7 @@
#include "net/base/host_mapping_rules.h"
#include "net/http/bidirectional_stream_impl.h"
#include "net/http/transport_security_state.h"
+#include "net/log/net_log.h"
#include "net/log/net_log_capture_mode.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_source.h"
@@ -113,8 +114,7 @@ HttpStreamFactoryImpl::JobController::~JobController() {
net_log_.EndEvent(NetLogEventType::HTTP_STREAM_JOB_CONTROLLER);
}
-std::unique_ptr<HttpStreamFactoryImpl::Request>
-HttpStreamFactoryImpl::JobController::Start(
+std::unique_ptr<HttpStreamRequest> HttpStreamFactoryImpl::JobController::Start(
HttpStreamRequest::Delegate* delegate,
WebSocketHandshakeStreamBase::CreateHelper*
websocket_handshake_stream_create_helper,
@@ -127,10 +127,10 @@ HttpStreamFactoryImpl::JobController::Start(
stream_type_ = stream_type;
priority_ = priority;
- auto request = std::make_unique<Request>(
+ auto request = std::make_unique<HttpStreamRequest>(
request_info_.url, this, delegate,
websocket_handshake_stream_create_helper, source_net_log, stream_type);
- // Keep a raw pointer but release ownership of Request instance.
+ // Keep a raw pointer but release ownership of HttpStreamRequest instance.
request_ = request.get();
// Associates |net_log_| with |source_net_log|.
@@ -243,7 +243,8 @@ void HttpStreamFactoryImpl::JobController::OnStreamReady(
factory_->OnStreamReady(job->proxy_info(), request_info_.privacy_mode);
if (IsJobOrphaned(job)) {
- // We have bound a job to the associated Request, |job| has been orphaned.
+ // We have bound a job to the associated HttpStreamRequest, |job| has been
+ // orphaned.
OnOrphanedJobComplete(job);
return;
}
@@ -270,7 +271,8 @@ void HttpStreamFactoryImpl::JobController::OnBidirectionalStreamImplReady(
DCHECK(job);
if (IsJobOrphaned(job)) {
- // We have bound a job to the associated Request, |job| has been orphaned.
+ // We have bound a job to the associated HttpStreamRequest, |job| has been
+ // orphaned.
OnOrphanedJobComplete(job);
return;
}
@@ -329,7 +331,8 @@ void HttpStreamFactoryImpl::JobController::OnStreamFailed(
MaybeResumeMainJob(job, base::TimeDelta());
if (IsJobOrphaned(job)) {
- // We have bound a job to the associated Request, |job| has been orphaned.
+ // We have bound a job to the associated HttpStreamRequest, |job| has been
+ // orphaned.
OnOrphanedJobComplete(job);
return;
}
@@ -374,7 +377,8 @@ void HttpStreamFactoryImpl::JobController::OnCertificateError(
MaybeResumeMainJob(job, base::TimeDelta());
if (IsJobOrphaned(job)) {
- // We have bound a job to the associated Request, |job| has been orphaned.
+ // We have bound a job to the associated HttpStreamRequest, |job| has been
+ // orphaned.
OnOrphanedJobComplete(job);
return;
}
@@ -397,7 +401,8 @@ void HttpStreamFactoryImpl::JobController::OnHttpsProxyTunnelResponse(
MaybeResumeMainJob(job, base::TimeDelta());
if (IsJobOrphaned(job)) {
- // We have bound a job to the associated Request, |job| has been orphaned.
+ // We have bound a job to the associated HttpStreamRequest, |job| has been
+ // orphaned.
OnOrphanedJobComplete(job);
return;
}
@@ -417,7 +422,8 @@ void HttpStreamFactoryImpl::JobController::OnNeedsClientAuth(
MaybeResumeMainJob(job, base::TimeDelta());
if (IsJobOrphaned(job)) {
- // We have bound a job to the associated Request, |job| has been orphaned.
+ // We have bound a job to the associated HttpStreamRequest, |job| has been
+ // orphaned.
OnOrphanedJobComplete(job);
return;
}
@@ -438,7 +444,8 @@ void HttpStreamFactoryImpl::JobController::OnNeedsProxyAuth(
MaybeResumeMainJob(job, base::TimeDelta());
if (IsJobOrphaned(job)) {
- // We have bound a job to the associated Request, |job| has been orphaned.
+ // We have bound a job to the associated HttpStreamRequest, |job| has been
+ // orphaned.
OnOrphanedJobComplete(job);
return;
}
diff --git a/chromium/net/http/http_stream_factory_impl_job_controller.h b/chromium/net/http/http_stream_factory_impl_job_controller.h
index 0026ec5b45b..d378d23f161 100644
--- a/chromium/net/http/http_stream_factory_impl_job_controller.h
+++ b/chromium/net/http/http_stream_factory_impl_job_controller.h
@@ -6,12 +6,13 @@
#define NET_HTTP_HTTP_STREAM_FACTORY_IMPL_JOB_CONTROLLER_H_
#include <memory>
+#include <string>
#include "base/cancelable_callback.h"
#include "net/base/host_port_pair.h"
#include "net/base/privacy_mode.h"
#include "net/http/http_stream_factory_impl_job.h"
-#include "net/http/http_stream_factory_impl_request.h"
+#include "net/http/http_stream_request.h"
#include "net/socket/next_proto.h"
namespace net {
@@ -27,7 +28,7 @@ class JobControllerPeer;
// HttpStreamFactoryImpl::JobController manages Request and Job(s).
class HttpStreamFactoryImpl::JobController
: public HttpStreamFactoryImpl::Job::Delegate,
- public HttpStreamFactoryImpl::Request::Helper {
+ public HttpStreamRequest::Helper {
public:
JobController(HttpStreamFactoryImpl* factory,
HttpStreamRequest::Delegate* delegate,
@@ -52,16 +53,17 @@ class HttpStreamFactoryImpl::JobController
// Methods below are called by HttpStreamFactoryImpl only.
// Creates request and hands out to HttpStreamFactoryImpl, this will also
// create Job(s) and start serving the created request.
- std::unique_ptr<Request> Start(HttpStreamRequest::Delegate* delegate,
- WebSocketHandshakeStreamBase::CreateHelper*
- websocket_handshake_stream_create_helper,
- const NetLogWithSource& source_net_log,
- HttpStreamRequest::StreamType stream_type,
- RequestPriority priority);
+ std::unique_ptr<HttpStreamRequest> Start(
+ HttpStreamRequest::Delegate* delegate,
+ WebSocketHandshakeStreamBase::CreateHelper*
+ websocket_handshake_stream_create_helper,
+ const NetLogWithSource& source_net_log,
+ HttpStreamRequest::StreamType stream_type,
+ RequestPriority priority);
void Preconnect(int num_streams);
- // From HttpStreamFactoryImpl::Request::Helper.
+ // From HttpStreamRequest::Helper.
// Returns the LoadState for Request.
LoadState GetLoadState() const override;
@@ -319,7 +321,7 @@ class HttpStreamFactoryImpl::JobController
// reference and is safe as |request_| will notify |this| JobController
// when it's destructed by calling OnRequestComplete(), which nulls
// |request_|.
- Request* request_;
+ HttpStreamRequest* request_;
HttpStreamRequest::Delegate* const delegate_;
diff --git a/chromium/net/http/http_stream_factory_impl_job_controller_unittest.cc b/chromium/net/http/http_stream_factory_impl_job_controller_unittest.cc
index a89bb0e1045..9b1d02fd1e8 100644
--- a/chromium/net/http/http_stream_factory_impl_job_controller_unittest.cc
+++ b/chromium/net/http/http_stream_factory_impl_job_controller_unittest.cc
@@ -4,6 +4,8 @@
#include "net/http/http_stream_factory_impl_job_controller.h"
+#include <algorithm>
+#include <list>
#include <string>
#include <utility>
#include <vector>
@@ -23,7 +25,6 @@
#include "net/http/http_network_session_peer.h"
#include "net/http/http_stream_factory_impl.h"
#include "net/http/http_stream_factory_impl_job.h"
-#include "net/http/http_stream_factory_impl_request.h"
#include "net/http/http_stream_factory_test_util.h"
#include "net/log/net_log_with_source.h"
#include "net/log/test_net_log.h"
@@ -32,7 +33,7 @@
#include "net/proxy_resolution/mock_proxy_resolver.h"
#include "net/proxy_resolution/proxy_config_service_fixed.h"
#include "net/proxy_resolution/proxy_info.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/quic/chromium/mock_crypto_client_stream_factory.h"
#include "net/quic/chromium/mock_quic_data.h"
#include "net/quic/chromium/quic_stream_factory.h"
@@ -42,6 +43,7 @@
#include "net/socket/socket_test_util.h"
#include "net/spdy/chromium/spdy_test_util_common.h"
#include "net/test/net_test_suite.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gmock_mutant.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -87,11 +89,10 @@ class FailingProxyResolverFactory : public ProxyResolverFactory {
FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
// ProxyResolverFactory override.
- int CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& script_data,
- std::unique_ptr<ProxyResolver>* result,
- const CompletionCallback& callback,
- std::unique_ptr<Request>* request) override {
+ int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
+ std::unique_ptr<ProxyResolver>* result,
+ const CompletionCallback& callback,
+ std::unique_ptr<Request>* request) override {
return ERR_PAC_SCRIPT_FAILED;
}
};
@@ -162,6 +163,11 @@ class HttpStreamFactoryImplJobPeer {
static void SetShouldReconsiderProxy(HttpStreamFactoryImpl::Job* job) {
job->should_reconsider_proxy_ = true;
}
+
+ static void SetStream(HttpStreamFactoryImpl::Job* job,
+ std::unique_ptr<HttpStream> http_stream) {
+ job->stream_ = std::move(http_stream);
+ }
};
class JobControllerPeer {
@@ -233,8 +239,9 @@ class HttpStreamFactoryImplJobControllerTest : public ::testing::Test {
if (use_alternative_proxy_) {
std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
ProxyResolutionService::CreateFixedFromPacResult(
- "HTTPS myproxy.org:443");
- session_deps_.proxy_resolution_service = std::move(proxy_resolution_service);
+ "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
+ session_deps_.proxy_resolution_service =
+ std::move(proxy_resolution_service);
}
session_deps_.net_log = net_log_.bound().net_log();
HttpNetworkSession::Params params =
@@ -304,7 +311,7 @@ class HttpStreamFactoryImplJobControllerTest : public ::testing::Test {
std::unique_ptr<HttpNetworkSession> session_;
HttpStreamFactoryImpl* factory_ = nullptr;
HttpStreamFactoryImpl::JobController* job_controller_ = nullptr;
- std::unique_ptr<HttpStreamFactoryImpl::Request> request_;
+ std::unique_ptr<HttpStreamRequest> request_;
std::unique_ptr<SequencedSocketData> tcp_data_;
std::unique_ptr<MockQuicData> quic_data_;
MockCryptoClientStreamFactory crypto_client_stream_factory_;
@@ -338,7 +345,8 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, ProxyResolutionFailsSync) {
proxy_config.set_pac_url(GURL("http://fooproxyurl"));
proxy_config.set_pac_mandatory(true);
session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
- std::make_unique<ProxyConfigServiceFixed>(proxy_config),
+ std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
+ proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
std::make_unique<FailingProxyResolverFactory>(), nullptr));
HttpRequestInfo request_info;
request_info.method = "GET";
@@ -373,7 +381,8 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, ProxyResolutionFailsAsync) {
new MockAsyncProxyResolverFactory(false);
MockAsyncProxyResolver resolver;
session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
- std::make_unique<ProxyConfigServiceFixed>(proxy_config),
+ std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
+ proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
base::WrapUnique(proxy_resolver_factory), nullptr));
HttpRequestInfo request_info;
request_info.method = "GET";
@@ -403,7 +412,8 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, ProxyResolutionFailsAsync) {
TEST_F(HttpStreamFactoryImplJobControllerTest, NoSupportedProxies) {
session_deps_.proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("QUIC myproxy.org:443");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
session_deps_.enable_quic = false;
HttpRequestInfo request_info;
request_info.method = "GET";
@@ -429,10 +439,12 @@ class JobControllerReconsiderProxyAfterErrorTest
: public HttpStreamFactoryImplJobControllerTest,
public ::testing::WithParamInterface<::testing::tuple<bool, int>> {
public:
- void Initialize(std::unique_ptr<ProxyResolutionService> proxy_resolution_service,
- std::unique_ptr<ProxyDelegate> proxy_delegate) {
+ void Initialize(
+ std::unique_ptr<ProxyResolutionService> proxy_resolution_service,
+ std::unique_ptr<ProxyDelegate> proxy_delegate) {
session_deps_.proxy_delegate = std::move(proxy_delegate);
- session_deps_.proxy_resolution_service = std::move(proxy_resolution_service);
+ session_deps_.proxy_resolution_service =
+ std::move(proxy_resolution_service);
session_ = std::make_unique<HttpNetworkSession>(
SpdySessionDependencies::CreateSessionParams(&session_deps_),
SpdySessionDependencies::CreateSessionContext(&session_deps_));
@@ -471,12 +483,14 @@ TEST_P(JobControllerReconsiderProxyAfterErrorTest, ReconsiderProxyAfterError) {
const int mock_error = ::testing::get<1>(GetParam());
std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
ProxyResolutionService::CreateFixedFromPacResult(
- "HTTPS badproxy:99; HTTPS badfallbackproxy:98; DIRECT");
+ "HTTPS badproxy:99; HTTPS badfallbackproxy:98; DIRECT",
+ TRAFFIC_ANNOTATION_FOR_TESTS);
auto test_proxy_delegate = std::make_unique<TestProxyDelegate>();
TestProxyDelegate* test_proxy_delegate_raw = test_proxy_delegate.get();
// Before starting the test, verify that there are no proxies marked as bad.
- ASSERT_TRUE(proxy_resolution_service->proxy_retry_info().empty()) << mock_error;
+ ASSERT_TRUE(proxy_resolution_service->proxy_retry_info().empty())
+ << mock_error;
StaticSocketDataProvider socket_data_proxy_main_job;
socket_data_proxy_main_job.set_connect_data(MockConnect(ASYNC, mock_error));
@@ -524,7 +538,8 @@ TEST_P(JobControllerReconsiderProxyAfterErrorTest, ReconsiderProxyAfterError) {
request_info.method = "GET";
request_info.url = GURL("http://www.example.com");
- Initialize(std::move(proxy_resolution_service), std::move(test_proxy_delegate));
+ Initialize(std::move(proxy_resolution_service),
+ std::move(test_proxy_delegate));
EXPECT_EQ(set_alternative_proxy_server,
test_proxy_delegate_raw->alternative_proxy_server().is_quic());
@@ -572,13 +587,14 @@ TEST_F(JobControllerReconsiderProxyAfterErrorTest,
// Configure the proxies and initialize the test.
std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
ProxyResolutionService::CreateFixedFromPacResult(
- "HTTPS myproxy.org:443; DIRECT");
+ "HTTPS myproxy.org:443; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS);
auto test_proxy_delegate = std::make_unique<TestProxyDelegate>();
test_proxy_delegate->set_alternative_proxy_server(
ProxyServer::FromPacString("QUIC myproxy.org:443"));
- Initialize(std::move(proxy_resolution_service), std::move(test_proxy_delegate));
+ Initialize(std::move(proxy_resolution_service),
+ std::move(test_proxy_delegate));
// Enable delayed TCP and set time delay for waiting job.
QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory();
@@ -838,12 +854,12 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, AltJobSucceedsMainJobDestroyed) {
EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
// Make |alternative_job| succeed.
- HttpStream* http_stream =
- new HttpBasicStream(std::make_unique<ClientSocketHandle>(), false, false);
+ auto http_stream = std::make_unique<HttpBasicStream>(
+ std::make_unique<ClientSocketHandle>(), false, false);
+ EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, http_stream.get()));
- EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, http_stream));
-
- job_factory_.alternative_job()->SetStream(http_stream);
+ HttpStreamFactoryImplJobPeer::SetStream(job_factory_.alternative_job(),
+ std::move(http_stream));
job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig());
base::RunLoop().RunUntilIdle();
@@ -982,9 +998,10 @@ TEST_F(HttpStreamFactoryImplJobControllerTest,
EXPECT_TRUE(job_controller_->alternative_job());
// Make |alternative_job| succeed.
- HttpStream* http_stream =
- new HttpBasicStream(std::make_unique<ClientSocketHandle>(), false, false);
- job_factory_.alternative_job()->SetStream(http_stream);
+ auto http_stream = std::make_unique<HttpBasicStream>(
+ std::make_unique<ClientSocketHandle>(), false, false);
+ HttpStreamFactoryImplJobPeer::SetStream(job_factory_.alternative_job(),
+ std::move(http_stream));
// This should not call request_delegate_::OnStreamReady.
job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig());
// Make sure that controller does not leak.
@@ -1025,12 +1042,12 @@ TEST_F(HttpStreamFactoryImplJobControllerTest,
base::RunLoop().RunUntilIdle();
// Make |alternative_job| succeed.
- HttpStream* http_stream =
- new HttpBasicStream(std::make_unique<ClientSocketHandle>(), false, false);
-
- EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, http_stream));
+ auto http_stream = std::make_unique<HttpBasicStream>(
+ std::make_unique<ClientSocketHandle>(), false, false);
+ EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, http_stream.get()));
- job_factory_.alternative_job()->SetStream(http_stream);
+ HttpStreamFactoryImplJobPeer::SetStream(job_factory_.alternative_job(),
+ std::move(http_stream));
job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig());
// |alternative_job| succeeds and should report status to Request.
@@ -1160,12 +1177,14 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) {
job_controller_->GetLoadState();
// |alternative_job| succeeds and should report status to Request.
- HttpStream* http_stream =
- new HttpBasicStream(std::make_unique<ClientSocketHandle>(), false, false);
- job_factory_.alternative_job()->SetStream(http_stream);
+ auto http_stream = std::make_unique<HttpBasicStream>(
+ std::make_unique<ClientSocketHandle>(), false, false);
+ EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, http_stream.get()));
- EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _, http_stream));
+ HttpStreamFactoryImplJobPeer::SetStream(job_factory_.alternative_job(),
+ std::move(http_stream));
job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig());
+
request_.reset();
EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
}
@@ -1385,7 +1404,8 @@ TEST_F(HttpStreamFactoryImplJobControllerTest, ResumeMainJobLaterCanceled) {
base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME);
std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
ProxyResolutionService::CreateDirect();
- ProxyResolutionService* proxy_resolution_service_raw = proxy_resolution_service.get();
+ ProxyResolutionService* proxy_resolution_service_raw =
+ proxy_resolution_service.get();
session_deps_.proxy_resolution_service = std::move(proxy_resolution_service);
// Using hanging resolver will cause the alternative job to hang indefinitely.
diff --git a/chromium/net/http/http_stream_factory_impl_request.h b/chromium/net/http/http_stream_factory_impl_request.h
deleted file mode 100644
index 2418dfb0819..00000000000
--- a/chromium/net/http/http_stream_factory_impl_request.h
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_HTTP_HTTP_STREAM_FACTORY_IMPL_REQUEST_H_
-#define NET_HTTP_HTTP_STREAM_FACTORY_IMPL_REQUEST_H_
-
-#include <memory>
-#include <set>
-
-#include "base/macros.h"
-#include "base/optional.h"
-#include "net/base/net_export.h"
-#include "net/http/http_stream_factory_impl.h"
-#include "net/log/net_log_with_source.h"
-#include "net/socket/connection_attempts.h"
-#include "net/socket/ssl_client_socket.h"
-#include "net/spdy/chromium/spdy_session_key.h"
-#include "url/gurl.h"
-
-namespace net {
-
-class BidirectionalStreamImpl;
-class HttpStream;
-
-class HttpStreamFactoryImpl::Request : public HttpStreamRequest {
- public:
- class NET_EXPORT_PRIVATE Helper {
- public:
- virtual ~Helper() {}
-
- // Returns the LoadState for Request.
- virtual LoadState GetLoadState() const = 0;
-
- // Called when Request is destructed.
- virtual void OnRequestComplete() = 0;
-
- // Called to resume the HttpStream creation process when necessary
- // Proxy authentication credentials are collected.
- virtual int RestartTunnelWithProxyAuth() = 0;
-
- // Called when the priority of transaction changes.
- virtual void SetPriority(RequestPriority priority) = 0;
-
- // Called when SpdySessionPool notifies the Request
- // that it can be served on a SpdySession created by another Request,
- // therefore the Jobs can be destroyed.
- virtual void OnStreamReadyOnPooledConnection(
- const SSLConfig& used_ssl_config,
- const ProxyInfo& proxy_info,
- std::unique_ptr<HttpStream> stream) = 0;
- virtual void OnBidirectionalStreamImplReadyOnPooledConnection(
- const SSLConfig& used_ssl_config,
- const ProxyInfo& used_proxy_info,
- std::unique_ptr<BidirectionalStreamImpl> stream) = 0;
- };
-
- // Request will notify |job_controller| when it's destructed.
- // Thus |job_controller| is valid for the lifetime of the |this| Request.
- Request(const GURL& url,
- Helper* helper,
- HttpStreamRequest::Delegate* delegate,
- WebSocketHandshakeStreamBase::CreateHelper*
- websocket_handshake_stream_create_helper,
- const NetLogWithSource& net_log,
- StreamType stream_type);
-
- ~Request() override;
-
- // The GURL from the HttpRequestInfo the started the Request.
- const GURL& url() const { return url_; }
-
- const NetLogWithSource& net_log() const { return net_log_; }
-
- // Called when the |helper_| determines the appropriate |spdy_session_key|
- // for the Request. Note that this does not mean that SPDY is necessarily
- // supported for this SpdySessionKey, since we may need to wait for NPN to
- // complete before knowing if SPDY is available.
- void SetSpdySessionKey(const SpdySessionKey& spdy_session_key) {
- spdy_session_key_ = spdy_session_key;
- }
- bool HasSpdySessionKey() const { return spdy_session_key_.has_value(); }
- const SpdySessionKey& GetSpdySessionKey() const {
- DCHECK(HasSpdySessionKey());
- return spdy_session_key_.value();
- }
- void ResetSpdySessionKey() { spdy_session_key_.reset(); }
-
- HttpStreamRequest::StreamType stream_type() const { return stream_type_; }
-
- // Marks completion of the request. Must be called before OnStreamReady().
- void Complete(bool was_alpn_negotiated,
- NextProto negotiated_protocol,
- bool using_spdy);
-
- // Called by |helper_| to record connection attempts made by the socket
- // layer in an attached Job for this stream request.
- void AddConnectionAttempts(const ConnectionAttempts& attempts);
-
- WebSocketHandshakeStreamBase::CreateHelper*
- websocket_handshake_stream_create_helper() {
- return websocket_handshake_stream_create_helper_;
- }
-
- void OnStreamReadyOnPooledConnection(const SSLConfig& used_ssl_config,
- const ProxyInfo& used_proxy_info,
- std::unique_ptr<HttpStream> stream);
- void OnBidirectionalStreamImplReadyOnPooledConnection(
- const SSLConfig& used_ssl_config,
- const ProxyInfo& used_proxy_info,
- std::unique_ptr<BidirectionalStreamImpl> stream);
-
- // HttpStreamRequest methods.
- int RestartTunnelWithProxyAuth() override;
- void SetPriority(RequestPriority priority) override;
- LoadState GetLoadState() const override;
- bool was_alpn_negotiated() const override;
- NextProto negotiated_protocol() const override;
- bool using_spdy() const override;
- const ConnectionAttempts& connection_attempts() const override;
-
- bool completed() const { return completed_; }
-
- private:
- const GURL url_;
-
- // Unowned. The helper must outlive this request.
- Helper* helper_;
-
- WebSocketHandshakeStreamBase::CreateHelper* const
- websocket_handshake_stream_create_helper_;
- const NetLogWithSource net_log_;
-
- base::Optional<SpdySessionKey> spdy_session_key_;
-
- bool completed_;
- bool was_alpn_negotiated_;
- // Protocol negotiated with the server.
- NextProto negotiated_protocol_;
- bool using_spdy_;
- ConnectionAttempts connection_attempts_;
-
- const HttpStreamRequest::StreamType stream_type_;
- DISALLOW_COPY_AND_ASSIGN(Request);
-};
-
-} // namespace net
-
-#endif // NET_HTTP_HTTP_STREAM_FACTORY_IMPL_REQUEST_H_
diff --git a/chromium/net/http/http_stream_factory_impl_unittest.cc b/chromium/net/http/http_stream_factory_impl_unittest.cc
index 8e0c9884c07..07b156e0015 100644
--- a/chromium/net/http/http_stream_factory_impl_unittest.cc
+++ b/chromium/net/http/http_stream_factory_impl_unittest.cc
@@ -40,7 +40,7 @@
#include "net/http/transport_security_state.h"
#include "net/log/net_log_with_source.h"
#include "net/proxy_resolution/proxy_info.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/quic/chromium/mock_crypto_client_stream_factory.h"
#include "net/quic/chromium/quic_http_utils.h"
#include "net/quic/chromium/quic_stream_factory_peer.h"
@@ -62,6 +62,7 @@
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
// This file can be included from net/http even though
// it is in net/websockets because it doesn't
@@ -88,6 +89,7 @@ class DictionaryValue;
namespace net {
class BidirectionalStreamImpl;
+class WebSocketEndpointLockManager;
namespace {
@@ -174,7 +176,7 @@ class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl {
void WaitForPreconnects() {
while (!preconnect_done_) {
waiting_for_preconnect_ = true;
- base::RunLoop().Run();
+ loop_.Run();
waiting_for_preconnect_ = false;
}
}
@@ -184,11 +186,12 @@ class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl {
void OnPreconnectsCompleteInternal() override {
preconnect_done_ = true;
if (waiting_for_preconnect_)
- base::RunLoop::QuitCurrentWhenIdleDeprecated();
+ loop_.QuitWhenIdle();
}
bool preconnect_done_;
bool waiting_for_preconnect_;
+ base::RunLoop loop_;
};
class StreamRequestWaiter : public HttpStreamRequest::Delegate {
@@ -332,7 +335,8 @@ class WebSocketStreamCreateHelper
std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
std::unique_ptr<ClientSocketHandle> connection,
- bool using_proxy) override {
+ bool using_proxy,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager) override {
return std::make_unique<WebSocketBasicHandshakeStream>(
std::move(connection));
}
@@ -368,6 +372,8 @@ void PreconnectHelperForURL(int num_streams,
request.url = url;
request.load_flags = 0;
request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
+ request.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
session->http_stream_factory()->PreconnectStreams(num_streams, request);
mock_factory->WaitForPreconnects();
@@ -542,8 +548,8 @@ TEST_F(HttpStreamFactoryTest, PreconnectDirect) {
TEST_F(HttpStreamFactoryTest, PreconnectHttpProxy) {
for (size_t i = 0; i < arraysize(kTests); ++i) {
- SpdySessionDependencies session_deps(
- ProxyResolutionService::CreateFixed("http_proxy"));
+ SpdySessionDependencies session_deps(ProxyResolutionService::CreateFixed(
+ "http_proxy", TRAFFIC_ANNOTATION_FOR_TESTS));
std::unique_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
HttpNetworkSessionPeer peer(session.get());
@@ -576,8 +582,8 @@ TEST_F(HttpStreamFactoryTest, PreconnectHttpProxy) {
TEST_F(HttpStreamFactoryTest, PreconnectSocksProxy) {
for (size_t i = 0; i < arraysize(kTests); ++i) {
- SpdySessionDependencies session_deps(
- ProxyResolutionService::CreateFixed("socks4://socks_proxy:1080"));
+ SpdySessionDependencies session_deps(ProxyResolutionService::CreateFixed(
+ "socks4://socks_proxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS));
std::unique_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
HttpNetworkSessionPeer peer(session.get());
@@ -695,7 +701,8 @@ TEST_F(HttpStreamFactoryTest, PreconnectSetsMotivation) {
TEST_F(HttpStreamFactoryTest, JobNotifiesProxy) {
const char* kProxyString = "PROXY bad:99; PROXY maybe:80; DIRECT";
SpdySessionDependencies session_deps(
- ProxyResolutionService::CreateFixedFromPacResult(kProxyString));
+ ProxyResolutionService::CreateFixedFromPacResult(
+ kProxyString, TRAFFIC_ANNOTATION_FOR_TESTS));
// First connection attempt fails
StaticSocketDataProvider socket_data1;
@@ -715,6 +722,8 @@ TEST_F(HttpStreamFactoryTest, JobNotifiesProxy) {
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = GURL("http://www.google.com");
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -734,6 +743,62 @@ TEST_F(HttpStreamFactoryTest, JobNotifiesProxy) {
EXPECT_TRUE(iter != retry_info.end());
}
+// This test requests a stream for an https:// URL using an HTTP proxy.
+// The proxy will fail to establish a tunnel via connect, and the resolved
+// proxy list includes a fallback to DIRECT.
+//
+// The expected behavior is that proxy fallback does NOT occur, even though the
+// request might work using the fallback. This is a regression test for
+// https://crbug.com/680837.
+TEST_F(HttpStreamFactoryTest, NoProxyFallbackOnTunnelFail) {
+ const char* kProxyString = "PROXY bad:99; DIRECT";
+ SpdySessionDependencies session_deps(
+ ProxyResolutionService::CreateFixedFromPacResult(
+ kProxyString, TRAFFIC_ANNOTATION_FOR_TESTS));
+
+ // A 404 in response to a CONNECT will trigger
+ // ERR_TUNNEL_CONNECTION_FAILED.
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 404 Not Found\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
+ };
+
+ // Simulate a failure during CONNECT to bad:99.
+ StaticSocketDataProvider socket_data1(data_reads, arraysize(data_reads),
+ nullptr, 0);
+ socket_data1.set_connect_data(MockConnect(SYNCHRONOUS, OK));
+ session_deps.socket_factory->AddSocketDataProvider(&socket_data1);
+
+ std::unique_ptr<HttpNetworkSession> session(
+ SpdySessionDependencies::SpdyCreateSession(&session_deps));
+
+ // Request a stream for an https:// URL. The exact URL doesn't matter for
+ // this test, since it mocks a failure immediately when establishing a
+ // tunnel through the proxy.
+ HttpRequestInfo request_info;
+ request_info.method = "GET";
+ request_info.url = GURL("https://www.google.com");
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
+
+ SSLConfig ssl_config;
+ StreamRequestWaiter waiter;
+ std::unique_ptr<HttpStreamRequest> request(
+ session->http_stream_factory()->RequestStream(
+ request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
+ /* enable_ip_based_pooling = */ true,
+ /* enable_alternative_services = */ true, NetLogWithSource()));
+ waiter.WaitForStream();
+
+ // The stream should have failed, since the proxy server failed to
+ // establish a tunnel.
+ ASSERT_THAT(waiter.error_status(), IsError(ERR_TUNNEL_CONNECTION_FAILED));
+
+ // The proxy should NOT have been marked as bad.
+ const ProxyRetryInfoMap& retry_info =
+ session->proxy_resolution_service()->proxy_retry_info();
+ EXPECT_EQ(0u, retry_info.size());
+}
+
// List of errors that are used in the tests related to QUIC proxy.
const int quic_proxy_test_mock_errors[] = {
ERR_PROXY_CONNECTION_FAILED,
@@ -745,7 +810,6 @@ const int quic_proxy_test_mock_errors[] = {
ERR_CONNECTION_REFUSED,
ERR_CONNECTION_ABORTED,
ERR_TIMED_OUT,
- ERR_TUNNEL_CONNECTION_FAILED,
ERR_SOCKS_CONNECTION_FAILED,
ERR_PROXY_CERTIFICATE_INVALID,
ERR_QUIC_PROTOCOL_ERROR,
@@ -758,8 +822,8 @@ const int quic_proxy_test_mock_errors[] = {
TEST_F(HttpStreamFactoryTest, QuicProxyMarkedAsBad) {
for (size_t i = 0; i < arraysize(quic_proxy_test_mock_errors); ++i) {
std::unique_ptr<ProxyResolutionService> proxy_resolution_service;
- proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("QUIC bad:99; DIRECT");
+ proxy_resolution_service = ProxyResolutionService::CreateFixedFromPacResult(
+ "QUIC bad:99; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS);
HttpNetworkSession::Params session_params;
session_params.enable_quic = true;
@@ -803,6 +867,8 @@ TEST_F(HttpStreamFactoryTest, QuicProxyMarkedAsBad) {
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = GURL("http://www.google.com");
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -940,7 +1006,8 @@ TEST_F(HttpStreamFactoryTest, WithQUICAlternativeProxyMarkedAsBad) {
MockClientSocketFactory socket_factory;
std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
ProxyResolutionService::CreateFixedFromPacResult(
- "HTTPS badproxy:99; HTTPS badfallbackproxy:98; DIRECT");
+ "HTTPS badproxy:99; HTTPS badfallbackproxy:98; DIRECT",
+ TRAFFIC_ANNOTATION_FOR_TESTS);
TestProxyDelegate test_proxy_delegate;
HttpServerPropertiesImpl http_server_properties;
MockCertVerifier cert_verifier;
@@ -1006,6 +1073,8 @@ TEST_F(HttpStreamFactoryTest, WithQUICAlternativeProxyMarkedAsBad) {
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = GURL("http://www.google.com");
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -1053,7 +1122,7 @@ TEST_F(HttpStreamFactoryTest, WithQUICAlternativeProxyNotMarkedAsBad) {
MockClientSocketFactory socket_factory;
std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
ProxyResolutionService::CreateFixedFromPacResult(
- "HTTPS badproxy:99; DIRECT");
+ "HTTPS badproxy:99; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS);
TestProxyDelegate test_proxy_delegate;
HttpServerPropertiesImpl http_server_properties;
MockCertVerifier cert_verifier;
@@ -1104,6 +1173,8 @@ TEST_F(HttpStreamFactoryTest, WithQUICAlternativeProxyNotMarkedAsBad) {
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = GURL("http://www.google.com");
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -1140,8 +1211,8 @@ TEST_F(HttpStreamFactoryTest, UsePreConnectIfNoZeroRTT) {
for (int num_streams = 1; num_streams < 3; ++num_streams) {
GURL url = GURL("https://www.google.com");
- SpdySessionDependencies session_deps(
- ProxyResolutionService::CreateFixed("http_proxy"));
+ SpdySessionDependencies session_deps(ProxyResolutionService::CreateFixed(
+ "http_proxy", TRAFFIC_ANNOTATION_FOR_TESTS));
// Setup params to disable preconnect, but QUIC doesn't 0RTT.
HttpNetworkSession::Params session_params =
@@ -1200,7 +1271,7 @@ TEST_F(HttpStreamFactoryTest, OnlyOnePreconnectToProxyServer) {
GURL url = GURL("http://www.google.com");
std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
ProxyResolutionService::CreateFixedFromPacResult(
- "HTTPS myproxy.org:443");
+ "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
// Set up the proxy server as a server that supports request priorities.
HttpServerPropertiesImpl http_server_properties;
@@ -1254,6 +1325,8 @@ TEST_F(HttpStreamFactoryTest, OnlyOnePreconnectToProxyServer) {
request.method = "GET";
request.url = url;
request.load_flags = 0;
+ request.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
if (preconnect_request == 0) {
// First preconnect job should succeed.
@@ -1293,7 +1366,8 @@ TEST_F(HttpStreamFactoryTest, ProxyServerPreconnectDifferentPrivacyModes) {
base::HistogramTester histogram_tester;
GURL url = GURL("http://www.google.com");
std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy.org:443");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
// Set up the proxy server as a server that supports request priorities.
HttpServerPropertiesImpl http_server_properties;
@@ -1341,6 +1415,8 @@ TEST_F(HttpStreamFactoryTest, ProxyServerPreconnectDifferentPrivacyModes) {
request_privacy_mode_disabled.method = "GET";
request_privacy_mode_disabled.url = url;
request_privacy_mode_disabled.load_flags = 0;
+ request_privacy_mode_disabled.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// First preconnect job should succeed.
session->http_stream_factory()->PreconnectStreams(
@@ -1361,6 +1437,8 @@ TEST_F(HttpStreamFactoryTest, ProxyServerPreconnectDifferentPrivacyModes) {
request_privacy_mode_enabled.url = url;
request_privacy_mode_enabled.load_flags = 0;
request_privacy_mode_enabled.privacy_mode = PRIVACY_MODE_ENABLED;
+ request_privacy_mode_enabled.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Request with a different privacy mode should succeed.
session->http_stream_factory()->PreconnectStreams(
@@ -1394,6 +1472,8 @@ TEST_F(HttpStreamFactoryTest, PrivacyModeDisablesChannelId) {
request_info.url = GURL("https://www.google.com");
request_info.load_flags = 0;
request_info.privacy_mode = PRIVACY_MODE_DISABLED;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -1493,6 +1573,8 @@ TEST_F(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) {
request_info.url = GURL("https://www.google.com");
request_info.load_flags = 0;
request_info.privacy_mode = PRIVACY_MODE_DISABLED;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -1543,6 +1625,8 @@ TEST_F(HttpStreamFactoryTest, GetLoadState) {
HttpRequestInfo request_info;
request_info.method = "GET";
request_info.url = GURL("http://www.google.com");
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -1573,6 +1657,8 @@ TEST_F(HttpStreamFactoryTest, RequestHttpStream) {
request_info.method = "GET";
request_info.url = GURL("http://www.google.com");
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -1622,6 +1708,8 @@ TEST_F(HttpStreamFactoryTest, ReprioritizeAfterStreamReceived) {
request_info.method = "GET";
request_info.url = GURL("https://www.google.com");
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -1667,6 +1755,8 @@ TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverSSL) {
request_info.method = "GET";
request_info.url = GURL("https://www.google.com");
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -1694,8 +1784,8 @@ TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverSSL) {
}
TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverProxy) {
- SpdySessionDependencies session_deps(
- ProxyResolutionService::CreateFixed("myproxy:8888"));
+ SpdySessionDependencies session_deps(ProxyResolutionService::CreateFixed(
+ "myproxy:8888", TRAFFIC_ANNOTATION_FOR_TESTS));
StaticSocketDataProvider socket_data;
socket_data.set_connect_data(MockConnect(ASYNC, OK));
@@ -1710,6 +1800,8 @@ TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverProxy) {
request_info.method = "GET";
request_info.url = GURL("http://www.google.com");
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -1746,8 +1838,8 @@ TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverProxy) {
// Verifies that once a stream has been created to a proxy server (that supports
// request priorities) the next preconnect job can again open new sockets.
TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverProxyWithPreconnects) {
- SpdySessionDependencies session_deps(
- ProxyResolutionService::CreateFixed("https://myproxy.org:443"));
+ SpdySessionDependencies session_deps(ProxyResolutionService::CreateFixed(
+ "https://myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS));
// Set up the proxy server as a server that supports request priorities.
auto http_server_properties = std::make_unique<HttpServerPropertiesImpl>();
@@ -1770,6 +1862,8 @@ TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverProxyWithPreconnects) {
request_info.method = "GET";
request_info.url = GURL("http://www.google.com");
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
base::HistogramTester histogram_tester;
const int num_preconnects = 5;
@@ -1839,6 +1933,8 @@ TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) {
request_info.method = "GET";
request_info.url = GURL("ws://www.google.com");
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -1883,6 +1979,8 @@ TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) {
request_info.method = "GET";
request_info.url = GURL("wss://www.google.com");
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -1909,8 +2007,8 @@ TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) {
}
TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) {
- SpdySessionDependencies session_deps(
- ProxyResolutionService::CreateFixed("myproxy:8888"));
+ SpdySessionDependencies session_deps(ProxyResolutionService::CreateFixed(
+ "myproxy:8888", TRAFFIC_ANNOTATION_FOR_TESTS));
MockRead read(SYNCHRONOUS, "HTTP/1.0 200 Connection established\r\n\r\n");
StaticSocketDataProvider socket_data(&read, 1, 0, 0);
@@ -1925,6 +2023,8 @@ TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) {
request_info.method = "GET";
request_info.url = GURL("ws://www.google.com");
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -1982,6 +2082,8 @@ TEST_F(HttpStreamFactoryTest, RequestSpdyHttpStreamHttpsURL) {
request_info.method = "GET";
request_info.url = GURL("https://www.google.com");
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -2012,9 +2114,10 @@ TEST_F(HttpStreamFactoryTest, RequestSpdyHttpStreamHttpURL) {
url::SchemeHostPort scheme_host_port("http", "myproxy.org", 443);
auto session_deps = std::make_unique<SpdySessionDependencies>(
ProxyResolutionService::CreateFixedFromPacResult(
- "HTTPS myproxy.org:443"));
+ "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS));
std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
- ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy.org:443");
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
SequencedSocketData socket_data(&mock_read, 1, nullptr, 0);
@@ -2038,6 +2141,8 @@ TEST_F(HttpStreamFactoryTest, RequestSpdyHttpStreamHttpURL) {
request_info.method = "GET";
request_info.url = GURL("http://www.google.com");
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -2124,6 +2229,8 @@ TEST_F(HttpStreamFactoryTest, NewSpdySessionCloseIdleH2Sockets) {
request_info.method = "GET";
request_info.url = GURL("https://www.google.com");
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter1;
@@ -2179,6 +2286,8 @@ TEST_F(HttpStreamFactoryTest, TwoSpdyConnects) {
request_info.method = "GET";
request_info.url = GURL("https://www.google.com");
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
// Request two streams at once and make sure they use the same connection.
@@ -2233,6 +2342,8 @@ TEST_F(HttpStreamFactoryTest, RequestBidirectionalStreamImpl) {
request_info.method = "GET";
request_info.url = GURL("https://www.google.com");
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -2422,6 +2533,8 @@ TEST_P(HttpStreamFactoryBidirectionalQuicTest,
request_info.method = "GET";
request_info.url = default_url_;
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
StreamRequestWaiter waiter;
std::unique_ptr<HttpStreamRequest> request(
@@ -2446,7 +2559,7 @@ TEST_P(HttpStreamFactoryBidirectionalQuicTest,
TestBidirectionalDelegate delegate;
stream_impl->Start(&bidi_request_info, NetLogWithSource(),
/*send_request_headers_automatically=*/true, &delegate,
- nullptr);
+ nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
delegate.WaitUntilDone();
scoped_refptr<IOBuffer> buffer = new net::IOBuffer(1);
@@ -2487,6 +2600,8 @@ TEST_P(HttpStreamFactoryBidirectionalQuicTest,
request_info.method = "GET";
request_info.url = default_url_;
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
StreamRequestWaiter waiter;
std::unique_ptr<HttpStreamRequest> request(
@@ -2549,6 +2664,8 @@ TEST_P(HttpStreamFactoryBidirectionalQuicTest,
request_info.method = "GET";
request_info.url = default_url_;
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
StreamRequestWaiter waiter;
std::unique_ptr<HttpStreamRequest> request(
@@ -2573,7 +2690,7 @@ TEST_P(HttpStreamFactoryBidirectionalQuicTest,
TestBidirectionalDelegate delegate;
stream_impl->Start(&bidi_request_info, NetLogWithSource(),
/*send_request_headers_automatically=*/true, &delegate,
- nullptr);
+ nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
delegate.WaitUntilDone();
// Make sure the BidirectionalStream negotiated goes through QUIC.
@@ -2615,6 +2732,8 @@ TEST_F(HttpStreamFactoryTest, RequestBidirectionalStreamImplFailure) {
request_info.method = "GET";
request_info.url = GURL("https://www.google.com");
request_info.load_flags = 0;
+ request_info.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
@@ -2679,11 +2798,16 @@ TEST_F(HttpStreamFactoryTest, Tag) {
request_info1.url = GURL("https://example.org");
request_info1.load_flags = 0;
request_info1.socket_tag = tag1;
+ request_info1.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SocketTag tag2(getuid(), 0x87654321);
HttpRequestInfo request_info2 = request_info1;
request_info2.socket_tag = tag2;
+ request_info2.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
- // Verify one stream with one tag results in one session, group and socket.
+ // Verify one stream with one tag results in one session, group and
+ // socket.
SSLConfig ssl_config;
StreamRequestWaiter waiter1;
std::unique_ptr<HttpStreamRequest> request1(
@@ -2836,9 +2960,13 @@ TEST_P(HttpStreamFactoryBidirectionalQuicTest, Tag) {
request_info1.url = default_url_;
request_info1.load_flags = 0;
request_info1.socket_tag = tag1;
+ request_info1.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SocketTag tag2(getuid(), 0x87654321);
HttpRequestInfo request_info2 = request_info1;
request_info2.socket_tag = tag2;
+ request_info2.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Verify one stream with one tag results in one QUIC session.
SSLConfig ssl_config;
@@ -2935,16 +3063,23 @@ TEST_F(HttpStreamFactoryTest, ChangeSocketTag) {
request_info1.url = GURL("https://www.example.org");
request_info1.load_flags = 0;
request_info1.socket_tag = tag1;
+ request_info1.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SocketTag tag2(getuid(), 0x87654321);
HttpRequestInfo request_info2 = request_info1;
request_info2.socket_tag = tag2;
+ request_info2.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
// Prepare another HttpRequestInfo with tag1 and a different host name.
HttpRequestInfo request_info3 = request_info1;
request_info3.url = GURL("https://foo.example.org");
+ request_info3.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
- // Verify one stream with one tag results in one session, group and socket.
+ // Verify one stream with one tag results in one session, group and
+ // socket.
SSLConfig ssl_config;
StreamRequestWaiter waiter1;
std::unique_ptr<HttpStreamRequest> request1(
@@ -3130,6 +3265,8 @@ TEST_F(HttpStreamFactoryTest, MultiIPAliases) {
request_info1.method = "GET";
request_info1.url = GURL("https://a.example.org");
request_info1.privacy_mode = PRIVACY_MODE_DISABLED;
+ request_info1.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
HttpRequestInfo request_info1_alias = request_info1;
request_info1.url = GURL("https://b.example.org");
@@ -3138,6 +3275,8 @@ TEST_F(HttpStreamFactoryTest, MultiIPAliases) {
request_info2.method = "GET";
request_info2.url = GURL("https://a.example.org");
request_info2.privacy_mode = PRIVACY_MODE_ENABLED;
+ request_info2.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
HttpRequestInfo request_info2_alias = request_info2;
request_info2.url = GURL("https://b.example.org");
diff --git a/chromium/net/http/http_stream_factory_test_util.h b/chromium/net/http/http_stream_factory_test_util.h
index 91b2e09babe..d2c2fd5e6be 100644
--- a/chromium/net/http/http_stream_factory_test_util.h
+++ b/chromium/net/http/http_stream_factory_test_util.h
@@ -14,6 +14,7 @@
#include "net/http/http_stream_factory_impl.h"
#include "net/http/http_stream_factory_impl_job.h"
#include "net/http/http_stream_factory_impl_job_controller.h"
+#include "net/http/http_stream_request.h"
#include "net/proxy_resolution/proxy_info.h"
#include "net/socket/next_proto.h"
#include "testing/gmock/include/gmock/gmock.h"
diff --git a/chromium/net/http/http_stream_factory_impl_request.cc b/chromium/net/http/http_stream_request.cc
index 3579aeaa3b5..deb3902ebea 100644
--- a/chromium/net/http/http_stream_factory_impl_request.cc
+++ b/chromium/net/http/http_stream_request.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/http/http_stream_factory_impl_request.h"
+#include "net/http/http_stream_request.h"
#include <utility>
@@ -10,14 +10,13 @@
#include "base/logging.h"
#include "base/stl_util.h"
#include "net/http/bidirectional_stream_impl.h"
-#include "net/http/http_stream_factory_impl_job.h"
#include "net/log/net_log_event_type.h"
#include "net/spdy/chromium/spdy_http_stream.h"
#include "net/spdy/chromium/spdy_session.h"
namespace net {
-HttpStreamFactoryImpl::Request::Request(
+HttpStreamRequest::HttpStreamRequest(
const GURL& url,
Helper* helper,
HttpStreamRequest::Delegate* delegate,
@@ -38,14 +37,14 @@ HttpStreamFactoryImpl::Request::Request(
net_log_.BeginEvent(NetLogEventType::HTTP_STREAM_REQUEST);
}
-HttpStreamFactoryImpl::Request::~Request() {
+HttpStreamRequest::~HttpStreamRequest() {
net_log_.EndEvent(NetLogEventType::HTTP_STREAM_REQUEST);
helper_->OnRequestComplete();
}
-void HttpStreamFactoryImpl::Request::Complete(bool was_alpn_negotiated,
- NextProto negotiated_protocol,
- bool using_spdy) {
+void HttpStreamRequest::Complete(bool was_alpn_negotiated,
+ NextProto negotiated_protocol,
+ bool using_spdy) {
DCHECK(!completed_);
completed_ = true;
was_alpn_negotiated_ = was_alpn_negotiated;
@@ -53,7 +52,7 @@ void HttpStreamFactoryImpl::Request::Complete(bool was_alpn_negotiated,
using_spdy_ = using_spdy;
}
-void HttpStreamFactoryImpl::Request::OnStreamReadyOnPooledConnection(
+void HttpStreamRequest::OnStreamReadyOnPooledConnection(
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
std::unique_ptr<HttpStream> stream) {
@@ -62,52 +61,55 @@ void HttpStreamFactoryImpl::Request::OnStreamReadyOnPooledConnection(
std::move(stream));
}
-void HttpStreamFactoryImpl::Request::
- OnBidirectionalStreamImplReadyOnPooledConnection(
- const SSLConfig& used_ssl_config,
- const ProxyInfo& used_proxy_info,
- std::unique_ptr<BidirectionalStreamImpl> stream) {
+void HttpStreamRequest::OnBidirectionalStreamImplReadyOnPooledConnection(
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ std::unique_ptr<BidirectionalStreamImpl> stream) {
DCHECK(completed_);
helper_->OnBidirectionalStreamImplReadyOnPooledConnection(
used_ssl_config, used_proxy_info, std::move(stream));
}
-int HttpStreamFactoryImpl::Request::RestartTunnelWithProxyAuth() {
+int HttpStreamRequest::RestartTunnelWithProxyAuth() {
return helper_->RestartTunnelWithProxyAuth();
}
-void HttpStreamFactoryImpl::Request::SetPriority(RequestPriority priority) {
+void HttpStreamRequest::SetPriority(RequestPriority priority) {
helper_->SetPriority(priority);
}
-LoadState HttpStreamFactoryImpl::Request::GetLoadState() const {
+LoadState HttpStreamRequest::GetLoadState() const {
return helper_->GetLoadState();
}
-bool HttpStreamFactoryImpl::Request::was_alpn_negotiated() const {
+bool HttpStreamRequest::was_alpn_negotiated() const {
DCHECK(completed_);
return was_alpn_negotiated_;
}
-NextProto HttpStreamFactoryImpl::Request::negotiated_protocol() const {
+NextProto HttpStreamRequest::negotiated_protocol() const {
DCHECK(completed_);
return negotiated_protocol_;
}
-bool HttpStreamFactoryImpl::Request::using_spdy() const {
+bool HttpStreamRequest::using_spdy() const {
DCHECK(completed_);
return using_spdy_;
}
-const ConnectionAttempts& HttpStreamFactoryImpl::Request::connection_attempts()
- const {
+const ConnectionAttempts& HttpStreamRequest::connection_attempts() const {
return connection_attempts_;
}
-void HttpStreamFactoryImpl::Request::AddConnectionAttempts(
+void HttpStreamRequest::AddConnectionAttempts(
const ConnectionAttempts& attempts) {
for (const auto& attempt : attempts)
connection_attempts_.push_back(attempt);
}
+WebSocketHandshakeStreamBase::CreateHelper*
+HttpStreamRequest::websocket_handshake_stream_create_helper() const {
+ return websocket_handshake_stream_create_helper_;
+}
+
} // namespace net
diff --git a/chromium/net/http/http_stream_request.h b/chromium/net/http/http_stream_request.h
new file mode 100644
index 00000000000..2cce574134c
--- /dev/null
+++ b/chromium/net/http/http_stream_request.h
@@ -0,0 +1,290 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_HTTP_HTTP_STREAM_REQUEST_H_
+#define NET_HTTP_HTTP_STREAM_REQUEST_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/optional.h"
+#include "net/base/load_states.h"
+#include "net/base/net_error_details.h"
+#include "net/base/net_export.h"
+#include "net/base/request_priority.h"
+#include "net/http/http_response_info.h"
+#include "net/log/net_log_with_source.h"
+#include "net/proxy_resolution/proxy_info.h"
+#include "net/socket/connection_attempts.h"
+#include "net/socket/next_proto.h"
+#include "net/spdy/chromium/spdy_session_key.h"
+#include "net/ssl/ssl_config.h"
+#include "net/ssl/ssl_info.h"
+#include "net/websockets/websocket_handshake_stream_base.h"
+#include "url/gurl.h"
+
+namespace net {
+
+class BidirectionalStreamImpl;
+class HttpAuthController;
+class HttpStream;
+class SSLCertRequestInfo;
+
+// The HttpStreamRequest is the client's handle to the worker object which
+// handles the creation of an HttpStream. While the HttpStream is being
+// created, this object is the creator's handle for interacting with the
+// HttpStream creation process. The request is cancelled by deleting it, after
+// which no callbacks will be invoked.
+class NET_EXPORT_PRIVATE HttpStreamRequest {
+ public:
+ // Indicates which type of stream is requested.
+ enum StreamType {
+ BIDIRECTIONAL_STREAM,
+ HTTP_STREAM,
+ };
+
+ // The HttpStreamRequest::Delegate is a set of callback methods for a
+ // HttpStreamRequestJob. Generally, only one of these methods will be
+ // called as a result of a stream request.
+ class NET_EXPORT_PRIVATE Delegate {
+ public:
+ virtual ~Delegate() {}
+
+ // This is the success case for RequestStream.
+ // |stream| is now owned by the delegate.
+ // |used_ssl_config| indicates the actual SSL configuration used for this
+ // stream, since the HttpStreamRequest may have modified the configuration
+ // during stream processing.
+ // |used_proxy_info| indicates the actual ProxyInfo used for this stream,
+ // since the HttpStreamRequest performs the proxy resolution.
+ virtual void OnStreamReady(const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ std::unique_ptr<HttpStream> stream) = 0;
+
+ // This is the success case for RequestWebSocketHandshakeStream.
+ // |stream| is now owned by the delegate.
+ // |used_ssl_config| indicates the actual SSL configuration used for this
+ // stream, since the HttpStreamRequest may have modified the configuration
+ // during stream processing.
+ // |used_proxy_info| indicates the actual ProxyInfo used for this stream,
+ // since the HttpStreamRequest performs the proxy resolution.
+ virtual void OnWebSocketHandshakeStreamReady(
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ std::unique_ptr<WebSocketHandshakeStreamBase> stream) = 0;
+
+ virtual void OnBidirectionalStreamImplReady(
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ std::unique_ptr<BidirectionalStreamImpl> stream) = 0;
+
+ // This is the failure to create a stream case.
+ // |used_ssl_config| indicates the actual SSL configuration used for this
+ // stream, since the HttpStreamRequest may have modified the configuration
+ // during stream processing.
+ virtual void OnStreamFailed(int status,
+ const NetErrorDetails& net_error_details,
+ const SSLConfig& used_ssl_config) = 0;
+
+ // Called when we have a certificate error for the request.
+ // |used_ssl_config| indicates the actual SSL configuration used for this
+ // stream, since the HttpStreamRequest may have modified the configuration
+ // during stream processing.
+ virtual void OnCertificateError(int status,
+ const SSLConfig& used_ssl_config,
+ const SSLInfo& ssl_info) = 0;
+
+ // This is the failure case where we need proxy authentication during
+ // proxy tunnel establishment. For the tunnel case, we were unable to
+ // create the HttpStream, so the caller provides the auth and then resumes
+ // the HttpStreamRequest.
+ //
+ // For the non-tunnel case, the caller will discover the authentication
+ // failure when reading response headers. At that point, it will handle the
+ // authentication failure and restart the HttpStreamRequest entirely.
+ //
+ // Ownership of |auth_controller| and |proxy_response| are owned
+ // by the HttpStreamRequest. |proxy_response| is not guaranteed to be usable
+ // after the lifetime of this callback. The delegate may take a reference
+ // to |auth_controller| if it is needed beyond the lifetime of this
+ // callback.
+ //
+ // |used_ssl_config| indicates the actual SSL configuration used for this
+ // stream, since the HttpStreamRequest may have modified the configuration
+ // during stream processing.
+ virtual void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response,
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ HttpAuthController* auth_controller) = 0;
+
+ // This is the failure for SSL Client Auth
+ // Ownership of |cert_info| is retained by the HttpStreamRequest. The
+ // delegate may take a reference if it needs the cert_info beyond the
+ // lifetime of this callback.
+ virtual void OnNeedsClientAuth(const SSLConfig& used_ssl_config,
+ SSLCertRequestInfo* cert_info) = 0;
+
+ // This is the failure of the CONNECT request through an HTTPS proxy.
+ // Headers can be read from |response_info|, while the body can be read
+ // from |stream|.
+ //
+ // |used_ssl_config| indicates the actual SSL configuration used for this
+ // stream, since the HttpStreamRequest may have modified the configuration
+ // during stream processing.
+ //
+ // |used_proxy_info| indicates the actual ProxyInfo used for this stream,
+ // since the HttpStreamRequest performs the proxy resolution.
+ //
+ // Ownership of |stream| is transferred to the delegate.
+ virtual void OnHttpsProxyTunnelResponse(
+ const HttpResponseInfo& response_info,
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ std::unique_ptr<HttpStream> stream) = 0;
+
+ // Called when finding all QUIC alternative services are marked broken for
+ // the origin in this request which advertises supporting QUIC.
+ virtual void OnQuicBroken() = 0;
+ };
+
+ class NET_EXPORT_PRIVATE Helper {
+ public:
+ virtual ~Helper() {}
+
+ // Returns the LoadState for Request.
+ virtual LoadState GetLoadState() const = 0;
+
+ // Called when Request is destructed.
+ virtual void OnRequestComplete() = 0;
+
+ // Called to resume the HttpStream creation process when necessary
+ // Proxy authentication credentials are collected.
+ virtual int RestartTunnelWithProxyAuth() = 0;
+
+ // Called when the priority of transaction changes.
+ virtual void SetPriority(RequestPriority priority) = 0;
+
+ // Called when SpdySessionPool notifies the Request
+ // that it can be served on a SpdySession created by another Request,
+ // therefore the Jobs can be destroyed.
+ virtual void OnStreamReadyOnPooledConnection(
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& proxy_info,
+ std::unique_ptr<HttpStream> stream) = 0;
+ virtual void OnBidirectionalStreamImplReadyOnPooledConnection(
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ std::unique_ptr<BidirectionalStreamImpl> stream) = 0;
+ };
+
+ // Request will notify |job_controller| when it's destructed.
+ // Thus |job_controller| is valid for the lifetime of the |this| Request.
+ HttpStreamRequest(const GURL& url,
+ Helper* helper,
+ HttpStreamRequest::Delegate* delegate,
+ WebSocketHandshakeStreamBase::CreateHelper*
+ websocket_handshake_stream_create_helper,
+ const NetLogWithSource& net_log,
+ StreamType stream_type);
+
+ ~HttpStreamRequest();
+
+ // When a HttpStream creation process is stalled due to necessity
+ // of Proxy authentication credentials, the delegate OnNeedsProxyAuth
+ // will have been called. It now becomes the delegate's responsibility
+ // to collect the necessary credentials, and then call this method to
+ // resume the HttpStream creation process.
+ int RestartTunnelWithProxyAuth();
+
+ // Called when the priority of the parent transaction changes.
+ void SetPriority(RequestPriority priority);
+
+ // Marks completion of the request. Must be called before OnStreamReady().
+ void Complete(bool was_alpn_negotiated,
+ NextProto negotiated_protocol,
+ bool using_spdy);
+
+ // Called by |helper_| to record connection attempts made by the socket
+ // layer in an attached Job for this stream request.
+ void AddConnectionAttempts(const ConnectionAttempts& attempts);
+
+ // Called when a stream becomes available on a connection that was not created
+ // by this request.
+ void OnStreamReadyOnPooledConnection(const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ std::unique_ptr<HttpStream> stream);
+ void OnBidirectionalStreamImplReadyOnPooledConnection(
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ std::unique_ptr<BidirectionalStreamImpl> stream);
+
+ // Returns the LoadState for the request.
+ LoadState GetLoadState() const;
+
+ // Returns true if TLS/ALPN was negotiated for this stream.
+ bool was_alpn_negotiated() const;
+
+ // Protocol negotiated with the server.
+ NextProto negotiated_protocol() const;
+
+ // Returns true if this stream is being fetched over SPDY.
+ bool using_spdy() const;
+
+ // Returns socket-layer connection attempts made for this stream request.
+ const ConnectionAttempts& connection_attempts() const;
+
+ // Returns the WebSocketHandshakeStreamBase::CreateHelper for this stream
+ // request.
+ WebSocketHandshakeStreamBase::CreateHelper*
+ websocket_handshake_stream_create_helper() const;
+
+ // The GURL from the HttpRequestInfo the started the Request.
+ const GURL& url() const { return url_; }
+
+ const NetLogWithSource& net_log() const { return net_log_; }
+
+ // Called when the |helper_| determines the appropriate |spdy_session_key|
+ // for the Request. Note that this does not mean that SPDY is necessarily
+ // supported for this SpdySessionKey, since we may need to wait for NPN to
+ // complete before knowing if SPDY is available.
+ void SetSpdySessionKey(const SpdySessionKey& spdy_session_key) {
+ spdy_session_key_ = spdy_session_key;
+ }
+ bool HasSpdySessionKey() const { return spdy_session_key_.has_value(); }
+ const SpdySessionKey& GetSpdySessionKey() const {
+ DCHECK(HasSpdySessionKey());
+ return spdy_session_key_.value();
+ }
+ void ResetSpdySessionKey() { spdy_session_key_.reset(); }
+
+ StreamType stream_type() const { return stream_type_; }
+
+ bool completed() const { return completed_; }
+
+ private:
+ const GURL url_;
+
+ // Unowned. The helper must outlive this request.
+ Helper* helper_;
+
+ WebSocketHandshakeStreamBase::CreateHelper* const
+ websocket_handshake_stream_create_helper_;
+ const NetLogWithSource net_log_;
+
+ base::Optional<SpdySessionKey> spdy_session_key_;
+
+ bool completed_;
+ bool was_alpn_negotiated_;
+ // Protocol negotiated with the server.
+ NextProto negotiated_protocol_;
+ bool using_spdy_;
+ ConnectionAttempts connection_attempts_;
+ const StreamType stream_type_;
+
+ DISALLOW_COPY_AND_ASSIGN(HttpStreamRequest);
+};
+
+} // namespace net
+
+#endif // NET_HTTP_HTTP_STREAM_REQUEST_H_
diff --git a/chromium/net/http/http_stream_factory_impl_request_unittest.cc b/chromium/net/http/http_stream_request_unittest.cc
index 5cffaa6963f..329166114bb 100644
--- a/chromium/net/http/http_stream_factory_impl_request_unittest.cc
+++ b/chromium/net/http/http_stream_request_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/http/http_stream_factory_impl_request.h"
+#include "net/http/http_stream_request.h"
#include <utility>
@@ -11,8 +11,7 @@
#include "net/http/http_stream_factory_impl_job.h"
#include "net/http/http_stream_factory_impl_job_controller.h"
#include "net/http/http_stream_factory_test_util.h"
-#include "net/proxy_resolution/proxy_info.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/spdy/chromium/spdy_test_util_common.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -20,10 +19,8 @@ using testing::_;
namespace net {
-class HttpStreamFactoryImplRequestTest : public ::testing::Test {};
-
// Make sure that Request passes on its priority updates to its jobs.
-TEST_F(HttpStreamFactoryImplRequestTest, SetPriority) {
+TEST(HttpStreamRequestTest, SetPriority) {
SequencedSocketData data(nullptr, 0, nullptr, 0);
data.set_connect_data(MockConnect(ASYNC, OK));
auto ssl_data = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
@@ -49,10 +46,9 @@ TEST_F(HttpStreamFactoryImplRequestTest, SetPriority) {
job_controller.get();
factory->job_controller_set_.insert(std::move(job_controller));
- std::unique_ptr<HttpStreamFactoryImpl::Request> request(
- job_controller_raw_ptr->Start(
- &request_delegate, nullptr, NetLogWithSource(),
- HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
+ std::unique_ptr<HttpStreamRequest> request(job_controller_raw_ptr->Start(
+ &request_delegate, nullptr, NetLogWithSource(),
+ HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
EXPECT_TRUE(job_controller_raw_ptr->main_job());
EXPECT_EQ(DEFAULT_PRIORITY, job_controller_raw_ptr->main_job()->priority());
diff --git a/chromium/net/http/http_util.cc b/chromium/net/http/http_util.cc
index 9361272ce0d..e26c7d78b7d 100644
--- a/chromium/net/http/http_util.cc
+++ b/chromium/net/http/http_util.cc
@@ -22,6 +22,7 @@
namespace net {
namespace {
+
template <typename ConstIterator>
void TrimLWSImplementation(ConstIterator* begin, ConstIterator* end) {
// leading whitespace
@@ -33,23 +34,6 @@ void TrimLWSImplementation(ConstIterator* begin, ConstIterator* end) {
--(*end);
}
-// Helpers --------------------------------------------------------------------
-
-// Returns the index of the closing quote of the string, if any. |start| points
-// at the opening quote.
-size_t FindStringEnd(const std::string& line, size_t start, char delim) {
- DCHECK_LT(start, line.length());
- DCHECK_EQ(line[start], delim);
- DCHECK((delim == '"') || (delim == '\''));
-
- const char set[] = { delim, '\\', '\0' };
- for (size_t end = line.find_first_of(set, start + 1);
- end != std::string::npos; end = line.find_first_of(set, end + 2)) {
- if (line[end] != '\\')
- return end;
- }
- return line.length();
-}
} // namespace
// HttpUtil -------------------------------------------------------------------
@@ -79,65 +63,111 @@ void HttpUtil::ParseContentType(const std::string& content_type_str,
if (type_end == std::string::npos)
type_end = content_type_str.length();
- size_t charset_val = 0;
- size_t charset_end = 0;
+ std::string charset_value;
bool type_has_charset = false;
- // Iterate over parameters
- size_t param_start = content_type_str.find_first_of(';', type_end);
- if (param_start != std::string::npos) {
- base::StringTokenizer tokenizer(begin + param_start, content_type_str.end(),
- ";");
- tokenizer.set_quote_chars("\"");
- while (tokenizer.GetNext()) {
- std::string::const_iterator equals_sign =
- std::find(tokenizer.token_begin(), tokenizer.token_end(), '=');
- if (equals_sign == tokenizer.token_end())
- continue;
+ // Iterate over parameters. Can't split the string around semicolons
+ // preemptively because quoted strings may include semicolons. Matches logic
+ // in https://mimesniff.spec.whatwg.org/.
+ std::string::size_type offset = content_type_str.find_first_of(';', type_end);
+ while (offset < content_type_str.size()) {
+ DCHECK_EQ(';', content_type_str[offset]);
+ // Trim off the semicolon.
+ ++offset;
+
+ // Trim off any following spaces.
+ offset = content_type_str.find_first_not_of(HTTP_LWS, offset);
+ std::string::size_type param_name_start = offset;
+
+ // Extend parameter name until run into a semicolon or equals sign. Per
+ // spec, trailing spaces are not removed.
+ offset = content_type_str.find_first_of(";=", offset);
+
+ // Nothing more to do if at end of string, or if there's no parameter
+ // value, since names without values aren't allowed.
+ if (offset == std::string::npos || content_type_str[offset] == ';')
+ continue;
- std::string::const_iterator param_name_begin = tokenizer.token_begin();
- std::string::const_iterator param_name_end = equals_sign;
- std::string::const_iterator param_value_begin = equals_sign + 1;
- std::string::const_iterator param_value_end = tokenizer.token_end();
- DCHECK(param_value_begin <= tokenizer.token_end());
-
- // From parameter name, only trim leading whitespace.
- // From parameter value, only trim trailing whitespace.
- // See https://crbug.com/772834.
- TrimLWS(&param_name_begin, &param_value_end);
-
- if (base::LowerCaseEqualsASCII(
- base::StringPiece(param_name_begin, param_name_end), "charset")) {
- // TODO(abarth): Refactor this function to consistently use iterators.
- charset_val = param_value_begin - begin;
- charset_end = param_value_end - begin;
- type_has_charset = true;
- } else if (base::LowerCaseEqualsASCII(
- base::StringPiece(param_name_begin, param_name_end),
- "boundary")) {
- if (boundary)
- boundary->assign(param_value_begin, param_value_end);
+ base::StringPiece param_name(content_type_str.begin() + param_name_start,
+ content_type_str.begin() + offset);
+
+ // Now parse the value.
+ DCHECK_EQ('=', content_type_str[offset]);
+ // Trim off the '='.
+ offset++;
+
+ // Remove leading spaces. This violates the spec, though it matches
+ // pre-existing behavior.
+ //
+ // TODO(mmenke): Consider doing this (only?) after parsing quotes, which
+ // seems to align more with the spec - not the content-type spec, but the
+ // GET spec's way of getting an encoding, and the spec for handling
+ // boundary values as well.
+ // See https://encoding.spec.whatwg.org/#names-and-labels.
+ offset = content_type_str.find_first_not_of(HTTP_LWS, offset);
+
+ std::string param_value;
+ if (offset == std::string::npos) {
+ // Nothing to do here - an unquoted string of only whitespace is
+ // considered to have an empty value.
+ } else if (content_type_str[offset] != '"') {
+ // If the first character is not a quotation mark, copy data directly.
+ std::string::size_type value_start = offset;
+ offset = content_type_str.find_first_of(';', offset);
+ std::string::size_type value_end = offset;
+
+ // Remove terminal whitespace. If ran off the end of the string, have to
+ // update |value_end| first.
+ if (value_end == std::string::npos)
+ value_end = content_type_str.size();
+ while (value_end > value_start &&
+ IsLWS(content_type_str[value_end - 1])) {
+ --value_end;
}
- }
- }
- if (type_has_charset) {
- // Trim leading whitespace from charset_val.
- charset_val = content_type_str.find_first_not_of(HTTP_LWS, charset_val);
- charset_val = std::min(charset_val, charset_end);
- char first_char = content_type_str[charset_val];
- // RFC 7231 Section 3.1.1.1 allows double quotes around charset.
- if (first_char == '"') {
- charset_end = FindStringEnd(content_type_str, charset_val, first_char);
- ++charset_val;
- DCHECK(charset_end >= charset_val);
+ param_value =
+ content_type_str.substr(value_start, value_end - value_start);
} else {
- // Ignore the part after '('. This is not in the standard, but may occur
- // in rare cases.
+ // Otherwise, append data, with special handling for backslashes, until
+ // a close quote.
+
+ // Skip open quote.
+ DCHECK_EQ('"', content_type_str[offset]);
+ ++offset;
+
+ while (offset < content_type_str.size() &&
+ content_type_str[offset] != '"') {
+ // Skip over backslash and append the next character, when not at
+ // the end of the string. Otherwise, copy the next character (Which may
+ // be a backslash).
+ if (content_type_str[offset] == '\\' &&
+ offset + 1 < content_type_str.size()) {
+ ++offset;
+ }
+ param_value += content_type_str[offset];
+ ++offset;
+ }
+
+ offset = content_type_str.find_first_of(';', offset);
+ }
+
+ // 0-length parameter values are not considered valid.
+ if (!param_value.size())
+ continue;
+
+ // TODO(mmenke): Take first, rather than last, value in the case of
+ // duplicates.
+ // TODO(mmenke): Check that name has only valid characters.
+ if (base::LowerCaseEqualsASCII(param_name, "charset")) {
+ // Ignore the part after '('. This is not in the standard, but may
+ // occur in rare cases.
// TODO(bnc): Do not ignore the part after '('.
// See https://crbug.com/772343.
- charset_end = std::min(content_type_str.find_first_of("(", charset_val),
- charset_end);
+ charset_value = param_value.substr(0, param_value.find("("));
+ type_has_charset = true;
+ } else if (base::LowerCaseEqualsASCII(param_name, "boundary")) {
+ if (boundary)
+ boundary->assign(std::move(param_value));
}
}
@@ -164,8 +194,7 @@ void HttpUtil::ParseContentType(const std::string& content_type_str,
}
if ((!eq && *had_charset) || type_has_charset) {
*had_charset = true;
- *charset = base::ToLowerASCII(
- base::StringPiece(begin + charset_val, begin + charset_end));
+ *charset = base::ToLowerASCII(charset_value);
}
}
diff --git a/chromium/net/http/http_util.h b/chromium/net/http/http_util.h
index a46a208a46e..428d90b0c3d 100644
--- a/chromium/net/http/http_util.h
+++ b/chromium/net/http/http_util.h
@@ -39,8 +39,8 @@ class NET_EXPORT HttpUtil {
// charset values are normalized to lowercase. The mime_type and charset
// output values are only modified if the content_type_str contains a mime
// type and charset value, respectively. The boundary output value is
- // optional and will be assigned the (quoted) value of the boundary
- // paramter, if any.
+ // optional and will be assigned the (unquoted) value of the boundary
+ // parameter, if any.
static void ParseContentType(const std::string& content_type_str,
std::string* mime_type,
std::string* charset,
diff --git a/chromium/net/http/http_util_unittest.cc b/chromium/net/http/http_util_unittest.cc
index bb9bcd92378..ec4e6d108d0 100644
--- a/chromium/net/http/http_util_unittest.cc
+++ b/chromium/net/http/http_util_unittest.cc
@@ -734,6 +734,18 @@ TEST(HttpUtilTest, ParseContentType) {
const bool expected_had_charset;
const char* const expected_boundary;
} tests[] = {
+ { "text/html",
+ "text/html",
+ "",
+ false,
+ ""
+ },
+ { "text/html;",
+ "text/html",
+ "",
+ false,
+ ""
+ },
{ "text/html; charset=utf-8",
"text/html",
"utf-8",
@@ -763,7 +775,7 @@ TEST(HttpUtilTest, ParseContentType) {
"text/html",
"",
false,
- "\"WebKit-ada-df-dsf-adsfadsfs\""
+ "WebKit-ada-df-dsf-adsfadsfs"
},
// Parameter name is "boundary ", not "boundary".
// See https://crbug.com/772834.
@@ -778,20 +790,20 @@ TEST(HttpUtilTest, ParseContentType) {
"text/html",
"",
false,
- " \"WebKit-ada-df-dsf-adsfadsfs\""
+ "WebKit-ada-df-dsf-adsfadsfs"
},
// Parameter value includes leading space. See https://crbug.com/772834.
{ "text/html; boundary= \"WebKit-ada-df-dsf-adsfadsfs\" ",
"text/html",
"",
false,
- " \"WebKit-ada-df-dsf-adsfadsfs\""
+ "WebKit-ada-df-dsf-adsfadsfs"
},
{ "text/html; boundary=\"WebKit-ada-df-dsf-adsfadsfs \"",
"text/html",
"",
false,
- "\"WebKit-ada-df-dsf-adsfadsfs \""
+ "WebKit-ada-df-dsf-adsfadsfs "
},
{ "text/html; boundary=WebKit-ada-df-dsf-adsfadsfs",
"text/html",
@@ -799,12 +811,110 @@ TEST(HttpUtilTest, ParseContentType) {
false,
"WebKit-ada-df-dsf-adsfadsfs"
},
+ { "text/html; charset",
+ "text/html",
+ "",
+ false,
+ ""
+ },
+ { "text/html; charset=",
+ "text/html",
+ "",
+ false,
+ ""
+ },
+ { "text/html; charset= ",
+ "text/html",
+ "",
+ false,
+ ""
+ },
+ { "text/html; charset= ;",
+ "text/html",
+ "",
+ false,
+ ""
+ },
+ { "text/html; charset=\"\"",
+ "text/html",
+ "",
+ false,
+ ""
+ },
+ { "text/html; charset=\" \"",
+ "text/html",
+ " ",
+ true,
+ ""
+ },
+ { "text/html; charset; charset=; charset=utf-8",
+ "text/html",
+ "utf-8",
+ true,
+ ""
+ },
+ { "text/html; charset=utf-8; charset=; charset;",
+ "text/html",
+ "utf-8",
+ true,
+ ""
+ },
+ // Stray quotes ignored.
+ { "text/html; \"; \"\"; charset=utf-8",
+ "text/html",
+ "utf-8",
+ true,
+ ""
+ },
+ // Non-leading quotes kept as-is.
+ { "text/html; charset=u\"tf-8\"",
+ "text/html",
+ "u\"tf-8\"",
+ true,
+ ""
+ },
{ "text/html; charset=\"utf-8\"",
"text/html",
"utf-8",
true,
""
},
+ // No closing quote.
+ { "text/html; charset=\"utf-8",
+ "text/html",
+ "utf-8",
+ true,
+ ""
+ },
+ // Check that \ is treated as an escape character.
+ { "text/html; charset=\"\\utf\\-\\8\"",
+ "text/html",
+ "utf-8",
+ true,
+ ""
+ },
+ // More interseting escape character test - test escaped backslash, escaped
+ // quote, and backslash at end of input in unterminated quoted string.
+ { "text/html; charset=\"\\\\\\\"\\",
+ "text/html",
+ "\\\"\\",
+ true,
+ ""
+ },
+ // Check quoted semicolon.
+ { "text/html; charset=\";charset=utf-8;\"",
+ "text/html",
+ ";charset=utf-8;",
+ true,
+ ""
+ },
+ // Unclear if this one should just return utf-8 or not.
+ { "text/html; charset= \"utf-8\"",
+ "text/html",
+ "utf-8",
+ true,
+ ""
+ },
// Regression test for https://crbug.com/772350:
// Single quotes are not delimiters but must be treated as part of charset.
{ "text/html; charset='utf-8'",
@@ -823,10 +933,14 @@ TEST(HttpUtilTest, ParseContentType) {
std::string boundary;
HttpUtil::ParseContentType(tests[i].content_type, &mime_type, &charset,
&had_charset, &boundary);
- EXPECT_EQ(tests[i].expected_mime_type, mime_type) << "i=" << i;
- EXPECT_EQ(tests[i].expected_charset, charset) << "i=" << i;
- EXPECT_EQ(tests[i].expected_had_charset, had_charset) << "i=" << i;
- EXPECT_EQ(tests[i].expected_boundary, boundary) << "i=" << i;
+ EXPECT_EQ(tests[i].expected_mime_type, mime_type)
+ << "content_type=" << tests[i].content_type;
+ EXPECT_EQ(tests[i].expected_charset, charset)
+ << "content_type=" << tests[i].content_type;
+ EXPECT_EQ(tests[i].expected_had_charset, had_charset)
+ << "content_type=" << tests[i].content_type;
+ EXPECT_EQ(tests[i].expected_boundary, boundary)
+ << "content_type=" << tests[i].content_type;
}
}
diff --git a/chromium/net/http/mock_http_cache.cc b/chromium/net/http/mock_http_cache.cc
index ad730d1e04c..c52fc246290 100644
--- a/chromium/net/http/mock_http_cache.cc
+++ b/chromium/net/http/mock_http_cache.cc
@@ -325,6 +325,10 @@ int MockDiskEntry::ReadyForSparseIO(const CompletionCallback& callback) {
return ERR_IO_PENDING;
}
+void MockDiskEntry::SetLastUsedTimeForTest(base::Time time) {
+ NOTREACHED();
+}
+
// If |value| is true, don't deliver any completion callbacks until called
// again with |value| set to false. Caution: remember to enable callbacks
// again or all subsequent tests will fail.
diff --git a/chromium/net/http/mock_http_cache.h b/chromium/net/http/mock_http_cache.h
index f313c1a16d0..f6716766786 100644
--- a/chromium/net/http/mock_http_cache.h
+++ b/chromium/net/http/mock_http_cache.h
@@ -73,6 +73,7 @@ class MockDiskEntry : public disk_cache::Entry,
bool CouldBeSparse() const override;
void CancelSparseIO() override;
int ReadyForSparseIO(const CompletionCallback& completion_callback) override;
+ void SetLastUsedTimeForTest(base::Time time) override;
uint8_t in_memory_data() const { return in_memory_data_; }
void set_in_memory_data(uint8_t val) { in_memory_data_ = val; }
diff --git a/chromium/net/http/partial_data.cc b/chromium/net/http/partial_data.cc
index 962e0ab3da9..5a71e1983b2 100644
--- a/chromium/net/http/partial_data.cc
+++ b/chromium/net/http/partial_data.cc
@@ -34,15 +34,14 @@ PartialData::PartialData()
: current_range_start_(0),
current_range_end_(0),
cached_start_(0),
- resource_size_(0),
cached_min_len_(0),
+ resource_size_(0),
range_present_(false),
final_range_(false),
sparse_entry_(true),
truncated_(false),
initial_validation_(false),
- weak_factory_(this) {
-}
+ weak_factory_(this) {}
PartialData::~PartialData() = default;
@@ -182,7 +181,8 @@ bool PartialData::IsLastRange() const {
bool PartialData::UpdateFromStoredHeaders(const HttpResponseHeaders* headers,
disk_cache::Entry* entry,
- bool truncated) {
+ bool truncated,
+ bool writing_in_progress) {
resource_size_ = 0;
if (truncated) {
DCHECK_EQ(headers->response_code(), 200);
@@ -200,6 +200,19 @@ bool PartialData::UpdateFromStoredHeaders(const HttpResponseHeaders* headers,
if (total_length <= 0)
return false;
+ // In case we see a truncated entry, we first send a network request for
+ // 1 byte range with If-Range: to probe server support for resumption.
+ // The setting of |current_range_start_| and |cached_start_| below (with any
+ // positive value of |cached_min_len_|) results in that.
+ //
+ // Setting |initial_validation_| to true is how this communicates to
+ // HttpCache::Transaction that we're doing that (and that it's not the user
+ // asking for one byte), so if it sees a 206 with that flag set it will call
+ // SetRangeToStartDownload(), and then restart the process looking for the
+ // entire file (which is what the user wanted), with the cache handling
+ // the previous portion, and then a second network request for the entire
+ // rest of the range. A 200 in response to the probe request can be simply
+ // returned directly to the user.
truncated_ = true;
initial_validation_ = true;
sparse_entry_ = false;
@@ -212,25 +225,39 @@ bool PartialData::UpdateFromStoredHeaders(const HttpResponseHeaders* headers,
return true;
}
- if (headers->response_code() != 206) {
- DCHECK(byte_range_.IsValid());
- sparse_entry_ = false;
+ sparse_entry_ = (headers->response_code() == 206);
+
+ if (writing_in_progress || sparse_entry_) {
+ // |writing_in_progress| means another Transaction is still fetching the
+ // body, so the only way we can see the length is if the server sent it
+ // in Content-Length -- GetDataSize would just return what got written
+ // thus far.
+ //
+ // |sparse_entry_| means a 206, and for those FixContentLength arranges it
+ // so that Content-Length written to the cache has the full length (on wire
+ // it's for a particular range only); while GetDataSize would be unusable
+ // since the data is stored using WriteSparseData, and not in the usual data
+ // stream.
+ resource_size_ = headers->GetContentLength();
+ if (resource_size_ <= 0)
+ return false;
+ } else {
+ // If we can safely use GetDataSize, it's preferrable since it's usable for
+ // things w/o Content-Length, such as chunked content.
resource_size_ = entry->GetDataSize(kDataStream);
- DVLOG(2) << "UpdateFromStoredHeaders size: " << resource_size_;
- return true;
}
- if (!headers->HasStrongValidators())
- return false;
+ DVLOG(2) << "UpdateFromStoredHeaders size: " << resource_size_;
- int64_t length_value = headers->GetContentLength();
- if (length_value <= 0)
- return false; // We must have stored the resource length.
-
- resource_size_ = length_value;
-
- // Make sure that this is really a sparse entry.
- return entry->CouldBeSparse();
+ if (sparse_entry_) {
+ // If our previous is a 206, we need strong validators as we may be
+ // stiching the cached data and network data together.
+ if (!headers->HasStrongValidators())
+ return false;
+ // Make sure that this is really a sparse entry.
+ return entry->CouldBeSparse();
+ }
+ return true;
}
void PartialData::SetRangeToStartDownload() {
diff --git a/chromium/net/http/partial_data.h b/chromium/net/http/partial_data.h
index 29ccbb3c4a9..68dd500f0f1 100644
--- a/chromium/net/http/partial_data.h
+++ b/chromium/net/http/partial_data.h
@@ -73,9 +73,13 @@ class PartialData {
// Extracts info from headers already stored in the cache. Returns false if
// there is any problem with the headers. |truncated| should be true if we
- // have an incomplete 200 entry.
+ // have an incomplete 200 entry due to a transfer having been interrupted.
+ // |writing_in_progress| should be set to true if a transfer for this entry's
+ // payload is still in progress.
bool UpdateFromStoredHeaders(const HttpResponseHeaders* headers,
- disk_cache::Entry* entry, bool truncated);
+ disk_cache::Entry* entry,
+ bool truncated,
+ bool writing_in_progress);
// Sets the byte current range to start again at zero (for a truncated entry).
void SetRangeToStartDownload();
@@ -128,11 +132,21 @@ class PartialData {
// Completion routine for our callback.
void GetAvailableRangeCompleted(int64_t* start, int result);
+ // The portion we're trying to get, either from cache or network.
int64_t current_range_start_;
int64_t current_range_end_;
+
+ // Next portion available in the cache --- this may be what's currently being
+ // read, or the next thing that will be read if the current network portion
+ // succeeds.
+ //
+ // |cached_start_| represents the beginning of the range, while
+ // |cached_min_len_| the data not yet read (possibly overestimated).
int64_t cached_start_;
- int64_t resource_size_;
int cached_min_len_;
+
+ // The size of the whole file.
+ int64_t resource_size_;
HttpByteRange byte_range_; // The range requested by the user.
// The clean set of extra headers (no ranges).
HttpRequestHeaders extra_headers_;
diff --git a/chromium/net/http/proxy_fallback.cc b/chromium/net/http/proxy_fallback.cc
new file mode 100644
index 00000000000..0c43b2eb095
--- /dev/null
+++ b/chromium/net/http/proxy_fallback.cc
@@ -0,0 +1,64 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/http/proxy_fallback.h"
+
+#include "net/base/net_errors.h"
+
+namespace net {
+
+bool CanFalloverToNextProxy(int* error) {
+ // A failure to resolve the hostname or any error related to establishing a
+ // TCP connection could be grounds for trying a new proxy configuration.
+ //
+ // Why do this when a hostname cannot be resolved? Some URLs only make sense
+ // to proxy servers. The hostname in those URLs might fail to resolve if we
+ // are still using a non-proxy config. We need to check if a proxy config
+ // now exists that corresponds to a proxy server that could load the URL.
+ //
+ // A failure while establishing a tunnel to the proxy
+ // (ERR_TUNNEL_CONNECTION_FAILED) is NOT considered grounds for fallback.
+ // Other browsers similarly don't fallback, and some client's PAC
+ // configurations rely on this for some degree of content blocking.
+ // See https://crbug.com/680837 for details.
+ switch (*error) {
+ case ERR_PROXY_CONNECTION_FAILED:
+ case ERR_NAME_NOT_RESOLVED:
+ case ERR_INTERNET_DISCONNECTED:
+ case ERR_ADDRESS_UNREACHABLE:
+ case ERR_CONNECTION_CLOSED:
+ case ERR_CONNECTION_TIMED_OUT:
+ case ERR_CONNECTION_RESET:
+ case ERR_CONNECTION_REFUSED:
+ case ERR_CONNECTION_ABORTED:
+ case ERR_TIMED_OUT:
+ case ERR_SOCKS_CONNECTION_FAILED:
+ // ERR_PROXY_CERTIFICATE_INVALID can happen in the case of trying to talk to
+ // a proxy using SSL, and ending up talking to a captive portal that
+ // supports SSL instead.
+ case ERR_PROXY_CERTIFICATE_INVALID:
+ case ERR_QUIC_PROTOCOL_ERROR:
+ case ERR_QUIC_HANDSHAKE_FAILED:
+ case ERR_MSG_TOO_BIG:
+ // ERR_SSL_PROTOCOL_ERROR can happen when trying to talk SSL to a non-SSL
+ // server (like a captive portal).
+ case ERR_SSL_PROTOCOL_ERROR:
+ return true;
+
+ case ERR_SOCKS_CONNECTION_HOST_UNREACHABLE:
+ // Remap the SOCKS-specific "host unreachable" error to a more
+ // generic error code (this way consumers like the link doctor
+ // know to substitute their error page).
+ //
+ // Note that if the host resolving was done by the SOCKS5 proxy, we can't
+ // differentiate between a proxy-side "host not found" versus a proxy-side
+ // "address unreachable" error, and will report both of these failures as
+ // ERR_ADDRESS_UNREACHABLE.
+ *error = ERR_ADDRESS_UNREACHABLE;
+ return false;
+ }
+ return false;
+}
+
+} // namespace net
diff --git a/chromium/net/http/proxy_fallback.h b/chromium/net/http/proxy_fallback.h
new file mode 100644
index 00000000000..7642bc4cf13
--- /dev/null
+++ b/chromium/net/http/proxy_fallback.h
@@ -0,0 +1,58 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_HTTP_PROXY_FALLBACK_H_
+#define NET_HTTP_PROXY_FALLBACK_H_
+
+// ------------------------------------------------------------
+// Proxy Fallback Overview
+// ------------------------------------------------------------
+//
+// Proxy fallback is a feature that is split between the proxy resolution layer
+// and the HTTP layers.
+//
+// The proxy resolution layer is responsible for:
+// * Obtaining a list of proxies to use
+// (ProxyResolutionService::ResolveProxy). Proxy lists are (usually) the
+// result of having evaluated a PAC script, such as:
+// return "PROXY foobar1:8080; HTTPS foobar2:8080; DIRECT";
+//
+// * Re-ordering the proxy list such that proxies that have recently failed
+// are given lower priority (ProxyInfo::DeprioritizeBadProxies)
+//
+// * Maintaining the expiring cache of proxies that have recently failed.
+//
+//
+// The HTTP layer is responsible for:
+// * Attempting to issue the URLRequest through each of the
+// proxies, in the order specified by the list.
+//
+// * Deciding whether this attempt was successful, whether it was a failure
+// but should keep trying other proxies, or whether it was a failure and
+// should stop trying other proxies.
+//
+// * Upon successful completion of an attempt though a proxy, calling
+// ProxyResolutionService::ReportSuccess to inform it of all the failed
+// attempts that were made. (A proxy is only considered to be "bad"
+// if the request was able to be completed through some other proxy).
+//
+//
+// Exactly how to interpret the proxy lists returned by PAC is not specified by
+// a standard. The justifications for what errors are considered for fallback
+// are given beside the implementation.
+
+#include "net/base/net_export.h"
+
+namespace net {
+
+// Returns true if the request should be re-tried using the next proxy in the
+// fallback list.
+//
+// |*error| is the network error that the request failed with. When returning
+// false it may be replaced with a different error.
+NET_EXPORT bool CanFalloverToNextProxy(int* error);
+
+} // namespace net
+
+#endif // NET_HTTP_PROXY_FALLBACK_H_
diff --git a/chromium/net/http/transport_security_state.cc b/chromium/net/http/transport_security_state.cc
index cd4e9c74a31..3802937bc0c 100644
--- a/chromium/net/http/transport_security_state.cc
+++ b/chromium/net/http/transport_security_state.cc
@@ -33,7 +33,7 @@
#include "net/cert/x509_certificate.h"
#include "net/dns/dns_util.h"
#include "net/http/http_security_headers.h"
-#include "net/net_features.h"
+#include "net/net_buildflags.h"
#include "net/ssl/ssl_info.h"
namespace net {
@@ -766,28 +766,16 @@ TransportSecurityState::TransportSecurityState()
// Both HSTS and HPKP cause fatal SSL errors, so return true if a
// host has either.
bool TransportSecurityState::ShouldSSLErrorsBeFatal(const std::string& host) {
- STSState sts_state;
- PKPState pkp_state;
- if (GetStaticDomainState(host, &sts_state, &pkp_state))
- return true;
- if (GetDynamicSTSState(host, &sts_state))
- return true;
- return GetDynamicPKPState(host, &pkp_state);
+ STSState unused_sts;
+ PKPState unused_pkp;
+ return GetStaticDomainState(host, &unused_sts, &unused_pkp) ||
+ GetDynamicSTSState(host, &unused_sts) ||
+ GetDynamicPKPState(host, &unused_pkp);
}
bool TransportSecurityState::ShouldUpgradeToSSL(const std::string& host) {
- STSState dynamic_sts_state;
- if (GetDynamicSTSState(host, &dynamic_sts_state))
- return dynamic_sts_state.ShouldUpgradeToSSL();
-
- STSState static_sts_state;
- PKPState unused;
- if (GetStaticDomainState(host, &static_sts_state, &unused) &&
- static_sts_state.ShouldUpgradeToSSL()) {
- return true;
- }
-
- return false;
+ STSState sts_state;
+ return GetSTSState(host, &sts_state) && sts_state.ShouldUpgradeToSSL();
}
TransportSecurityState::PKPStatus TransportSecurityState::CheckPublicKeyPins(
@@ -857,18 +845,8 @@ void TransportSecurityState::CheckExpectStaple(
}
bool TransportSecurityState::HasPublicKeyPins(const std::string& host) {
- PKPState dynamic_state;
- if (GetDynamicPKPState(host, &dynamic_state))
- return dynamic_state.HasPublicKeyPins();
-
- STSState unused;
- PKPState static_pkp_state;
- if (GetStaticDomainState(host, &unused, &static_pkp_state)) {
- if (static_pkp_state.HasPublicKeyPins())
- return true;
- }
-
- return false;
+ PKPState pkp_state;
+ return GetPKPState(host, &pkp_state) && pkp_state.HasPublicKeyPins();
}
TransportSecurityState::CTRequirementsStatus
@@ -885,6 +863,12 @@ TransportSecurityState::CheckCTRequirements(
using CTRequirementLevel = RequireCTDelegate::CTRequirementLevel;
std::string hostname = host_port_pair.host();
+ // CT is not required if the certificate does not chain to a publicly
+ // trusted root certificate. Testing can override this, as certain tests
+ // rely on using a non-publicly-trusted root.
+ if (!is_issued_by_known_root && g_ct_required_for_testing == 0)
+ return CT_NOT_REQUIRED;
+
// A connection is considered compliant if it has sufficient SCTs or if the
// build is outdated. Other statuses are not considered compliant; this
// includes COMPLIANCE_DETAILS_NOT_AVAILABLE because compliance must have been
@@ -896,9 +880,9 @@ TransportSecurityState::CheckCTRequirements(
// Check Expect-CT first so that other CT requirements do not prevent
// Expect-CT reports from being sent.
+ bool required_via_expect_ct = false;
ExpectCTState state;
- if (is_issued_by_known_root && IsDynamicExpectCTEnabled() &&
- GetDynamicExpectCTState(hostname, &state)) {
+ if (IsDynamicExpectCTEnabled() && GetDynamicExpectCTState(hostname, &state)) {
UMA_HISTOGRAM_ENUMERATION(
"Net.ExpectCTHeader.PolicyComplianceOnConnectionSetup",
policy_compliance, ct::CTPolicyCompliance::CT_POLICY_MAX);
@@ -909,17 +893,28 @@ TransportSecurityState::CheckCTRequirements(
served_certificate_chain,
signed_certificate_timestamps);
}
- if (state.enforce)
- return complies ? CT_REQUIREMENTS_MET : CT_REQUIREMENTS_NOT_MET;
+ required_via_expect_ct = state.enforce;
}
CTRequirementLevel ct_required = CTRequirementLevel::DEFAULT;
- if (require_ct_delegate_)
- ct_required = require_ct_delegate_->IsCTRequiredForHost(hostname);
- if (ct_required != CTRequirementLevel::DEFAULT) {
- if (ct_required == CTRequirementLevel::REQUIRED)
+ if (require_ct_delegate_) {
+ // Allow the delegate to override the CT requirement state, including
+ // overriding any Expect-CT enforcement.
+ ct_required = require_ct_delegate_->IsCTRequiredForHost(
+ hostname, validated_certificate_chain, public_key_hashes);
+ }
+ switch (ct_required) {
+ case CTRequirementLevel::REQUIRED:
return complies ? CT_REQUIREMENTS_MET : CT_REQUIREMENTS_NOT_MET;
- return CT_NOT_REQUIRED;
+ case CTRequirementLevel::NOT_REQUIRED:
+ return CT_NOT_REQUIRED;
+ case CTRequirementLevel::DEFAULT:
+ if (required_via_expect_ct) {
+ // If Expect-CT is set, short-circuit checking additional policies,
+ // since they will only enable CT requirement, not exclude from it.
+ return complies ? CT_REQUIREMENTS_MET : CT_REQUIREMENTS_NOT_MET;
+ }
+ break;
}
// Allow unittests to override the default result.
@@ -1581,11 +1576,7 @@ TransportSecurityState::CheckPublicKeyPinsImpl(
const PublicKeyPinReportStatus report_status,
std::string* failure_log) {
PKPState pkp_state;
- STSState unused;
-
- bool found_state =
- GetDynamicPKPState(host_port_pair.host(), &pkp_state) ||
- GetStaticDomainState(host_port_pair.host(), &unused, &pkp_state);
+ bool found_state = GetPKPState(host_port_pair.host(), &pkp_state);
// HasPublicKeyPins should have returned true in order for this method to have
// been called.
@@ -1597,14 +1588,10 @@ TransportSecurityState::CheckPublicKeyPinsImpl(
}
bool TransportSecurityState::GetStaticDomainState(const std::string& host,
- STSState* sts_state,
- PKPState* pkp_state) const {
+ STSState* sts_result,
+ PKPState* pkp_result) const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS;
- sts_state->include_subdomains = false;
- pkp_state->include_subdomains = false;
-
if (!IsBuildTimely())
return false;
@@ -1612,38 +1599,37 @@ bool TransportSecurityState::GetStaticDomainState(const std::string& host,
if (!DecodeHSTSPreload(host, &result))
return false;
- sts_state->domain = host.substr(result.hostname_offset);
- pkp_state->domain = sts_state->domain;
- sts_state->include_subdomains = result.sts_include_subdomains;
- sts_state->last_observed = base::GetBuildTime();
- sts_state->upgrade_mode = STSState::MODE_DEFAULT;
if (result.force_https) {
- sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS;
+ sts_result->domain = host.substr(result.hostname_offset);
+ sts_result->include_subdomains = result.sts_include_subdomains;
+ sts_result->last_observed = base::GetBuildTime();
+ sts_result->upgrade_mode = STSState::MODE_FORCE_HTTPS;
}
if (enable_static_pins_ && result.has_pins) {
- pkp_state->include_subdomains = result.pkp_include_subdomains;
- pkp_state->last_observed = base::GetBuildTime();
-
if (result.pinset_id >= g_hsts_source->pinsets_count)
return false;
+
+ pkp_result->domain = host.substr(result.hostname_offset);
+ pkp_result->include_subdomains = result.pkp_include_subdomains;
+ pkp_result->last_observed = base::GetBuildTime();
+
const TransportSecurityStateSource::Pinset* pinset =
&g_hsts_source->pinsets[result.pinset_id];
-
if (pinset->report_uri != kNoReportURI)
- pkp_state->report_uri = GURL(pinset->report_uri);
+ pkp_result->report_uri = GURL(pinset->report_uri);
if (pinset->accepted_pins) {
const char* const* sha256_hash = pinset->accepted_pins;
while (*sha256_hash) {
- AddHash(*sha256_hash, &pkp_state->spki_hashes);
+ AddHash(*sha256_hash, &pkp_result->spki_hashes);
sha256_hash++;
}
}
if (pinset->rejected_pins) {
const char* const* sha256_hash = pinset->rejected_pins;
while (*sha256_hash) {
- AddHash(*sha256_hash, &pkp_state->bad_spki_hashes);
+ AddHash(*sha256_hash, &pkp_result->bad_spki_hashes);
sha256_hash++;
}
}
@@ -1652,6 +1638,20 @@ bool TransportSecurityState::GetStaticDomainState(const std::string& host,
return true;
}
+bool TransportSecurityState::GetSTSState(const std::string& host,
+ STSState* result) {
+ PKPState unused;
+ return GetDynamicSTSState(host, result) ||
+ GetStaticDomainState(host, result, &unused);
+}
+
+bool TransportSecurityState::GetPKPState(const std::string& host,
+ PKPState* result) {
+ STSState unused;
+ return GetDynamicPKPState(host, result) ||
+ GetStaticDomainState(host, &unused, result);
+}
+
bool TransportSecurityState::GetDynamicSTSState(const std::string& host,
STSState* result) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
diff --git a/chromium/net/http/transport_security_state.h b/chromium/net/http/transport_security_state.h
index 79d3a1c3453..5f7873f7637 100644
--- a/chromium/net/http/transport_security_state.h
+++ b/chromium/net/http/transport_security_state.h
@@ -84,8 +84,14 @@ class NET_EXPORT TransportSecurityState {
// Called by the TransportSecurityState, allows the Delegate to override
// the default handling of Certificate Transparency requirements, if
// desired.
+ // |hostname| contains the host being contacted, serving the certificate
+ // |chain|, with the set of hashesh |hashes|. Note that |hashes| and
+ // |chain| are not guaranteed to be in the same order - that is, the first
+ // hash in |hashes| is NOT guaranteed to be for the leaf cert in |chain|.
virtual CTRequirementLevel IsCTRequiredForHost(
- const std::string& hostname) = 0;
+ const std::string& hostname,
+ const X509Certificate* chain,
+ const HashValueVector& hashes) = 0;
protected:
virtual ~RequireCTDelegate() = default;
@@ -479,16 +485,27 @@ class NET_EXPORT TransportSecurityState {
// the Delegate (if any).
bool DeleteDynamicDataForHost(const std::string& host);
- // Returns true and updates |*sts_result| and |*pkp_result| iff there is a
+ // Returns true and updates |*result| if |host| has dynamic or static
+ // HSTS/HPKP (respectively) state. If multiple entries match |host|, dynamic
+ // state is preferred over static state and other than that the most specific
+ // match determines the return value (both is in deviation of RFC6797, cf.
+ // https://crbug.com/821811).
+ //
+ // Note that these methods are not const because they opportunistically remove
+ // entries that have expired.
+ bool GetSTSState(const std::string& host, STSState* result);
+ bool GetPKPState(const std::string& host, PKPState* result);
+
+ // Returns true and updates |*sts_result| and/or |*pkp_result| if there is
// static (built-in) state for |host|. If multiple entries match |host|,
// the most specific match determines the return value.
bool GetStaticDomainState(const std::string& host,
STSState* sts_result,
PKPState* pkp_result) const;
- // Returns true and updates |*result| iff |host| has HSTS/HPKP/Expect-CT
- // (respectively) state. If multiple entries match |host|, the most specific
- // match determines the return value.
+ // Returns true and updates |*result| iff |host| has dynamic
+ // HSTS/HPKP/Expect-CT (respectively) state. If multiple entries match |host|,
+ // the most specific match determines the return value.
//
// Note that these methods are not const because they opportunistically remove
// entries that have expired.
diff --git a/chromium/net/http/transport_security_state_static.json b/chromium/net/http/transport_security_state_static.json
index 1ab7b859697..5160001f19b 100644
--- a/chromium/net/http/transport_security_state_static.json
+++ b/chromium/net/http/transport_security_state_static.json
@@ -641,6 +641,7 @@
{ "name": "googleweblight.com", "policy": "google", "include_subdomains": true, "pins": "google" },
{ "name": "google.ws", "policy": "google", "include_subdomains": true, "pins": "google" },
{ "name": "gstatic.com", "policy": "google", "include_subdomains": true, "pins": "google" },
+ { "name": "gstatic.cn", "policy": "google", "include_subdomains": true, "pins": "google" },
{ "name": "gvt1.com", "policy": "google", "include_subdomains": true, "pins": "google" },
{ "name": "static.googleadsserving.cn", "policy": "google", "include_subdomains": true, "pins": "google" },
{ "name": "urchin.com", "policy": "google", "include_subdomains": true, "pins": "google" },
@@ -2441,7 +2442,6 @@
{ "name": "wvr-law.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wzyboy.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "xenesisziarovky.sk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "xf-liam.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "yksityisyydensuoja.fi", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "yokeepo.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "zravypapir.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -2873,7 +2873,6 @@
{ "name": "fteproxy.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "g2g.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gambitprint.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "gamercredo.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "genuxation.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "getnikola.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "github.party", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -4606,7 +4605,6 @@
{ "name": "carboneselectricosnettosl.info", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "carsforbackpackers.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cecipu.gob.cl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "centricweb.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "chcemvediet.sk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "christiaanconover.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "christianbro.gq", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5159,7 +5157,6 @@
{ "name": "bentley.link", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "berra.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bfw-online.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "bgmn.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "biasmath.es", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "biou.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bitcoinworld.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5902,7 +5899,6 @@
{ "name": "wondermags.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "xiaofengsky.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "zqhong.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "bmoattachments.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dorianharmans.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "inverselink-user-content.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "inverselink.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -6425,7 +6421,6 @@
{ "name": "jdubya.info", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jeffcasavant.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jeremiahbenes.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "jeugdkans.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jhejderup.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jimas.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jka.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -7632,7 +7627,6 @@
{ "name": "theworldsend.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "thezonders.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tmitchell.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "tnrsca.jp", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "todobazar.es", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tonsit.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tonsit.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -10768,7 +10762,6 @@
{ "name": "setphaserstostun.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "setuid.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sevenmatches.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "shadoom.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "shadowsocks.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "shadowsworldonline.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "shagi29.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -11347,7 +11340,6 @@
{ "name": "zjutv.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "zomerschoen.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "zorium.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "zuram.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "zvncloud.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "zyf.pw", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "4x.fi", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -11849,7 +11841,6 @@
{ "name": "ivi.es", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jan-cermak.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jimgao.tk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "jeroenseegers.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "itcko.sk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "joedavison.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "joshuarogers.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -12881,7 +12872,6 @@
{ "name": "kjarni.cc", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kkovacs.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kkzxak47.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "kngkng.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ko-sys.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "koluke.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "koluke.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -13077,7 +13067,6 @@
{ "name": "rickweijers.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "right2.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rkkhok.hu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "roguelikecenter.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "roguesignal.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rose-prism.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "roseitsolutions.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -13395,7 +13384,6 @@
{ "name": "attogtech.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "au2pb.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "auditos.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "ausoptic.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "avaaz.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "avaq.fr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "avqueen.cn", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -13506,7 +13494,6 @@
{ "name": "bypassed.host", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bypassed.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bypassed.online", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "bypassed.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bypassed.party", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bypassed.press", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "bypassed.pw", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -20130,7 +20117,6 @@
{ "name": "sokietech.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "skynetz.tk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "smartviewing.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "sinnovate.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "silentexplosion.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "shopherbal.co.za", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "slashand.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -24091,7 +24077,6 @@
{ "name": "painefamily.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pantallasled.mx", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "paradiesgirls.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "paradisenazarene.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "paratxt.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "parkrocker.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "payboy.rocks", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -24817,7 +24802,6 @@
{ "name": "avonlearningcampus.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "avpres.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "avtoforex.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "avtosept.by", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "awei.pub", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "awningsaboveus.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "axialsports.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -25423,7 +25407,6 @@
{ "name": "devisonline.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dezintranet.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "df1paw.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "dfnet.ml", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dgx.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "dhlinux.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "diagnosia.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -25553,7 +25536,6 @@
{ "name": "eez.ee", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "ef-georgia.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "effective-altruist.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "effishiency.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "eigo.work", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "einfachbahn.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "einhorn.space", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -25943,7 +25925,6 @@
{ "name": "gregmartyn.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gregorykelleher.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "grevesgarten.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "greybit.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "grillteller42.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "groenewoud.run", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "grow-shop.ee", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -26265,7 +26246,6 @@
{ "name": "jaan.su", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jability.ovh", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jacobdevans.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "jakeguild.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jamanji.com.ng", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "james-bell.co.uk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "jamesaimonetti.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -27280,7 +27260,6 @@
{ "name": "preexport.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "prefix.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "preludes.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "prenger.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "prepare-job-hunting.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "prestige-car-location.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "pretachique.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -27459,7 +27438,6 @@
{ "name": "riversideradio.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rj-onderneemt.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rkc-hygrotherm.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "rlsnet.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rm-it.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rnag.ie", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "robertabittle.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -27742,7 +27720,6 @@
{ "name": "smartfon4you.ru", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "smime.io", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "smksultanismail2.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "smzsq.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "snapserv.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sneak.berlin", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sneeuwhoogtes.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -29931,7 +29908,6 @@
{ "name": "grayclub.co.il", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gruwa.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "frontline.cloud", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "gta5voice.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gst.name", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "gmx.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "hacker8.cn", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -31317,7 +31293,6 @@
{ "name": "rebelz.se", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "reflexions.co", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "radical.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "renyiyou.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "public-g.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "reldoc.com.mx", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "public-projects.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -32798,7 +32773,6 @@
{ "name": "chuck.ovh", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cloudlight.biz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "coffeetocode.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "clubalfa.it", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cinerama.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cirurgicagervasio.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "cidadedopoker.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -34679,7 +34653,6 @@
{ "name": "xn--y8j5gq14rbdd.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "xn--n8jp5083dnzs.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "zonesec.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "zhangsidan.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "zoki.art", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "yandere.moe", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "xn--6x6a.life", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -35200,7 +35173,6 @@
{ "name": "streamthemeeting.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "subwayz.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "sussexwebdesigns.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "sussexwebdesigns.info", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "swissid.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "talltreeskv.com.au", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "tdrcartuchos.com.br", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -36984,7 +36956,6 @@
{ "name": "kpfanworld.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "krasavchik.by", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "krokodent.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "krugoval.hr", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kudo.co.id", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kuechenprofi-group.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "kuehnel-online.eu", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -37398,7 +37369,6 @@
{ "name": "raeven.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rainbowstore.com.ua", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rainpaper.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "randy.su", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "rb-china.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "reaiaer.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "realestateradioshow.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -38516,7 +38486,6 @@
{ "name": "wivoc.nl", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wolszon.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wondergorilla.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
- { "name": "worcesterdance.org", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wordbits.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "wordcounter.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
{ "name": "work-in-progress.website", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -39743,7 +39712,6 @@
{ "name": "raidensnakesden.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rainbowinflatables.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rajyogarishikesh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "ramov.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rascals-castles.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rascalscastles.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "rascalscastlesdoncaster.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -41216,7 +41184,6 @@
{ "name": "kxnrl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "l7plumbing.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lacuevadechauvet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "lafr4nc3.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lag-gbr.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "landhaus-christmann.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "lanternalauth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -41619,7 +41586,6 @@
{ "name": "detuinmuze.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "developyourelement.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dierabenmutti.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "digitalbox.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "digitalwasteland.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "direct2uk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "dirtygeek.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -43009,7 +42975,6 @@
{ "name": "gigime.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ginza-luce.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gites-alizea.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "gkvsc.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "glaciernursery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "gladystudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "globalgovernancewatch.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -43535,7 +43500,6 @@
{ "name": "octohost.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "ohohrazi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "oisd.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "olgui.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "oliveoil.bot", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "oliverclausen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "oliviervaillancourt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -43752,7 +43716,6 @@
{ "name": "scib.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "scicomm.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "scijinks.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
- { "name": "scrapmalin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "screenmachine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sdxcentral.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "sean-wright.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -45971,6 +45934,3149 @@
{ "name": "zimmer-voss.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zmscable.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
{ "name": "zylai.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1231212.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "123123q.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "123123qq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "123bearing.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "123bearing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "123bearing.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "123roulement.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "123roulement.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "24timeravis.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "2au.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3555500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3lot.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500103.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500108.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500a500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500b500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500c500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500d500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500e500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500f500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500g500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500h500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500i500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500j500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500k500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500l500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500m500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500n500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500o500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500p500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500pingtai.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500q500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500r500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500s500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500t500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500u500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500y500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "500z500.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "5364.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "5364d.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "56877.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "918yy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "91966.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aanbieders.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "abos.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "activecare-monitor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adf-safetytools.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "advanceworx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "affordablehealthquotesforyou.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "affvps.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agechecker.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agenziaimmobiliarezeta.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "airikai.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alexanderb.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alistairholland.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allprorisk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "altered.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "altphotos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "amello.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "andalusierondreizen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "andycloud.dynu.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "angehardy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anglesgirl.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "animojis.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "annmariewaltsphotography.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ansgar.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "appify.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "applicationmanager.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "appshuttle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arno-klein.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arno-klein.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arno-klein.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arschkrebs.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aspirateur-anti-pollution.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "atgroup.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "autorando.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "autospurgo.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "awxg.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b72.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "baches-piscines.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "badgesenpatches.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "balia.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "balticnetworks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "banketbesteld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "baopublishing.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "baraxolka.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bart-f.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "baseconvert.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bauer.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bck-koethen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "beckon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "beginatzero.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "benc.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "benmorecentre.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bergfreunde.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "berz.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bestautoinsurance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bettingsider.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bfgcdn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bflix.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "binarydream.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "birdslabel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitcalt.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitcalt.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitmarket.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitmarket.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bloemenbesteld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blueoakart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blueskycoverage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blundell.wedding", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bmwcolors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "borisenko.by", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bowlcake.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bozdoz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "br7.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brainsik.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brightonzhang.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brimspark.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brimspark.systems", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "broodbesteld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bsd.com.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buddhismus.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buena.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bueroplus.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buffaloturf.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buyritefairview.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bwl-earth.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cadre.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "caibi.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "callanbryant.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "canadian-nurse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cannahealth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "carbontv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cardexchangesolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "carlobiagi.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "caryefurd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "catalogobiblioteca.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cb-crochet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cbmusa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cd5k.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cdasenegal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cedricmartineau.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "celebrityhealthcritic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "celluliteorangeskin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "celluliteremovaldiet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "centralegedimat.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chargify.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chasetrails.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "checkyourreps.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chimerity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cinemarxism.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cio-cisointerchange.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "citybeat.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clase3.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cldfile.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clicandfioul.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cliniquecomplementaire.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cloaked.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cloudfiles.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cmftech.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cna-aiic.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cnaprograms.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cnatraining.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "codigo-bonus-bet.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "codigodelbonusbet365.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coins2001.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "colpacpackaging.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "combatircelulitis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "combattrecellulite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "comodosslstore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "conju.cat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "constares.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "consultingroupitaly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cooljs.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coolpickz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coussinsky.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cpd-education.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "craftinghand.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "craigsimpson.scot", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "croeder.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "croncron.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "crownpoint.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cryptocaseproject.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cursosgratuitos.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cyberatlantis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cybercareers.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "d.rip", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "daniel-milnes.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dannycairns.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "danwolff.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dataregister.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "davidhanle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dawoud.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ddnsweb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "debbyefurd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dedge.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deechtebakkers.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dekeurslagers.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dekulk.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "delf.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "der-lan.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "despachomartinyasociados.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deutsche-seniorenbetreuung.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dharamkot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dictionaryofnumbers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dietaanticelulitica.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dietaanticelulitis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dietacelulitis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dietafeliz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "disarc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "divi-experte.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "djsk.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dko-steiermark.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dmailshop.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dmmultionderhoud.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dmschilderwerken.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "domster.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "doooooops.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dorfzittig.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "douglasstafford.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "drachenleder.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "drakensberg-tourism.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "drmayakato.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dubbingkursus.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "duckduck.horse", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dupree.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dyn-dnhensel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dzsibi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e-baraxolka.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "easydumpsterrental.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "easyreal.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "easyschools.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ebest.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "echo.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "echoteam.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "echoteen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "econverter.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "edgevelder.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "edinburghsportsandoutdoorlearning.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "edlinger.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "edlinger.mobi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "educationfutures.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "edwinyrkuniversity.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eenekorea.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eengoedenotaris.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eldapoint.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "electrotainment.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elektronische-post.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elerizoentintado.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eliminercellulite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elisabethrene.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "emkrivoy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "emmababy420.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "employeeexpress.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "enbecom.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "encrypt.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ent-london.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "entercenter.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "epo32.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ervaarjapan.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "espacecuisine.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "essayshark.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "estedafah.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "euwid.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "evangelicalmagazine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ex-deli.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "exoscale.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "experienceoutdoors.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eztvtorrent.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fabrica360.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "facebydrh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "facucosta.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "failoverplan.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fairssl.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "faisalshuvo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "faithleaks.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "familyworld.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "faraonplay5.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fegli.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "final-expense-quotes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "financepark.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "finnwea.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fir3net.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flashbaggie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flaviu.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fliio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fnbnokomis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "followthedog.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "forodieta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "foundchurch.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "frankinteriordesign.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freddieonfire.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freitasul.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freitasul.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "frequentflyerapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "friederloch.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "frietbesteld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "funkner.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "funtime.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fxmarketing.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fxmarketing.net.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fxseo.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fxwebsites.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fxwebsites.net.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fyksen.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "garyrh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "geekystudios.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gesundheitmassage.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "getbreadcrumbs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "getpanelapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "getthefriendsyouwant.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "give2charity.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "give2charityapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "glenavy.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "glenberviegolfclub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "glotech.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "goflo.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gogonano.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "got-tty.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gpga.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grafmag.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "greatlengthshairextensionssalon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "greatlifeinsurancegroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "greener.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "greenhats.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "groentebesteld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guides-et-admin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guildbase.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hakaru.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hamburgerbesteld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hamcram.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "happydietplan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hardez.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "healthstar-dev.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "healthstar.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "helicaldash.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hendrik.li", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hestervanderheijden.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "higgsboson.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hilaryhutler.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hitandhealth.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hoevenstein.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hofauer.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hookany.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "horizonlawncare.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hostcoz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hsn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hsulei.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "i-aloks.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ianmooreis.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "icloudlogin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "icowhitepapers.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "idealvenir.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "idlethoughtsandramblings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ilemonrain.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "illustrate.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ilove.fish", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imask.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imppac-schmuck.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "indianaberry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inf-fusion.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infirmiere-canadienne.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "insideofgaming.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "insolved.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "intal.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "intelliance.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "internationaltalento.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "internet-aukcion.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "intita.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "invadelabs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ipresent.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itsense.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jahmusic.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "janvari.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "janvaribalint.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jkyuan.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "johnsonho.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jolokia.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "juef.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "juliekproperties.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jurijbuga.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "justbelieverecoverypa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kaasbesteld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kaitol.click", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kamui.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "karlloch.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kebabbesteld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "keithlomax.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kempo-sissach.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kenbillionsyuan.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kennynet.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kenx5.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kevinmoreland.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kids-ok.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kimdumaine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kinderopvangzevenbergen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kisma.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "klaxon.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "klcreations.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kleim.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "knightsbridgewine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "komelin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "koolitee.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kouki-food.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kuchenfeelisa.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kuhnelautorepair.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kulickovy-pojezd.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kuttler.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kx197.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lakehavasuhomes.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lamp.re", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "landrovermerriamparts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laparoscopia.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laranjada.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "larbertbaptist.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lavasing.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laylo.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lemonparty.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lemouillour.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lespret.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "letraba.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "leulu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lietaer.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lifeinsurancepro.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lighthouseinstruments.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "limap.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lincolnfinewines.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "linearmap.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "literarymachin.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "littlebestfriend.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "littleredsbakeshop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lmrcouncil.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "location-fichier-email.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "locationvoiturecorse.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "loposchokk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lotl.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lyukaacom.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lzqii.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mack.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mackeysack.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "madandpissedoff.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maddistonevangelical.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maddistonparentcouncil.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maddistonpsa.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "madweb.design", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "magical-secrets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "magicalcircuslv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maisondoree.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maitriser-son-stress.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "makersatwork.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "manoro.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "manylots.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marechal-company.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marelijah.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "markantoffice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marketlinks.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "martasibaja.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "matt-royal.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mauran.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maxp.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mcfx.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mcivor.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mcprocdn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mechok.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "medicare-providers.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "medicarecoveragefinder.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "medicareinfo.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "medigap-quote.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mediter-simplement.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "megauction.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "meine-reise-gut-versichert.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "menudieta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mercedespartscenter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "meshok.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "metafurquest.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mfacko.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mgtbaas.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "michiganstateuniversityonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mickusit.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mieuxvivreadarvoy.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "millibitcoin.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "minimal-apps.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "monakasatmasr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moneypark.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "morepablo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mormonleaks.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "morningcurve.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "movie1000.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mtgsuomi.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "muckrack.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myadpost.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myphotoshopbrushes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myproxy.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myrealestateschool.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mytfg.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "naomiheji.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "narenderchopra.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nationalhomequotes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nationwiderealtyinvestors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nbib.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nbrain.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neil-barrett.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neil-barrett.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nejenpneu.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "netbrewventures.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "netfog.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "netsafeid.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nettegeschenke.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "newchance.store", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "niallator.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nicholasperkins.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nirjharstudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nllboard.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nlleisure.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nobledust.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "norys-escape.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nostosh.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nugdev.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "numbermunchers.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nurseone.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nursingschool.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nwbc.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nzdmo.govt.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "octarineparrot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ohne-name.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "olltechjob.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "omdesign.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "online-health-insurance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oscillation-services.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "osielnava.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ourworldindata.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "overrustle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "owid.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "owl-hakkei.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "owl-square.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paass.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pamsorel.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paris-store.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "parkhillsbaptist.church", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "partypearl.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "partyspecialists.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "patatbesteld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pdomo.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "peaudorange.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "penser-electronique.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pestkill.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "peterbruceharvey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "philipp-trulson.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "phosphene.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "photosoftware.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pieldenaranja.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pietermaene.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pioneer-car.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pioneer-rus.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pircher.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pixabay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pizzabesteld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "placedaffiliate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "planetknauer.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "play-charades.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "plumbingcentral.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pmaene.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "policesromandesrecrutement.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "policyreporter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "policyreporter.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "polit-it.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pomockypredeti.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "poopr.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "portofala.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "posyperfume.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "precision.st", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "prijsvergelijken.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "primalbase.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pristinegreenlandscaping.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "producepromotions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "progenitor.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "programmaticmagic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "psdreams.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pst.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "psychicsource.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "psytrance-pro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "punte-juwelier.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "q123123.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quant-labs.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quarkdose.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "questions-admin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quiet-waters.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qwertyatom100.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "r33.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rabica.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rainstormsinjuly.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "raipet.no-ip.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "randomcode.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "raoul-kieffer.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rawr.sexy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rcsolutions.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "re-engines.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reformatreality.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "regime-anticellulite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "regimebonheur.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "regimecellulite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reginagroffy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "removalcellulite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "remrol.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "renaissanceplasticsurgery.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "renewpfc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rent-a-c.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reseponline.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rideyourdamn.bike", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rightnetworks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ristoviitanen.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rittis.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "robottip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rodafe.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "routercncperu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rpus.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rucksack-rauf-und-weg.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rusmolotok.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ryancarter.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "safeui.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "salexy.kz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "salvagedfurnitureparlour.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sanipousse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sarahwikeley.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sasanika.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "science-anatomie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scootaloo.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scottishcu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scrod.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sdg-tracker.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "segaretro.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "semrush.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "seriouss.am", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sgutranscripts.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shaamrelief.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shadwe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shellgame.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shermantank.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shivammaheshwari.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shopstart.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shorehamfort.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "short-term-plans.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shouldihookupwithmybarista.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "showroom113.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shredriteservices.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shyuka.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sigmapramuka.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "silvobeat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sirchuk.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sivale.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skatesins.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skid.church", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skomski.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smartservices.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "snackbesteld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sodomojo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "somaliaonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "songluck.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spacedots.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sphido.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spittank.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sportvereine.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spotteredu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spreadsheetgear.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "srun.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ssh.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "star-clean.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "startergen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stephaniedeady.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sterlinx.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sternadel.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sternenbund.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stilecop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "strajnar.si", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "strongsalpinesucculents.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stroomacties.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "structure.systems", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stuartmorris.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "studentse.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "summershomes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sun-leo.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "supermercadosdia.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sushibesteld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "svinformatica.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taartbesteld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tagabrand.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tagpay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taimane.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "talkingmoose.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taxi-puck.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "team2fou.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teddyss.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teenerotic.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "telamon.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "telecharger-itunes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "telework.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teltru.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tempflix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tetrafinancial-manufacturing-industrial-equipment-financing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tetrafinancial-news.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tetrafinancial-technology-equipment-software-financing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teufel.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thatdarkplace.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theanticellulitediet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thecellulitediet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "themaster.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "themefoxx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "themonkeytrail.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thestudyla.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theuucc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "think-positive-watches.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thomasscholz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tildesnyder.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "timbrust.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "time2choose.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "timoso.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tirlins.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tjampoer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tleng.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tnl.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tobyalden.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tokyobarbershop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "toonsburgh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "torg-room.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trashwagon.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "travelshack.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trezy.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trezy.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "truentumvet.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trustserv.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tslcontractors.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tss.am", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tsung.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tty1.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "u-metals.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uc.ac.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uitslagensoftware.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unatco.noip.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unedouleur.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unstamps.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "usage.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "usastaffing.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uwsoftware.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uwvloereruit.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vapecrunch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "venenum.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "verry.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "versbesteld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "versolslapeyre.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vestingbar.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "via-shire-krug.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "visionnissancanandaiguaparts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vjpatel.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vleesbesteld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vlzbazar.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vocalsynth.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vulns.sexy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vykup-car.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wallacehigh.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wallacequinn.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "waterdrop.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webgaff.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webhostingzzp.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "weedcircles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "weien.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wella-download-center.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "welpo.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wendlberger.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wg-steubenstrasse.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wiebel.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wijnbesteld.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wjr.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "womensalespros.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wonghome.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wpcdn.bid", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wpmu-tutorials.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wpoptimalizace.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wpsec.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wristreview.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wrp-timber-mouldings.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wtwk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wyo.cam", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "x-one.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xia.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn-----8kcgbo2bmdgkdacthvjf.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--4pv80kkz8auzf.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--qfun83b.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xpoc.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xzoneadventure.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yahan.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yazaral.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ylde.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yourskin.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yuanjiazhao.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yukari.cafe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zeelynk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zfg.li", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zhl123.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zorig.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zula.africa", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zumazar.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zyger.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "022367.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "022379.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "022391.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "022501.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "022503.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "022507.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "022561.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "022571.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "022601.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "022609.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "022610.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "02327.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "02375.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "026122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "02638.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "03170317.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "0391315.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "0511315.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "0792112.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "081752.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "081763.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "081769.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "081783.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "081925.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "081927.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "081957.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "081967.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "082157.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "082159.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "082167.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "082173.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "082175.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "082179.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "082187.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "082192.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "082193.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "082195.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "082359.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "083903.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "083905.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "083907.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "083912.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "083957.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "083960.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "083962.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "083965.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "083967.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "09892.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1001mv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "10430.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "10435.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "10436.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "10438.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "10439.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "10453.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "10495.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "10774.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "10840.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "10v2.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "124133.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "124633.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "143533.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "143633.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "143733.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "143933.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "145433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "145733.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "146233.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "146433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "146533.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "146733.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "149433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "149733.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "152433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "154233.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "154633.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "154933.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "156433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1661237.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1811559.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1876996.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "18celebration.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "18celebration.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "192433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1f123.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1montre.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "215dy.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "247exchange.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "2858958.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "2991236.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3-dot-careapp1-146314.appspot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "302422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "303422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "304122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "304322.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "304622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3056999.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "309422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "30yearmortgagerates.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "310422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "313422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "314022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "314122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "314322.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "314522.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "314622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "314633.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "314922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "315422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "316433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "319422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "320281.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "324022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "324122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "324133.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "324522.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "324533.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "324922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "325422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "326422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "326433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "329422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "340422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "340622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "340922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "341422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "341433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "341533.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "341633.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "341733.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "341922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "342022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "342033.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "342133.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "342633.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "342733.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "342922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "342933.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "343022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "343622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "343722.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "343922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "346022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "346033.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "346122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "346233.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "346322.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "346422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "346522.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "346533.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "346722.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "346922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "348233.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "348433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "348533.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "349022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "349033.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "349233.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "349433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "349533.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "350422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "354022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "354133.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "354233.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "354622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "354633.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "354922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "354933.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "356433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "370422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "371422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "373422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "374933.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "375422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "380422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "390422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "392422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "393422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "394022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "394122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "394322.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "394522.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "394622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "394922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "396422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "4237.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "440hz.radio", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "4everproxy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "504122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "504322.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "504622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "504922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "506422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "514122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "514522.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "514622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "514922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "515422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "516422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "51877.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "519422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "524022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "524622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "524922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "52ncp.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "531422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "534122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "534622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "534922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "536422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "540922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "541022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "541622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "541722.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "541922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "545922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "576422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "579422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "583422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "585422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "586422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "591422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "592422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "5930593.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "594022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "594622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "595422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "596422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "5997891.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "602422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "604122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "604322.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "604522.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "604622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "605422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "606422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "609422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "614022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "614322.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "614922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "61730123.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "621422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "624022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "624122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "624322.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "624522.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "624922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "626422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "630422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "631422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "634022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "634322.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "634622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "634922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "635422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "636422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "639422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "640622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "640722.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "640922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "641022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "641322.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "641422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "641522.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "641622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "641722.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "641822.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "641922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "642022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "642322.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "642422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "642722.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "642822.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "642922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "643022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "643122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "643722.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "643922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "645022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "645122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "645322.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "645722.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "645822.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "645922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "645ds.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "646022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "646322.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "646722.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "649022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "649622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "649722.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "649822.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "651422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "652422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "659422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "6652566.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "670422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "671422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "672422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "673422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "676422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "679422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "680422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "690422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "691422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "692422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "693422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "694322.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "694622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "694922.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "6997896.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "704233.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "704533.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "704633.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "712433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "713433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "714133.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "714533.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "714633.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "715433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "718433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "719433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "724233.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "726433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "728433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "729433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "730433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "731433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "732433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "735433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "736433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "738433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "739433.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "740833.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "741833.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "742833.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "743833.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "7885765.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "7891553.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "7891997.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "789zr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "7proxies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "804322.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "809422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "80993.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "814022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8189196.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8maerz.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "903422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "905422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "912422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "913422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "914122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "919422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "924122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "924322.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "924622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "926422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "931422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "932422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "934122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "943022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9454.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "946022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "946422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "949022.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "949122.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "949622.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "949722.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "95778.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9679693.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9681909.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "972422.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9788876.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9918883.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aavienna.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "acgpiano.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "acheter-ethylotest.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adftrasporti.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adoucisseur.shop", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "advocoeurdehaan.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "advtran.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aesthetx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agnesk.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agrafix.design", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ahtuxpk.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aisi316l.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "akronet.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "akropol.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "albanboye.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alco-united.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aldred.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alerbon.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allontanamentovolatili.milano.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allstakesupply.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alphaetomega3d.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "andso.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "antarespc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aobogo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "apparelfashionwiki.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ask1.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asmood.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "audirsq3.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ausmwoid.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "badblock.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "balance7.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "balenciaspa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bc-personal.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "benceskorka.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "birdandbranchnyc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bischoff-mathey.family", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitbank.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitclubfun.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blackgate.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "boke112.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bondtofte.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "booksinthefridge.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bpa.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brackets-salad.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brovelton.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bueroshop24.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cafedupont.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cafedupont.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cafedupont.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "caiwenjian.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "callumsilcock.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "callumsilcock.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "campus-discounts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cemeteriat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "christianjens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "city-walks.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ckp.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clien.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clubdelzapato.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cncado.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cnsyear.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cocareonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "codersbistro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "codetheworld.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "consec-systems.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "continuum.memorial", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "corona-renderer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "course.rs", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cozitop.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "craftist.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "crunchrapps.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "crypto-navi.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cryptoparty.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "csfcloud.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "csrichter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cwbrtrust.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dancingshiva.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dawena.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deep.social", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dggm.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dggwp.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "diamondt.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digitalexhale.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dingelbob-schuhcreme.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "directwatertanks.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "disinfestazioni.rimini.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dixi.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dmmkenya.co.ke", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dnsql.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dokipy.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "donpomodoro.com.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "drivya.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dropq.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dub.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dynamo.city", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e-traceur-france.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e7fun.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ebonyporn.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ed4becky.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eigenpul.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eigenpulse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "electicofficial.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "electricfencealberton.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "electricfencebenoni.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "electrician-umhlanga.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "electricianumhlangarocks.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elfe.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elixi.re", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elnoorandelmohanad.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "emaging-productions.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "escort-fashion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ethantskinner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "etskinner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eurotravelstar.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "evidentiasoftware.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "evodia-spirits.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "excesssecurity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "expanddigital.media", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "expiscor.solutions", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "falegname-roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "falldennismarketing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fantastici.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "farrelf.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fassaden-selleng.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fastcash.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "feegg.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fhmkh.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fil.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "filtr.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fishgen.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "foluomeng.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "francetraceur.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freerealincest.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freesoftlab.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fs257.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fsj4u.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fuantaishenhaimuli.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "funds.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gamereader.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "genoveve.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gesundes-im-napf.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "getdeveloper.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ghibli.studio", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "givip.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "glicerina.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "griechische-pfoetchen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "griyo.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gsaj114.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gubagoo.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gupfen.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gxmyqy.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "healthgames.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hg525.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hilltopcellar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "himekomi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hjkbm.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hjkhs.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hjtky.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hmcdj.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hoarding.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hoeveiligismijn.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "honey.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hoodiecrow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "horecaapparatuurkobezuijen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "huashan.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hubertmoszka.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hydrazin.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "idafauziyah.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "idealninajemce.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "illicitdigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imediafly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imprimante-3d-store.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "incestporn.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infocusvr.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inku.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "innovum.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "invidio.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ioerror.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iotfen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ipv8.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ironpeak.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "isaacdgoodman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itn.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iyuanbao.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jacobamunch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jakebeardsley.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jamie.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jamjestsimon.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jaysaw.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jfbst.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "johannesen.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "johnsanchez.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "johnyytb.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jong030.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jordanp.engineer", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jvega.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kati0.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "keelove.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "keihin-chaplin.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kelderwijnen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kffs.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kimo.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kimtran.kim", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kinos.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lavoieducoeur.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "liam-is-a-nig.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lieberwirth.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lightbox.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "listekdo.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "livinglocalnashville.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lobosdomain.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lode.li", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "logtalk.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "logtalk.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "luckydog.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "luoxingyu.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maintenance-traceur-hp.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "majkassab.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "manfredi.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mar-eco.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marcelwiedemeier.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marshmallow.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "matridiana.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mcinterface.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "medi.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "medienweite.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "melillaorienta.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mercier-auto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mercier-cars.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "michele.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mijndiad.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "milftube.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mobiletry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "monkay.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "montredeal.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moo.pet", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mruganiepodspacja.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mtrip.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mulenvo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "multisite.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myammo.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "navienna.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neflabs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "netspeedia.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nexttv.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nginxconfig.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nhsolutions.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nightstand.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "njast.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "novinivo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "np-edv.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nugetdependencies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nutrieduca.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nyhaoyuan.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "odosblog.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "office-discount.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "okashi.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "omeuanimal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "openmetals.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ouglor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "p-t.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paintingindurban.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "parisprovincedemenagements.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pasportaservo.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "passendonderwijs.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pci-e.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "peinard.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pensionpilot.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "philsown.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pilot.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pilotgrowth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pix-geeks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "playyou.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pmsfdev.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pornoserver.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "portablespeakersfinder.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "powaclub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "premierjewelersjax.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "prmte.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "promesa.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "purplebricks.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "purplebricks.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "purplemet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qabalah.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qq52o.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quantumpair.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quintype.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "racesport.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "radiosendungen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "raphaeladdile.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "realfamilyporn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "realfamilysex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "realfreedom.city", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "realincest.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "realincestporn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "really-simple-plugins.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "redporno.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ressos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rhevelo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "robdavidson.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "romano.guru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rootspersona.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "roundaboutweb.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ruquay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "salvaalocombia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "schmelle.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scholz-kallies.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scpslgame.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "securitysense.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "see.wtf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sergeemond.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "serkaneles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sfcomercio.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shafou.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shalazine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sharpe-practice.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shehaal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shirtsdelivered.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shlmail.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "showroom.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "showroom.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shrug.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "silvobeat.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "simark.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sjv4u.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skifttiljutlanderbank.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smmcab.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smsk.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smsk.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smskmail.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "softw.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "somosnoticia.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spanda.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "staklim-malang.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "steerty.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stefanorossi.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "storytea.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stuartmorris.id.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stuartmorris.name", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stuartmorris.tel", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sublocale.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sugartownfarm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "szymczak.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taddiestales.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "takuhai12.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taplemon.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taplemon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tatildukkani.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tcspartner.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "techbelife.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teesypeesy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "telefoon.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "terabyteharddrive.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thallinger.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theactuary.ninja", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thebannerstore.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "theeighthbit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tir-mauperthuis.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tonkayagran.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "torontostarts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "touhouwiki.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "transbike.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "transfers.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tsukeawase.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tulenceria.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tungstenroyce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uclip.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uktw.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ulovdomov.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unblocked.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unstockd.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "usuan.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "utazas-nyaralas.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vase-eroticke-povidky.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vbwinery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vcraftaudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vdzwan.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "veggie-treff.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "versicherungen-werner-hahn.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "villesalonen.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "virtualhealth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "voidcore.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "votesandymurman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wanquanojbk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wealthformyhealth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webstijlen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "welovecatsandkittens.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wentu.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wesoco.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wewitro.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wgplatform.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whatsupdeco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wingmin.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wjci.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wolfarth.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "workcheck.bz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wptomatic.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wrapit.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "writeenglishright.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ww0512.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wwbsb.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wwjd.dynu.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xiaobude.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xice.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xmtpro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--80aejljbfwxn.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--dk8haaa.ws", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--lckwg.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--wq9h.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xy1919.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xy6161.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xy6262.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xy6363.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xy7171.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xy7272.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xy7373.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ycherbonnel.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yh35.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yigujin.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "youareme.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "younl.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "your-erotic-stories.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yxt521.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zaagbaak.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zenti.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zg-dyw.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zhangheda.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zikinf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zirtual.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zkzone.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zonadigital.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zonky.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zonkysetkani.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zooplankton.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zs-reporyje.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zubora.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zzekj.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "029inno.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1b1.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1r.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1salland.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "245meadowvistaway.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3djuegos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3s-datasolution.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3s-datasolutions.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3s-ddns.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3s-dns.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3s-mail.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3sdatasolution.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3sdatasolutions.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3sddns.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3shosting.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3smail.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "645ds.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "69fps.gg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "6ird.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "808phone.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "88889822.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "918gd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9822.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9822.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "99999822.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9farm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9jajuice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "9y.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "a-msystems.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "acerentalandsales.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "acquisition.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adrup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "advertisemant.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aep-digital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "affiliatefeatures.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "afterskool.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agiserv.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ahmetozer.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aibsoftware.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ajiaojr.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ajiaojr.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ajiaojr.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ajiaojr.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "akiym.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aktan.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "akukas.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "algofactory.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allbrandbrand.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allontanamentovolatili.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aloesoluciones.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alpes-deis-tools.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "altiacaselight.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "altoneum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "amirautos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "andrei-nakov.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anglirl.eu.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anguiao.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aniaimichal.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "antennista.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anthisis.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anyquestions.govt.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aopsy.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "apercloud.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "apobot.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "appgeek.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arda-audio.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "argama-nature.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arisevendor.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arka.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arno.pm", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "artefakt.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arteinstudio.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "artmanager.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asenno.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "atmschambly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "audiotechniker.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aussiefunadvisor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aussiestoresonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aussiewebmarketing.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "authoritysolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avocadooo.stream", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "awesomesit.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "axiumacademy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "az-moga.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "azadliq.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "backtest.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bakermen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bancaolhares.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bankee.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bankitt.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bassrider.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bbkanews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "beadare.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "beamer-discount.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "becklove.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "benedict-balzer.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "benjaminvasel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "besb.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "betacavi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "betrallyarabia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bidu.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bikiniatoll.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bildkomponist.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "billhartzer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "biogeist.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitstep.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blackilli.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blindpigandtheacorn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bltdirect.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bluecrazii.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bluntandsnakes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "boem.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bonibuty.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bookingworldspeakers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "breakpoint.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brendanbatliner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brown-devost.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "buildmorebuslanes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "c12discountonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "c3.pm", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "calluna.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "camshowhub.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "captainsinn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cartouche-deal.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "carun.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "casinoonlinesicuri.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cdncompanies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cdom.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "celcomhomefibre.com.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "centrosocialferrel.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cerivo.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ceskepivnisety.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cfda.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chaip.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chat2.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chcoc.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chrisbryant.me.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chundelac.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cio.go.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "claus-bahr.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cloudconsulting.net.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cloudconsulting.org.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cloudconsulting.web.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "codemperium.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coinx.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coldaddy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "combron.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "combron.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "comicspornoxxx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "conocimientosdigitales.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "converticacommerce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "coor.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "corelia.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cortexx.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "crc-online.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "crealogix-online.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cremepassion.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cross.lol", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cur.by", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cursosingles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cvcoders.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cwbw.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cwilson.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cybercocoon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cybersantri.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cygnan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "daikoz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dalepresencia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "daniel-cholewa.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dansage.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dartcode.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dataharvest.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dawnofeden.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ddns-test.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "decis.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deepaero.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "denbkh.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "detski.center", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deuchnord.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deutschebusiness.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deutscheshoponline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deuxmetrescubes.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dharveydev.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dictzone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dieterglas.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "discoverthreejs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "disinfestazioni.torino.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dispatchitsolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dispatchitsolutions.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "disti.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dockerup.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "doswap.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dramyalderman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dsteiner.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dubaosheng.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dumont.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dung-massage.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "duonganhtuan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dwbtoftshit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dwellstudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dybuster.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dynamicdesignuk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "e-bikesdirect.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eatmebudapest.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ed-matters.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ehmsen.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "el-news.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elb500ttl.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elcambiador.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "emobilityforum.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esgr.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esolitos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "esrs.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "etd-glasfaser.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ether.school", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ethergram.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "exoten-spezialist.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "expo-larionov.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "faerie-art.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fahrwerk.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "falaeapp.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "familie-poeppinghaus.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "farrel-f.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "farrel-f.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fbo.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fdm.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fedbizopps.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fedshirevets.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "feuerloescher-arten.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "feuerloescher-test.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ffw-zeven.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ffzeven.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fig.ms", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "filezilla-project.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "finalrewind.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "findapinball.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "findstorenearme.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "findstorenearme.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "findstorenearme.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fitqbe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fiuxy.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fixitfelix.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flagfox.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fleetsmith.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fly-en-drive.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flydrivesicilie.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flyswoop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "folwark.krakow.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "folwarkwiazy.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fort.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "forum-heg.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fotoflits.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "frettirnar.is", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fsrs.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ftptest.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fuck-your-false-positive.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fulltxt.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "funadvisor.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "funadvisorfrance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "furi.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "furlog.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "furrytech.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "furtherfood.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gailfellowsphotography.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gansleit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gaphag.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "garforthgolfclub.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "garten-diy.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "geekseries.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gemeinsam-ideen-verwirklichen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gisac.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "globelink-group.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "glotechkitchens.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "glotechrepairs.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gluedtomusic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gmccar.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "goa8.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "godruoyi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gosforthdentalsurgery.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "goshow.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gostaffer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gradenotify.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "greenenergysolution.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gubagoo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gvm.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hacc.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "haleo.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hartzer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hautaka.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "healthplansamerica.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heka.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "helpscoutdocs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "herkam.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "herrtxbias.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "herrtxbias.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hestia-systeme.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hestia-systeme.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hestia-systeme.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hestia-systeme.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hi808.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "highlightsfootball.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "highspeedinternet.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hillcountryoralsurgery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hiring-process.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hlidacnajemneho.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hollowpoint.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "holstphoto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "homeserver-kp.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "horrorserv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "houseofherbs.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "https-rulesets.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hudebnibazarmixer.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hundeverwaltung.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hxsf.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hyperautomotive.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "i00.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iamle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ianjmoriarty.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ianmoriarty.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "icnsoft.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ijm.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ilii.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imyunya.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inesfinc.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infermiere.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infra.land", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infra.press", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infranium.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ingredientdaddy.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "innersafe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inquant.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "intasky.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "intasky.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "invitacionesytarjetas.gratis", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ionote.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iphonekaitori.tokyo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ipo-times.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iptvzoom.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iran-poll.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "islandoilsupply.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ismena.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "it-faul.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "italieflydrive.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "itforcc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "izhaojie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jackops.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jakubarbet.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "james-digital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jamesrobertson.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jan-hill.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jaroslavc.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jateng.press", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jcom-communication-system.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jedayoshi.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jerret.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jettravel.com.mt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jhill.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jmatt.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jsuse.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jvsticker.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kamatajisyaku.tokyo.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kartatopia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "katemihalikova.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "katzenbrunnen-test.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kc3.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kcliner.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kcshipping.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kejar.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kenia-vakantie.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kenokallinger.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kerzyte.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "keymach.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kiaka.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kicou.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kiddies.academy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kiddieschristian.academy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kiddieschristianacademy.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kieran.ie", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kinderzahn-bogenhausen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kkull.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "koicenter-thuine.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "konpyuta.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kredigram.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "l.me.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lacantine.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ladadate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laharilais.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lamclam.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lame1337.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laperfumista.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lateral.dog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "learning-id.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "leastsignificantbit.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "legaillart.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lelambiental.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lemondenumerique.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lequerceagriturismo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "linext.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "linkat4.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lk-hardware.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "localblitz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lsws.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lukas-gorr.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "luminaires-online.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lw-addons.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "machu-picchu.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "madeloc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "magasinsenfrance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "magewell.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maikolfish.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mangapoi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "manuall.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "manuall.info.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "manuall.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "manuelpinto.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mapeo.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marclay.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mariereichl.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marketinggenerators.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marshallwilson.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mateuszpilszek.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mattatoio.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mattbagley.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "matthewsetter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maurice-walker.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maxbeenen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mc-jobs.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mc4free.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mclmotors.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mediafly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mediavault.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "medpeer.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mein-kuechenhelfer.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "melodiouscode.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "melodiouscode.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "memrise.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "meraseo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mes-bouquins.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "metanodo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mijnetz.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "millennium-thisiswhoweare.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moc.ac", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "modalrakyat.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "molokai.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moonagic.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moviespur.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "movimento-terra.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mrxn.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mtltransport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "multimed.krakow.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "multiroom-streaming.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myf.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mymusiclist.alwaysdata.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mysber.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mysockfactory.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mysockfactory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mythemeshop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "na-school.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nanofy.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nascio.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nausicaahotel.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nc2c.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nedys.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nextcloud.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nootropicpedia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "npcrcss.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nte.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nyatane.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oboeta.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "officeinteriors.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oldschool-criminal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "omniasig.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "omnisky.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onbuzzer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onesports.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onlineinfographic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onpermit.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onvousment.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "openbeecloud.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "opencrm.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "optometryscotland.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ortodonciaian.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oxro.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pablorey-art.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "panopy.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "panopy.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pantallasyescenarios.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "papillon-events.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "parkrunstats.servehttp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "partage.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pawsru.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pcsetting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "peerigon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "permeance108.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pesto.video", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "petrpikora.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pflanzenshop-emsland.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ph3r3tz.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pharmica.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pharmica.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "phaux.uno", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "phishing-studie.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "phishing.rs", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "piruchita.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pkbjateng.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pkbjateng.or.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pksps.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "planeexplanation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "plastovelehatko.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "plob.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "plumbingglenvista.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pluscbdoil.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pmf.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "polly.spdns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "poloniex.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "porkel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "porte.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "poshlashes.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "positivenames.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "prodegree.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "progenda.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "program-and.work", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "promozione.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pulser.stream", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qianqiao.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qis.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qonto.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quickinfosystem.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quikstorhawaii.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qybot.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "radiocomsaocarlos.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ragasto.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rainel.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rakugaki.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rante.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ravenx.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rdmtaxservice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "realme.govt.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reckontalk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "redfox-infosec.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "redneck-gaming.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reevaappliances.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reiseversicherung-werner-hahn.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "renovum.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "res-kc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "restaurantguru.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "resultsdate.news", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rfxanalyst.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "richie.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ring.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "risi-china.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rleeden.servehttp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "roaddoc.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "roams.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rodinnebyvanie.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rolandinsh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rondreis-amerika.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rondreis-schotland.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ronnylindner.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ruckzuck-privatpatient.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "safeocs.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sailingonward.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "salland1.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "saltireconservation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "samuel-dumont.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "santoshpandit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sapphirepearl.com.sg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "satellites.hopto.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "schimmel-test.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scottishseniorsgolf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scottseditaacting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scrumplex.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "seanchaidh.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "searx.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sebastiaanwijnimport.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "senekalstorageman.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "senseye.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sentidosdelatierra.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "servitek.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "servx.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "servx.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "shandonsg.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sharealo.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sharkie.org.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sho-tanaka.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "show-stream.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "signal.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "simplithai.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sirencallofficial.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sisseastumine.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sistemos.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skybloom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smries.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "snippet.wiki", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "solartrackerapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "songtianyi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sos-falegname.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "soulsteer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spacestation13.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spanjeflydrive.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "starking.net.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "starklane.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "steigerlegal.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stickswag.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stratuscloudconsulting.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stratuscloudconsulting.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stratuscloudconsulting.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stratuscloudconsulting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stratuscloudconsulting.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stratuscloudconsulting.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stratuscloudconsulting.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stratuscloudconsulting.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "studytactics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "suffix.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "supertechcrew.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "suurhelsinki.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "swerve-media-testbed-03.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sydneylawnandturf.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taitmacleod.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "taskutark.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tatilmix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "team.house", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tebodental.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "techinsurance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tecmarkdig.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tecon.co.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "test-textbooks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thecloudshelter.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thecompany.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "therandombits.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thesplashlab.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thewagesroom.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thomas-prior.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thor.re", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "threema.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "time.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tischlerei-klettke.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tomd.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tomsdevsn.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "topeyelashenhancerserumreviews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "topworktops.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "torogroups.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trade247.exchange", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trafas.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "traiteurpapillonevents.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "transporta.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "traslochi-trasporti-facchinaggio.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trattamenti.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trattamento-cotto.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tributh.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ts3-dns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "turdnagel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tutorat-tect.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "twocornertiming.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "u175.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ubis.company", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ubis.group", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "un-framed.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unlocktalent.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unmarkdocs.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "urltell.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vasel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vasel.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ver.ma", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vergelijksimonly.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vikalbino.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "virtit.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vivaldi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vivoseg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vnfs-team.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vokalsystem.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "volatimer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vulndetect.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vulnerabilities.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vvoip.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "w2n.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wains.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "walter.lc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "waukeect.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webdl.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "weddingalbumsdesign.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "weihnachten-schenken.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wexilapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "what-wood.servehttp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whimtrip.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whychoosebob.net.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wichitafoundationpros.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wirkaufendeinau.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wlwlwx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wow-screenshots.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ws-meca.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wsadek.ovh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "www-9822.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wyrimaps.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wzfou.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xbrl.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xiaxuejin.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--eckle6c0exa0b0modc7054g7h8ajw6f.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--familie-pppinghaus-l3b.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--feuerlscher-arten-4zb.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--mein-kchenhelfer-ozb.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--mensenges-o1a8c.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--mensengesss-t8a.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--mhsv04avtt1xi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xqk7.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xtom.wiki", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ybzhao.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yiyueread.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "youked.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yubico.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yubico.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yubico.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yubico.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yubikey.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yubikey.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yubikey.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yubikey.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yuki-nagato.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yukimochi.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yuqi.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zahnrechner-staging.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zhcexo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zipkey.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zonewatcher.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "100lat.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "11dzon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1c-power.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "1volcano.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "230beats.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "233ss.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "2948.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "34oztonic.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "3candy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "478933.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "4kprojektory.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "57wilkie.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "66205.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "73223.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "772244.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8522hk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8522ph.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8522tw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8522usa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "86499.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8649955.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8649966.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "8649977.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "88522am.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "919945.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "a3.pm", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "a8q.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aarvinproperties.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "abe-medical.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "abraxan.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "abristolgeek.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "absolutehaitian.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "accelerator.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "acem.org.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "addnine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adept.org.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adingenierie.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "admin-numerique.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adminwiki.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "adultbizz.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aethonan.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agracan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "agrichamber.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aignermunich.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aignermunich.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aignermunich.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "airrestoration.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "airsick.guide", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ajsb85.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "akkeylab.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aliim.gdn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alijammusic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "allaboutthekink.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "almagalla.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alp.od.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "altes-sportamt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "altoa.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alts.li", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "alvn.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "amerika-forum.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "andiscyber.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "angervillelorcher.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anime-rg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "antani.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "antennisti.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "antibioticshome.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anypool.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "anypool.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "appimlab.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "appxcrypto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "apratimsaha.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "aptitude9.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arifburhan.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arinde.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arkulagunak.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "arogov.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "art-auction.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "artaronquieres.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "artofmonitoring.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "asmik-armenie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "astral.org.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "atherosense.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "atlassignsandplaques.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avalon-rpg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avatardiffusion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avocatbeziau.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "avptp.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "axchap.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "axfr.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "axonholdingse.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b4ckbone.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "b4r7.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bacoux.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "badmintonbible.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "balticer.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bangumi.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bankvanbreda.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "banquevanbreda.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "basicattentiontoken.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "be-up-developpement.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "beanbot.party", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bedels.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "beelit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bei18.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bep.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "besole.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "betonbit.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bevelpix.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bgfoto.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bigjohn.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "billywig.stream", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "biloplysninger.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "binarization.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "biodots.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "biodots.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "biodots.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "biodots.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bithir.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bitten.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blockedyourcar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blockedyourcar.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blockedyourcar.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "blokino.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bluewavewebdesign.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bluiandaj.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bluop.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bogdancornianu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "boltn.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bonebunny.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "borja.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bots.cat", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brank.as", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "brunick.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bryancastillo.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "btth.live", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bug.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "bwe-seminare.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cafeimsueden.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "calltothepen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "camping-seilershof.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "candaceplayforth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "candex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "captivationscience.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cardwars.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "carepassport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "carrollservicecompany.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "casinoluck.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "casusgrillcaribbean.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "caterkids.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ccsource.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cellartracker.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "centricbeats.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "certchannel.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chatbot.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chikatomo-ryugaku.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chilli943.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "chollima.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cindey.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cipher.team", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cloudflare-dns.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "clubnoetig-ink2g.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cmf.qc.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cn8522.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "combron.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "comoimportar.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "comosecarabarriga.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "comoseduzir.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "concursuri.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "connaitre-les-astres.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "connecto-data.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "constructexpres.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "copinstant.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "copycaught.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "copycaught.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "copycaught.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "copycaught.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "copycaught.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cosmic-os.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "craftngo.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "crazy-coders.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cryptoya.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "crystalapp.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "cyberserver.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "d0xq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dafont.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dagmar2018.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "danielmartin.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "danstillman.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "das-forum24.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "datahoarder.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "davewut.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "daymprove.life", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dc-elektro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dc-elektro.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dc-elektro.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "deliciousmedia.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "derattizzazioni.milano.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "develerik.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "diesteppenreiter.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "digitalliteracy.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dinheirolucrar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dirba.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "disciplina.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "discordia.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "disinfestazione.torino.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "disinfestazioni.milano.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "disinfestazioni.udine.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dmd.lv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dochimera.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dockerbook.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dogpawstudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "domus-global.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "domus-global.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "doulasofgreaterkansascity.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "durand.tf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dutchdare.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "dymowski.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ebisi.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eco-wiki.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ecobin.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ecodesigns.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ecombustibil.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "economycarrentalscyprus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "educnum.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "efinity.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "electricgatemotorskemptonpark.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "electricgatemotorsroodepoort.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elefandt.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elevator.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elo.fyi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elonaspitze.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elrinconderovica.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elsagradocoran.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "elshou.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "emiliendevos.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "enjincoin.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "enjinwallet.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "enjinx.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "entradaweb.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "epos.az", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "equk.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "erinlin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ethergeist.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "eulenschmiede.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "europetravelservice.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "evilness.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "evolvetechnologies.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ewaipiotr.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ewtl.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "exceptionalbits.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "exocen.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "extintormadrid.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "facil.services", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "faraonplay7.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "faraonplay8.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "favirei.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "feelmom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "feuerwehr-offenbach-bieber.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fibretv.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fibretv.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "files.from-me.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "findmynudes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "findoon.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "firechip.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fit-mit-system.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flashcomp.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flatmail.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "floersheimer-openair.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "flowair24.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fluxi.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "foutrelis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "francoise-paviot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freecookies.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "freshmaza.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "friarsonbase.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fruend-hausgeraeteshop.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fruttini.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ftv.re", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "furikake.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "furry.zone", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "fursuitbutts.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gaaz.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gandc.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gaon.network", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "garyswine.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gaudere.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gcguild.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "georgeperez.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "getserum.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "getsmartaboutdrugs.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gfestival.fo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gicl.dk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "git.ac.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gitar.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "glutenfreiheit.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gomasy.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "govype.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gpm.ltd", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "granfort.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "granian.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "graniteind.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "greer.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "grunwaldzki.center", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gudangpangan.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guidepointsecurity.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "guidesetc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "gurucomi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hackerone.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hackmeimfamo.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hackworx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "haizum.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "halfhosting.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hanzcollection.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "happyheartsabode.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "harlor.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hartlieb.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "haustechnik-breu.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "haverstack.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heartlandbiomed.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heimdallr.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "heleendebruyne.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "herpes-no.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hflsdev.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hfox.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hg.gg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "holzstueckwerk.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "homeoesp.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hooplessinseattle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hoponmedia.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "hotelamgarnmarkt.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "houseofhouston.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.bg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "humblebee.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "i9multiequipamentos.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iahemobile.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iamhansen.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ibna.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "icoh.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "idolshop.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "if0.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iiit.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ijsblokjesvormen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ikigaiweb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iloilofit.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "imjo.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "incarna.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inflate-a-bubbles.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infor-allaitement.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "infos-generation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inkurz.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "inmatefinancial.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ins.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "intelly.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "iosjailbreakiphone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ipemcomodoro.com.ar", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "irasandi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ironbelly.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "israelbiblicalstudies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "it-academy.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ivusn.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jakdelatseo.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jaleo.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jameschorlton.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "japansm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jasminefields.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "javierburgos.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jeffcloninger.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jelleraaijmakers.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jeremywagner.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jhf.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jiacl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jianshu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jisai.net.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "johnno.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jooksms.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jugendhackt.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "just-vet-and-drive.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "justsome.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "justthinktwice.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "jwallet.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "karaface.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kastemperaturen.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kazanasolutions.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "keeprubyweird.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kelheor.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kemmerer-net.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kernelmode.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kevinhq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "khosla.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kiesuwcursus.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kikimilyatacado.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kine-duthil.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kmdev.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "koi-lexikon.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "koirala.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "koirala.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kokoiroworks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kolbeinsson.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kolonie-am-stadtpark.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "koodimasin.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "krehl.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ksero.wroclaw.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "kyobostory-events.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "laboitebio-logique.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lahipotesisgaia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lakelandbank.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lakeshowlife.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lebensraum-fitness-toenisvorst.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "legacy.bank", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "levelaccordingly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "liam-w.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lignemax.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "likere.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lineageos.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "localhost.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "logingate.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lojahunamarcenaria.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lok.space", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "longma.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lovemen.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "lungta.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "macros.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "magicvodi.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "manuscriptlink.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maranatha.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mariapietropola.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "markdain.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marketindex.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "marketing91.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "masdillah.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mathsource.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mathsweek.school.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "matt-brooks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "matthiasbeck.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "matway.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "maxkeller.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mcsrvstat.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mctools.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mdzservers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "meereskunst.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "megztosidejos.lt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "meine-finanzanalyse.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "melodiouscode.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "memes.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "midgawash.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mightymillionslottery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mikumaycry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "milanstephan.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mirepublic.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "misanci.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mizuho-trade.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mobile-holzofenpizza.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mobilelooper.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mohela.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "more-terrain.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "morhys.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mosshi.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moucloud.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "moyu.host", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mr-coffee.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "msopopop.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "multitec.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mumakil.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "murashun.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "my4thtelco.com.sg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mydreamshaadi.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myhollywoodnews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mylstrom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myrepublic.com.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myrepublic.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myrepublic.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myrepublicau.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myrepublicaus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myrepublicbroadband.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myrepublicfibre.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myrepublicnz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "mysectools.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "myunox.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "n-man.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "n7.education", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nasme.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nax.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nbgrooves.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nbhorsetraining.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ncic.gg", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ncsc.gov.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ndhlink.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nehrp.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neilshealthymeals.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nejlevnejsi-parapety.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "neonknight.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "netbox.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "netflixlife.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "netrewrite.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nevermore.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nextcasino.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nf4.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nibo.blog", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nicsezcheckfbi.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "niffler.software", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ninjio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nodecraft.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "noelclaremont.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "noleggio-bagni-chimici.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "noriel.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "noteskeeper.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "notonprem.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "noustique.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nrsweb.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nrvnastudios.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nstyleintl.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "numismed-seniorcare.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "nve-qatar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oaklands.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "occenterprises.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "occonnections.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "offenes-deutschland.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "offfbynight.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ojanaho.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "omegathermoproducts.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "onionplay.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "open-domotics.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "opengovpartnership.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "openruhr.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "optimize-jpg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "orioncokolada.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "osaka-onakura.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "oyosoft.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paardenhulp.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paceda.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "palmen-apotheke.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "panlex.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "panos.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "papierniczy.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pasteblin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paxerahealth.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "paykings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "penguindrum.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "perez-marrero.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "persephone.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pescadorcomunicacao.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "petdesign.pet", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "peterborgapps.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "petpower.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pfk.org.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pharynx.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "philipp-winkler.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "philslab.ninja", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "phligence.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pieland.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pilsoncontracting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "placeitsf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "plainbulktshirts.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "planecon.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "playkinder.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "plesse.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pnakosoft.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pnakosoft.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pneumonline.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "po.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "politiezoneriho.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ponere.dz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pop3.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pornorama.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "porpcr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "posalji.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "premieresloges.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "principalship.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "privy-staging.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "prodietix.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "prosperontheweb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ps-sale.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pscr.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pself.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "psicologasandrabernal.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "psychiq.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "puravida-estate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "pushers.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qi0.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "qto.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quanjinlong.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quantaloupe.tech", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "quantumcore.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ra.vc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rabbitfinance.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "raisecorp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ramezanloo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rapidhubs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rdmrotterdam.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reactdatepicker.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "redchat.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "redlinelap.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rekyou.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "releasetimes.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "renewed.technology", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "renewgsa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "reptilauksjonen.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "revolutionhive.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rollatorweb.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "romanmichel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "root-space.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "roromendut.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rossfrancis.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rubens.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rudewiki.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rummage4property.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "rxight.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "salamon-it.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sale.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "salrosadohimalaia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "samlamac.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "satyanarayana.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sbir.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scaffalature.roma.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "scholarnet.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sdl-corporatesite-staging.azurewebsites.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "secbone.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "secyourity.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "selitysvideot.fi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "seniorem.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sharky.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sigmalux.ltd", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "silverartcollector.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "simon-agozzino.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "simpleclassiclife.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sinon.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sitesuccessful.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sjatsh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skalarwelle.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "skyworldserver.ddns.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smaltimentorifiuti.firenze.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smokinghunks.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "smsbrana.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "snic.website", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "snoerendevelopment.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "soakgames.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "soaringtoglory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sobreporcentagem.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "socialfacecook.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sonic.studio", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "spar.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "splunk.zone", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sranje.rocks", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "srihash.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sso.to", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "starcoachservices.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "steamstat.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "stirblaut.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "strangescout.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "streetmarket.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "studiebegeleiding-haegeman.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "studiohelder.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "suraya.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sushiwereld.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "swiftcrypto.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "sylvaincombe.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "synccentre.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "syobon.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "syscoon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "system-online.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "systemzeit.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tabletd.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tachyonapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tacostea.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tba.bm", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tchannels.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tenma.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teplofom.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "teplomash24.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thebusinessofgoodfilm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thesimplifiers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thestral.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thestralbot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "think-asia.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thirdbearsolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thisishugo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thomas-sammut.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "thycotic.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "time.gov", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "timjk.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "titansized.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tober-cpag.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "todokete.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "toreni.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "torkware.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tosostav.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tourify.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "towsonroofers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trad-n-vo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trading-analytics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tratamentoparacelulite.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tratamentoparacelulite.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "trianon.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tributh.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tributh.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tributh.gq", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "tributh.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "truvisory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "u5.re", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uhasseltctf.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "un.fo", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unitedstreamers.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "unixfox.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "upupming.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uradisam.rs", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "usagexchange.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "usninosnikrcni.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "usnti.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uvenuse.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "uvolejniku.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vaclavambroz.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vaibhavchatarkar.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "valcano-krd.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "valcano.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vb-oa.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vb.media", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ventriloservers.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "venturebanners.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "venturedisplay.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vforvendetta.science", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vicicode.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "victoreriksson.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "victoreriksson.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "victoreriksson.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "victoreriksson.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vikapaula.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "villehardouin.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "visiondigitalsog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "visitcambridgeshirefens.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vitzro.kr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vkulagin.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vlndc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "voidark.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "volcano-kazan.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "volcano-spb.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "volcano-vts.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "volcano24.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "volcanov.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vosselaer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vvw-8522.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "vysvetluju.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wanderzoom.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wangyubao.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "watchpci.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "waxlrs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wbut.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "web-art.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webeast.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webhooks.stream", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webline.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webmixseo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "webwinkelexploitatie.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "weednews.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "weekendinitaly.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "weitergedacht.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wener.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wepay.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "westcoastaggregate.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wft-portfolio.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whateveraspidercan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "whatismycountry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "workinginsync.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wpcanban.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "wvv-8522.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "www-86499.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xcompany.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xerownia.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xiaomionline24.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xiaoyy.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xif.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn----7sbfl2alf8a.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--24-6kch4bfqee.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--24-glcia8dc.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--80adb4aeode.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--e1aoahhqgn.xn--p1ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--myrepubic-wub.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xn--myrepublc-x5a.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xnxx.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xps2pdf.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xserownia.com.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xserownia.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xserownia.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xtrainsights.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xvideos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "xywing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yanbao.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "ygcdyf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yiffy.tips", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yiffy.zone", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "youc.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yourlovesong.com.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "yuzei.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zahnarzt-duempten.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zaptan.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zaptan.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zaptan.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zaptan.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zhoushuo.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zmala.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+ { "name": "zook.systems", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
// END OF 1-YEAR BULK HSTS ENTRIES
// Only eTLD+1 domains can be submitted automatically to hstspreload.org,
@@ -46046,6 +49152,9 @@
{ "name": "skypeassets.com", "policy": "custom", "mode": "force-https", "include_subdomains": true },
{ "name": "teams.microsoft.com", "policy": "custom", "mode": "force-https", "include_subdomains": true },
{ "name": "trouter.io", "policy": "custom", "mode": "force-https", "include_subdomains": true },
+ // IP Address
+ { "name": "1.1.1.1", "policy": "custom", "mode": "force-https", "include_subdomains": false },
+ { "name": "1.0.0.1", "policy": "custom", "mode": "force-https", "include_subdomains": false },
// No subdomains
{ "name": "wordpress.com", "policy": "custom", "mode": "force-https", "include_subdomains": false },
{ "name": "www.wordpress.com", "policy": "custom", "mode": "force-https", "include_subdomains": false },
@@ -46062,6 +49171,8 @@
// IPv6
{ "name": "ipv6only.network", "policy": "custom", "mode": "force-https", "include_subdomains": true },
{ "name": "trinity.fr.eu.org", "policy": "custom", "mode": "force-https", "include_subdomains": true },
+ { "name": "mysa.is", "policy": "custom", "mode": "force-https", "include_subdomains": true },
+ { "name": "vensl.org", "policy": "custom", "mode": "force-https", "include_subdomains": true },
// Expect-CT/Expect-Staple
{
"name": "crt.sh", "policy": "custom",
@@ -46236,6 +49347,7 @@
{ "name": "everytrycounts.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
{ "name": "intel.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
{ "name": "opioids.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+ { "name": "pppo.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
{ "name": "ffb.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
{ "name": "safecar.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
{ "name": "famep.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
@@ -46256,6 +49368,7 @@
{ "name": "securitytestfan.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
{ "name": "supportfan.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
{ "name": "xd.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
+ { "name": "bmoattachments.org", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true },
// END OF ETLD-OWNER REQUESTED ENTRIES
// To avoid trailing comma changes from showing up in diffs, we place a
diff --git a/chromium/net/http/transport_security_state_unittest.cc b/chromium/net/http/transport_security_state_unittest.cc
index 67aebbb48d4..efb902c938a 100644
--- a/chromium/net/http/transport_security_state_unittest.cc
+++ b/chromium/net/http/transport_security_state_unittest.cc
@@ -35,7 +35,7 @@
#include "net/cert/x509_certificate.h"
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
-#include "net/net_features.h"
+#include "net/net_buildflags.h"
#include "net/ssl/ssl_info.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
@@ -218,8 +218,10 @@ class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter {
class MockRequireCTDelegate : public TransportSecurityState::RequireCTDelegate {
public:
- MOCK_METHOD1(IsCTRequiredForHost,
- CTRequirementLevel(const std::string& hostname));
+ MOCK_METHOD3(IsCTRequiredForHost,
+ CTRequirementLevel(const std::string& hostname,
+ const X509Certificate* chain,
+ const HashValueVector& hashes));
};
void CompareCertificateChainWithList(
@@ -397,6 +399,23 @@ void CheckExpectStapleReport(TransportSecurityState* state,
cert_status));
}
+bool operator==(const TransportSecurityState::STSState& lhs,
+ const TransportSecurityState::STSState& rhs) {
+ return lhs.last_observed == rhs.last_observed && lhs.expiry == rhs.expiry &&
+ lhs.upgrade_mode == rhs.upgrade_mode &&
+ lhs.include_subdomains == rhs.include_subdomains &&
+ lhs.domain == rhs.domain;
+}
+
+bool operator==(const TransportSecurityState::PKPState& lhs,
+ const TransportSecurityState::PKPState& rhs) {
+ return lhs.last_observed == rhs.last_observed && lhs.expiry == rhs.expiry &&
+ lhs.spki_hashes == rhs.spki_hashes &&
+ lhs.bad_spki_hashes == rhs.bad_spki_hashes &&
+ lhs.include_subdomains == rhs.include_subdomains &&
+ lhs.domain == rhs.domain && lhs.report_uri == rhs.report_uri;
+}
+
} // namespace
class TransportSecurityStateTest : public testing::Test {
@@ -1790,10 +1809,7 @@ TEST_F(TransportSecurityStateTest, DecodePreloadedMultiplePrefix) {
EXPECT_FALSE(sts_state.include_subdomains);
EXPECT_EQ(TransportSecurityState::STSState::MODE_FORCE_HTTPS,
sts_state.upgrade_mode);
- EXPECT_FALSE(pkp_state.include_subdomains);
- EXPECT_EQ(GURL(), pkp_state.report_uri);
- EXPECT_EQ(0U, pkp_state.spki_hashes.size());
- EXPECT_EQ(0U, pkp_state.bad_spki_hashes.size());
+ EXPECT_TRUE(pkp_state == TransportSecurityState::PKPState());
EXPECT_FALSE(GetExpectCTState(&state, "hsts.example.com", &ct_state));
EXPECT_FALSE(GetExpectStapleState(&state, "hsts.example.com", &staple_state));
@@ -1803,9 +1819,7 @@ TEST_F(TransportSecurityStateTest, DecodePreloadedMultiplePrefix) {
staple_state = TransportSecurityState::ExpectStapleState();
EXPECT_TRUE(
GetStaticDomainState(&state, "hpkp.example.com", &sts_state, &pkp_state));
- EXPECT_FALSE(sts_state.include_subdomains);
- EXPECT_EQ(TransportSecurityState::STSState::MODE_DEFAULT,
- sts_state.upgrade_mode);
+ EXPECT_TRUE(sts_state == TransportSecurityState::STSState());
EXPECT_TRUE(pkp_state.include_subdomains);
EXPECT_EQ(GURL("https://report.example.com/hpkp-upload"),
pkp_state.report_uri);
@@ -1821,13 +1835,8 @@ TEST_F(TransportSecurityStateTest, DecodePreloadedMultiplePrefix) {
staple_state = TransportSecurityState::ExpectStapleState();
EXPECT_TRUE(GetStaticDomainState(&state, "expect-ct.example.com", &sts_state,
&pkp_state));
- EXPECT_FALSE(sts_state.include_subdomains);
- EXPECT_EQ(TransportSecurityState::STSState::MODE_DEFAULT,
- sts_state.upgrade_mode);
- EXPECT_FALSE(pkp_state.include_subdomains);
- EXPECT_EQ(GURL(), pkp_state.report_uri);
- EXPECT_EQ(0U, pkp_state.spki_hashes.size());
- EXPECT_EQ(0U, pkp_state.bad_spki_hashes.size());
+ EXPECT_TRUE(sts_state == TransportSecurityState::STSState());
+ EXPECT_TRUE(pkp_state == TransportSecurityState::PKPState());
EXPECT_TRUE(GetExpectCTState(&state, "expect-ct.example.com", &ct_state));
EXPECT_EQ(GURL("https://report.example.com/ct-upload"), ct_state.report_uri);
EXPECT_FALSE(
@@ -1839,13 +1848,8 @@ TEST_F(TransportSecurityStateTest, DecodePreloadedMultiplePrefix) {
staple_state = TransportSecurityState::ExpectStapleState();
EXPECT_TRUE(GetStaticDomainState(&state, "expect-staple.example.com",
&sts_state, &pkp_state));
- EXPECT_FALSE(sts_state.include_subdomains);
- EXPECT_EQ(TransportSecurityState::STSState::MODE_DEFAULT,
- sts_state.upgrade_mode);
- EXPECT_FALSE(pkp_state.include_subdomains);
- EXPECT_EQ(GURL(), pkp_state.report_uri);
- EXPECT_EQ(0U, pkp_state.spki_hashes.size());
- EXPECT_EQ(0U, pkp_state.bad_spki_hashes.size());
+ EXPECT_TRUE(sts_state == TransportSecurityState::STSState());
+ EXPECT_TRUE(pkp_state == TransportSecurityState::PKPState());
EXPECT_FALSE(
GetExpectCTState(&state, "expect-staple.example.com", &ct_state));
EXPECT_TRUE(
@@ -1903,10 +1907,7 @@ TEST_F(TransportSecurityStateTest, DecodePreloadedMultipleMix) {
EXPECT_TRUE(sts_state.include_subdomains);
EXPECT_EQ(TransportSecurityState::STSState::MODE_FORCE_HTTPS,
sts_state.upgrade_mode);
- EXPECT_FALSE(pkp_state.include_subdomains);
- EXPECT_EQ(GURL(), pkp_state.report_uri);
- EXPECT_EQ(0U, pkp_state.spki_hashes.size());
- EXPECT_EQ(0U, pkp_state.bad_spki_hashes.size());
+ EXPECT_TRUE(pkp_state == TransportSecurityState::PKPState());
EXPECT_FALSE(GetExpectCTState(&state, "example.com", &ct_state));
EXPECT_EQ(GURL(), ct_state.report_uri);
EXPECT_TRUE(GetExpectStapleState(&state, "example.com", &staple_state));
@@ -1920,9 +1921,7 @@ TEST_F(TransportSecurityStateTest, DecodePreloadedMultipleMix) {
staple_state = TransportSecurityState::ExpectStapleState();
EXPECT_TRUE(
GetStaticDomainState(&state, "hpkp.example.com", &sts_state, &pkp_state));
- EXPECT_FALSE(sts_state.include_subdomains);
- EXPECT_EQ(TransportSecurityState::STSState::MODE_DEFAULT,
- sts_state.upgrade_mode);
+ EXPECT_TRUE(sts_state == TransportSecurityState::STSState());
EXPECT_TRUE(pkp_state.include_subdomains);
EXPECT_EQ(GURL("https://report.example.com/hpkp-upload"),
pkp_state.report_uri);
@@ -1944,10 +1943,7 @@ TEST_F(TransportSecurityStateTest, DecodePreloadedMultipleMix) {
EXPECT_FALSE(sts_state.include_subdomains);
EXPECT_EQ(TransportSecurityState::STSState::MODE_FORCE_HTTPS,
sts_state.upgrade_mode);
- EXPECT_FALSE(pkp_state.include_subdomains);
- EXPECT_EQ(GURL(), pkp_state.report_uri);
- EXPECT_EQ(0U, pkp_state.spki_hashes.size());
- EXPECT_EQ(0U, pkp_state.bad_spki_hashes.size());
+ EXPECT_TRUE(pkp_state == TransportSecurityState::PKPState());
EXPECT_TRUE(GetExpectCTState(&state, "example.org", &ct_state));
EXPECT_EQ(GURL("https://report.example.org/ct-upload"), ct_state.report_uri);
EXPECT_FALSE(GetExpectStapleState(&state, "example.org", &staple_state));
@@ -1960,9 +1956,7 @@ TEST_F(TransportSecurityStateTest, DecodePreloadedMultipleMix) {
staple_state = TransportSecurityState::ExpectStapleState();
EXPECT_TRUE(
GetStaticDomainState(&state, "badssl.com", &sts_state, &pkp_state));
- EXPECT_TRUE(sts_state.include_subdomains);
- EXPECT_EQ(TransportSecurityState::STSState::MODE_DEFAULT,
- sts_state.upgrade_mode);
+ EXPECT_TRUE(sts_state == TransportSecurityState::STSState());
EXPECT_TRUE(pkp_state.include_subdomains);
EXPECT_EQ(GURL("https://report.example.com/hpkp-upload"),
pkp_state.report_uri);
@@ -2010,7 +2004,7 @@ TEST_F(TransportSecurityStateTest, DecodePreloadedMultipleMix) {
EXPECT_TRUE(sts_state.include_subdomains);
EXPECT_EQ(TransportSecurityState::STSState::MODE_FORCE_HTTPS,
sts_state.upgrade_mode);
- EXPECT_FALSE(pkp_state.include_subdomains);
+ EXPECT_TRUE(pkp_state == TransportSecurityState::PKPState());
EXPECT_FALSE(GetExpectCTState(&state, "simple-entry.example.com", &ct_state));
EXPECT_FALSE(
GetExpectStapleState(&state, "simple-entry.example.com", &staple_state));
@@ -2224,6 +2218,9 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
hashes.push_back(
HashValue(X509Certificate::CalculateFingerprint256(cert->cert_buffer())));
+ // If CT is required, then the requirements are not met if the CT policy
+ // wasn't met, but are met if the policy was met or the build was out of
+ // date.
{
TransportSecurityState state;
const TransportSecurityState::CTRequirementsStatus original_status =
@@ -2234,7 +2231,7 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS);
MockRequireCTDelegate always_require_delegate;
- EXPECT_CALL(always_require_delegate, IsCTRequiredForHost(_))
+ EXPECT_CALL(always_require_delegate, IsCTRequiredForHost(_, _, _))
.WillRepeatedly(Return(CTRequirementLevel::REQUIRED));
state.SetRequireCTDelegate(&always_require_delegate);
EXPECT_EQ(
@@ -2276,6 +2273,8 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
}
+ // If CT is not required, then regardless of the CT state for the host,
+ // it should indicate CT is not required.
{
TransportSecurityState state;
const TransportSecurityState::CTRequirementsStatus original_status =
@@ -2286,7 +2285,7 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS);
MockRequireCTDelegate never_require_delegate;
- EXPECT_CALL(never_require_delegate, IsCTRequiredForHost(_))
+ EXPECT_CALL(never_require_delegate, IsCTRequiredForHost(_, _, _))
.WillRepeatedly(Return(CTRequirementLevel::NOT_REQUIRED));
state.SetRequireCTDelegate(&never_require_delegate);
EXPECT_EQ(
@@ -2314,6 +2313,8 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
}
+ // If the Delegate is in the default state, then it should return the same
+ // result as if there was no delegate in the first place.
{
TransportSecurityState state;
const TransportSecurityState::CTRequirementsStatus original_status =
@@ -2324,7 +2325,7 @@ TEST_F(TransportSecurityStateTest, RequireCTConsultsDelegate) {
ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS);
MockRequireCTDelegate default_require_ct_delegate;
- EXPECT_CALL(default_require_ct_delegate, IsCTRequiredForHost(_))
+ EXPECT_CALL(default_require_ct_delegate, IsCTRequiredForHost(_, _, _))
.WillRepeatedly(Return(CTRequirementLevel::DEFAULT));
state.SetRequireCTDelegate(&default_require_ct_delegate);
EXPECT_EQ(
@@ -2500,7 +2501,7 @@ TEST_F(TransportSecurityStateTest, RequireCTViaFieldTrial) {
kFeatureName, base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get());
scoped_feature_list.InitWithFeatureList(std::move(feature_list));
- // It should fail if it doesn't comply with policy...
+ // It should fail if it doesn't comply with policy.
EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
@@ -2508,7 +2509,7 @@ TEST_F(TransportSecurityStateTest, RequireCTViaFieldTrial) {
TransportSecurityState::DISABLE_EXPECT_CT_REPORTS,
ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
- // ... and succeed if it does comply with policy ...
+ // It should succeed if it does comply with policy.
EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_MET,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
@@ -2516,13 +2517,21 @@ TEST_F(TransportSecurityStateTest, RequireCTViaFieldTrial) {
TransportSecurityState::DISABLE_EXPECT_CT_REPORTS,
ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
- // ... or if the build is outdated.
+ // It should succeed if the build is outdated.
EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_MET,
state.CheckCTRequirements(
HostPortPair("www.example.com", 443), true, hashes, cert.get(),
cert.get(), SignedCertificateTimestampAndStatusList(),
TransportSecurityState::DISABLE_EXPECT_CT_REPORTS,
ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY));
+
+ // It should succeed if it was a locally-trusted CA.
+ EXPECT_EQ(TransportSecurityState::CT_NOT_REQUIRED,
+ state.CheckCTRequirements(
+ HostPortPair("www.example.com", 443), false, hashes, cert.get(),
+ cert.get(), SignedCertificateTimestampAndStatusList(),
+ TransportSecurityState::DISABLE_EXPECT_CT_REPORTS,
+ ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY));
}
// Tests that Certificate Transparency is required for all of the Symantec
@@ -3100,7 +3109,7 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCTAndDelegate) {
// A connection to an Expect-CT host, which also requires CT by the delegate,
// should be closed and reported.
MockRequireCTDelegate always_require_delegate;
- EXPECT_CALL(always_require_delegate, IsCTRequiredForHost(_))
+ EXPECT_CALL(always_require_delegate, IsCTRequiredForHost(_, _, _))
.WillRepeatedly(Return(CTRequirementLevel::REQUIRED));
state.SetRequireCTDelegate(&always_require_delegate);
EXPECT_EQ(TransportSecurityState::CT_REQUIREMENTS_NOT_MET,
@@ -3121,6 +3130,62 @@ TEST_F(TransportSecurityStateTest, CheckCTRequirementsWithExpectCTAndDelegate) {
EXPECT_EQ(sct_list[0].sct, reporter.signed_certificate_timestamps()[0].sct);
}
+// Tests that for a host that explicitly disabled CT by delegate and is also
+// Expect-CT-enabled, CheckCTRequirements() sends reports.
+TEST_F(TransportSecurityStateTest,
+ CheckCTRequirementsWithExpectCTAndDelegateDisables) {
+ using ::testing::_;
+ using ::testing::Return;
+ using CTRequirementLevel =
+ TransportSecurityState::RequireCTDelegate::CTRequirementLevel;
+
+ const base::Time current_time(base::Time::Now());
+ const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
+ scoped_refptr<X509Certificate> cert1 =
+ ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
+ ASSERT_TRUE(cert1);
+ scoped_refptr<X509Certificate> cert2 =
+ ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
+ ASSERT_TRUE(cert2);
+ SignedCertificateTimestampAndStatusList sct_list;
+ MakeTestSCTAndStatus(ct::SignedCertificateTimestamp::SCT_EMBEDDED, "test_log",
+ std::string(), std::string(), base::Time::Now(),
+ ct::SCT_STATUS_INVALID_SIGNATURE, &sct_list);
+
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(
+ TransportSecurityState::kDynamicExpectCTFeature);
+
+ TransportSecurityState state;
+ MockExpectCTReporter reporter;
+ state.SetExpectCTReporter(&reporter);
+ state.AddExpectCT("example.test", expiry, false /* enforce */,
+ GURL("https://example-report.test"));
+
+ // A connection to an Expect-CT host, which is exempted from the CT
+ // requirements by the delegate, should be reported but not closed.
+ MockRequireCTDelegate never_require_delegate;
+ EXPECT_CALL(never_require_delegate, IsCTRequiredForHost(_, _, _))
+ .WillRepeatedly(Return(CTRequirementLevel::NOT_REQUIRED));
+ state.SetRequireCTDelegate(&never_require_delegate);
+ EXPECT_EQ(TransportSecurityState::CT_NOT_REQUIRED,
+ state.CheckCTRequirements(
+ HostPortPair("example.test", 443), true, HashValueVector(),
+ cert1.get(), cert2.get(), sct_list,
+ TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+ ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+ EXPECT_EQ(1u, reporter.num_failures());
+ EXPECT_EQ("example.test", reporter.host_port_pair().host());
+ EXPECT_EQ(443, reporter.host_port_pair().port());
+ EXPECT_EQ(expiry, reporter.expiration());
+ EXPECT_EQ(cert1.get(), reporter.validated_certificate_chain());
+ EXPECT_EQ(cert2.get(), reporter.served_certificate_chain());
+ EXPECT_EQ(sct_list.size(), reporter.signed_certificate_timestamps().size());
+ EXPECT_EQ(sct_list[0].status,
+ reporter.signed_certificate_timestamps()[0].status);
+ EXPECT_EQ(sct_list[0].sct, reporter.signed_certificate_timestamps()[0].sct);
+}
+
// Tests that the dynamic Expect-CT UMA histogram is recorded correctly.
TEST_F(TransportSecurityStateTest, DynamicExpectCTUMA) {
const char kHistogramName[] = "Net.ExpectCTHeader.ParseSuccess";
@@ -3270,6 +3335,7 @@ TEST_F(TransportSecurityStateStaticTest, IsPreloaded) {
TEST_F(TransportSecurityStateStaticTest, PreloadedDomainSet) {
TransportSecurityState state;
+ EnableStaticPins(&state);
TransportSecurityState::STSState sts_state;
TransportSecurityState::PKPState pkp_state;
diff --git a/chromium/net/http2/decoder/payload_decoders/payload_decoder_base_test_util.h b/chromium/net/http2/decoder/payload_decoders/payload_decoder_base_test_util.h
index 67033fa779f..fced486e411 100644
--- a/chromium/net/http2/decoder/payload_decoders/payload_decoder_base_test_util.h
+++ b/chromium/net/http2/decoder/payload_decoders/payload_decoder_base_test_util.h
@@ -61,11 +61,6 @@ class PayloadDecoderBaseTest : public RandomDecoderTest {
frame_header_is_set_ = true;
}
- const Http2FrameHeader& frame_header() const {
- CHECK(frame_header_is_set_);
- return frame_header_;
- }
-
FrameDecoderState* mutable_state() { return &frame_decoder_state_; }
// Randomize the payload decoder, sets the payload decoder's frame_header_,
diff --git a/chromium/net/http2/hpack/decoder/hpack_decoder_string_buffer.cc b/chromium/net/http2/hpack/decoder/hpack_decoder_string_buffer.cc
index 563b7bdac06..4be593af018 100644
--- a/chromium/net/http2/hpack/decoder/hpack_decoder_string_buffer.cc
+++ b/chromium/net/http2/hpack/decoder/hpack_decoder_string_buffer.cc
@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "base/trace_event/memory_usage_estimator.h"
+#include "net/http2/platform/api/http2_string.h"
#include "net/http2/tools/http2_bug_tracker.h"
namespace net {
@@ -166,7 +167,7 @@ void HpackDecoderStringBuffer::BufferStringIfUnbuffered() {
DVLOG(3) << "HpackDecoderStringBuffer::BufferStringIfUnbuffered state="
<< state_ << ", backing=" << backing_;
if (state_ != State::RESET && backing_ == Backing::UNBUFFERED) {
- DVLOG(2) << "HpackDecoderStringBuffer buffering string of length "
+ DVLOG(2) << "HpackDecoderStringBuffer buffering Http2String of length "
<< value_.size();
buffer_.assign(value_.data(), value_.size());
if (state_ == State::COMPLETE) {
@@ -201,7 +202,7 @@ Http2String HpackDecoderStringBuffer::ReleaseString() {
if (backing_ == Backing::BUFFERED) {
return std::move(buffer_);
} else {
- return value_.as_string();
+ return Http2String(value_);
}
}
return "";
diff --git a/chromium/net/http2/hpack/decoder/hpack_decoder_test.cc b/chromium/net/http2/hpack/decoder/hpack_decoder_test.cc
index 7a89e82106e..3a34f804491 100644
--- a/chromium/net/http2/hpack/decoder/hpack_decoder_test.cc
+++ b/chromium/net/http2/hpack/decoder/hpack_decoder_test.cc
@@ -121,7 +121,7 @@ class HpackDecoderTest : public ::testing::TestWithParam<bool>,
// error_message may be used in a GOAWAY frame as the Opaque Data.
void OnHeaderErrorDetected(Http2StringPiece error_message) override {
ASSERT_TRUE(saw_start_);
- error_messages_.push_back(error_message.as_string());
+ error_messages_.push_back(Http2String(error_message));
// No further callbacks should be made at this point, so replace 'this' as
// the listener with mock_listener_, which is a strict mock, so will
// generate an error for any calls.
diff --git a/chromium/net/http2/http2_constants.h b/chromium/net/http2/http2_constants.h
index a6149f5db6b..05c85026975 100644
--- a/chromium/net/http2/http2_constants.h
+++ b/chromium/net/http2/http2_constants.h
@@ -53,10 +53,10 @@ inline bool IsSupportedHttp2FrameType(Http2FrameType v) {
return IsSupportedHttp2FrameType(static_cast<uint32_t>(v));
}
-// The return type is 'string' so that they can generate a unique string for
-// each unsupported value. Since these are just used for debugging/error
-// messages, that isn't a cost to we need to worry about.
-// The same applies to the functions later in this file.
+// The return type is 'Http2String' so that they can generate a unique string
+// for each unsupported value. Since these are just used for debugging/error
+// messages, that isn't a cost to we need to worry about. The same applies to
+// the functions later in this file.
HTTP2_EXPORT_PRIVATE Http2String Http2FrameTypeToString(Http2FrameType v);
HTTP2_EXPORT_PRIVATE Http2String Http2FrameTypeToString(uint8_t v);
HTTP2_EXPORT_PRIVATE inline std::ostream& operator<<(std::ostream& out,
diff --git a/chromium/net/http2/http2_constants_test_util.cc b/chromium/net/http2/http2_constants_test_util.cc
index 1cad515e84d..c67cb0f894a 100644
--- a/chromium/net/http2/http2_constants_test_util.cc
+++ b/chromium/net/http2/http2_constants_test_util.cc
@@ -7,63 +7,6 @@
namespace net {
namespace test {
-std::vector<Http2FrameType> AllHttp2FrameTypes() {
- // clang-format off
- return {
- Http2FrameType::DATA,
- Http2FrameType::HEADERS,
- Http2FrameType::PRIORITY,
- Http2FrameType::RST_STREAM,
- Http2FrameType::SETTINGS,
- Http2FrameType::PUSH_PROMISE,
- Http2FrameType::PING,
- Http2FrameType::GOAWAY,
- Http2FrameType::WINDOW_UPDATE,
- Http2FrameType::CONTINUATION,
- Http2FrameType::ALTSVC,
- };
- // clang-format on
-}
-
-std::vector<Http2FrameFlag> AllHttp2FrameFlagsForFrameType(
- Http2FrameType type) {
- // clang-format off
- switch (type) {
- case Http2FrameType::DATA:
- return {
- Http2FrameFlag::END_STREAM,
- Http2FrameFlag::PADDED,
- };
- case Http2FrameType::HEADERS:
- return {
- Http2FrameFlag::END_STREAM,
- Http2FrameFlag::END_HEADERS,
- Http2FrameFlag::PADDED,
- Http2FrameFlag::PRIORITY,
- };
- case Http2FrameType::SETTINGS:
- return {
- Http2FrameFlag::ACK,
- };
- case Http2FrameType::PUSH_PROMISE:
- return {
- Http2FrameFlag::END_HEADERS,
- Http2FrameFlag::PADDED,
- };
- case Http2FrameType::PING:
- return {
- Http2FrameFlag::ACK,
- };
- case Http2FrameType::CONTINUATION:
- return {
- Http2FrameFlag::END_HEADERS,
- };
- default:
- return std::vector<Http2FrameFlag>{};
- }
- // clang-format on
-}
-
std::vector<Http2ErrorCode> AllHttp2ErrorCodes() {
// clang-format off
return {
diff --git a/chromium/net/http2/http2_constants_test_util.h b/chromium/net/http2/http2_constants_test_util.h
index 6d20cec9d83..bfb7cf55831 100644
--- a/chromium/net/http2/http2_constants_test_util.h
+++ b/chromium/net/http2/http2_constants_test_util.h
@@ -12,13 +12,6 @@
namespace net {
namespace test {
-// Returns a vector of all supported frame types.
-std::vector<Http2FrameType> AllHttp2FrameTypes();
-
-// Returns a vector of all supported frame flags for the specified
-// frame type. Empty if the type is unknown.
-std::vector<Http2FrameFlag> AllHttp2FrameFlagsForFrameType(Http2FrameType type);
-
// Returns a vector of all supported RST_STREAM and GOAWAY error codes.
std::vector<Http2ErrorCode> AllHttp2ErrorCodes();
diff --git a/chromium/net/log/file_net_log_observer.cc b/chromium/net/log/file_net_log_observer.cc
index 57787866e0a..5001d4b5c64 100644
--- a/chromium/net/log/file_net_log_observer.cc
+++ b/chromium/net/log/file_net_log_observer.cc
@@ -11,6 +11,7 @@
#include "base/bind.h"
#include "base/containers/queue.h"
+#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
@@ -41,31 +42,34 @@ scoped_refptr<base::SequencedTaskRunner> CreateFileTaskRunner() {
base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
}
-// Opens |path| in write mode. Returns the file handle on success, or nullptr on
-// failure.
-base::ScopedFILE OpenFileForWrite(const base::FilePath& path) {
- base::ScopedFILE result(base::OpenFile(path, "wb"));
- LOG_IF(ERROR, !result) << "Failed opening: " << path.value();
+// Opens |path| in write mode.
+base::File OpenFileForWrite(const base::FilePath& path) {
+ base::File result(path,
+ base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
+ LOG_IF(ERROR, !result.IsValid()) << "Failed opening: " << path.value();
return result;
}
-// Helper that writes data to a file. The |file| handle may optionally be null,
+// Helper that writes data to a file. |file->IsValid()| may be false,
// in which case nothing will be written. Returns the number of bytes
// successfully written (may be less than input data in case of errors).
-size_t WriteToFile(FILE* file,
+size_t WriteToFile(base::File* file,
base::StringPiece data1,
base::StringPiece data2 = base::StringPiece(),
base::StringPiece data3 = base::StringPiece()) {
size_t bytes_written = 0;
- if (file) {
+ if (file->IsValid()) {
// Append each of data1, data2 and data3.
if (!data1.empty())
- bytes_written += fwrite(data1.data(), 1, data1.size(), file);
+ bytes_written +=
+ std::max(0, file->WriteAtCurrentPos(data1.data(), data1.size()));
if (!data2.empty())
- bytes_written += fwrite(data2.data(), 1, data2.size(), file);
+ bytes_written +=
+ std::max(0, file->WriteAtCurrentPos(data2.data(), data2.size()));
if (!data3.empty())
- bytes_written += fwrite(data3.data(), 1, data3.size(), file);
+ bytes_written +=
+ std::max(0, file->WriteAtCurrentPos(data3.data(), data3.size()));
}
return bytes_written;
@@ -74,7 +78,7 @@ size_t WriteToFile(FILE* file,
// Copies all of the data at |source_path| and appends it to |destination_file|,
// then deletes |source_path|.
void AppendToFileThenDelete(const base::FilePath& source_path,
- FILE* destination_file,
+ base::File* destination_file,
char* read_buffer,
size_t read_buffer_size) {
base::ScopedFILE source_file(base::OpenFile(source_path, "rb"));
@@ -247,16 +251,16 @@ class FileNetLogObserver::FileWriter {
// Writes |constants_value| to a file.
static void WriteConstantsToFile(std::unique_ptr<base::Value> constants_value,
- FILE* file);
+ base::File* file);
// Writes |polled_data| to a file.
static void WritePolledDataToFile(std::unique_ptr<base::Value> polled_data,
- FILE* file);
+ base::File* file);
// If any events were written (wrote_event_bytes_), rewinds |file| by 2 bytes
// in order to overwrite the trailing ",\n" that was written by the last event
// line.
- void RewindIfWroteEventBytes(FILE* file) const;
+ void RewindIfWroteEventBytes(base::File* file) const;
// Concatenates all the log files to assemble the final
// |final_log_file_|. This single "stitched" file is what other
@@ -264,20 +268,19 @@ class FileNetLogObserver::FileWriter {
void StitchFinalLogFile();
// Creates the .inprogress directory used by bounded mode.
- void CreateInprogressDirectory() const;
+ void CreateInprogressDirectory();
// The path (and associated file handle) where the final netlog is written. In
// bounded mode this is mostly written to once logging is stopped, whereas in
// unbounded mode events will be directly written to it.
const base::FilePath final_log_path_;
- base::ScopedFILE final_log_file_;
-
- // Holds the file handle for the numbered events file where data is currently
- // being written to. The file path of this file is
- // GetEventFilePath(current_event_file_number_). The
- // file handle may be null if an error previously occurred opening the file,
- // or logging has been stopped.
- base::ScopedFILE current_event_file_;
+ base::File final_log_file_;
+
+ // Holds the numbered events file where data is currently being written to.
+ // The file path of this file is GetEventFilePath(current_event_file_number_).
+ // The file may be !IsValid() if an error previously occurred opening the
+ // file, or logging has been stopped.
+ base::File current_event_file_;
size_t current_event_file_size_;
// Indicates the total number of netlog event files allowed.
@@ -488,10 +491,10 @@ void FileNetLogObserver::FileWriter::Initialize(
if (IsBounded()) {
CreateInprogressDirectory();
- base::ScopedFILE constants_file = OpenFileForWrite(GetConstantsFilePath());
- WriteConstantsToFile(std::move(constants_value), constants_file.get());
+ base::File constants_file = OpenFileForWrite(GetConstantsFilePath());
+ WriteConstantsToFile(std::move(constants_value), &constants_file);
} else {
- WriteConstantsToFile(std::move(constants_value), final_log_file_.get());
+ WriteConstantsToFile(std::move(constants_value), &final_log_file_);
}
}
@@ -501,11 +504,11 @@ void FileNetLogObserver::FileWriter::Stop(
// Write out the polled data.
if (IsBounded()) {
- base::ScopedFILE closing_file = OpenFileForWrite(GetClosingFilePath());
- WritePolledDataToFile(std::move(polled_data), closing_file.get());
+ base::File closing_file = OpenFileForWrite(GetClosingFilePath());
+ WritePolledDataToFile(std::move(polled_data), &closing_file);
} else {
- RewindIfWroteEventBytes(final_log_file_.get());
- WritePolledDataToFile(std::move(polled_data), final_log_file_.get());
+ RewindIfWroteEventBytes(&final_log_file_);
+ WritePolledDataToFile(std::move(polled_data), &final_log_file_);
}
// If operating in bounded mode, the events were written to separate files
@@ -515,7 +518,7 @@ void FileNetLogObserver::FileWriter::Stop(
StitchFinalLogFile();
// Ensure the final log file has been flushed.
- final_log_file_.reset();
+ final_log_file_.Close();
}
void FileNetLogObserver::FileWriter::Flush(
@@ -526,7 +529,7 @@ void FileNetLogObserver::FileWriter::Flush(
write_queue->SwapQueue(&local_file_queue);
while (!local_file_queue.empty()) {
- FILE* output_file;
+ base::File* output_file;
// If in bounded mode, output events to the current event file. Otherwise
// output events to the final log path.
@@ -535,9 +538,9 @@ void FileNetLogObserver::FileWriter::Flush(
current_event_file_size_ >= max_event_file_size_) {
IncrementCurrentEventFile();
}
- output_file = current_event_file_.get();
+ output_file = &current_event_file_;
} else {
- output_file = final_log_file_.get();
+ output_file = &final_log_file_;
}
size_t bytes_written =
@@ -556,10 +559,10 @@ void FileNetLogObserver::FileWriter::Flush(
void FileNetLogObserver::FileWriter::DeleteAllFiles() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
- final_log_file_.reset();
+ final_log_file_.Close();
if (IsBounded()) {
- current_event_file_.reset();
+ current_event_file_.Close();
base::DeleteFile(GetInprogressDirectory(), true);
}
@@ -620,7 +623,7 @@ size_t FileNetLogObserver::FileWriter::FileNumberToIndex(
void FileNetLogObserver::FileWriter::WriteConstantsToFile(
std::unique_ptr<base::Value> constants_value,
- FILE* file) {
+ base::File* file) {
// Print constants to file and open events array.
std::string json;
@@ -632,7 +635,7 @@ void FileNetLogObserver::FileWriter::WriteConstantsToFile(
void FileNetLogObserver::FileWriter::WritePolledDataToFile(
std::unique_ptr<base::Value> polled_data,
- FILE* file) {
+ base::File* file) {
// Close the events array.
WriteToFile(file, "]");
@@ -648,18 +651,19 @@ void FileNetLogObserver::FileWriter::WritePolledDataToFile(
WriteToFile(file, "}\n");
}
-void FileNetLogObserver::FileWriter::RewindIfWroteEventBytes(FILE* file) const {
- if (file && wrote_event_bytes_) {
+void FileNetLogObserver::FileWriter::RewindIfWroteEventBytes(
+ base::File* file) const {
+ if (file->IsValid() && wrote_event_bytes_) {
// To be valid JSON the events array should not end with a comma. If events
// were written though, they will have been terminated with "\n," so strip
// it before closing the events array.
- fseek(file, -2, SEEK_END);
+ file->Seek(base::File::FROM_END, -2);
}
}
void FileNetLogObserver::FileWriter::StitchFinalLogFile() {
// Make sure all the events files are flushed (as will read them next).
- current_event_file_.reset();
+ current_event_file_.Close();
// Allocate a 64K buffer used for reading the files. At most kReadBufferSize
// bytes will be in memory at a time.
@@ -670,7 +674,7 @@ void FileNetLogObserver::FileWriter::StitchFinalLogFile() {
final_log_file_ = OpenFileForWrite(final_log_path_);
// Append the constants file.
- AppendToFileThenDelete(GetConstantsFilePath(), final_log_file_.get(),
+ AppendToFileThenDelete(GetConstantsFilePath(), &final_log_file_,
read_buffer.get(), kReadBufferSize);
// Iterate over the events files, from oldest to most recent, and append them
@@ -682,16 +686,16 @@ void FileNetLogObserver::FileWriter::StitchFinalLogFile() {
for (size_t filenumber = begin_filenumber; filenumber < end_filenumber;
++filenumber) {
AppendToFileThenDelete(GetEventFilePath(FileNumberToIndex(filenumber)),
- final_log_file_.get(), read_buffer.get(),
+ &final_log_file_, read_buffer.get(),
kReadBufferSize);
}
// Account for the final event line ending in a ",\n". Strip it to form valid
// JSON.
- RewindIfWroteEventBytes(final_log_file_.get());
+ RewindIfWroteEventBytes(&final_log_file_);
// Append the polled data.
- AppendToFileThenDelete(GetClosingFilePath(), final_log_file_.get(),
+ AppendToFileThenDelete(GetClosingFilePath(), &final_log_file_,
read_buffer.get(), kReadBufferSize);
// Delete the inprogress directory (and anything that may still be left inside
@@ -699,13 +703,13 @@ void FileNetLogObserver::FileWriter::StitchFinalLogFile() {
base::DeleteFile(GetInprogressDirectory(), true);
}
-void FileNetLogObserver::FileWriter::CreateInprogressDirectory() const {
+void FileNetLogObserver::FileWriter::CreateInprogressDirectory() {
DCHECK(IsBounded());
// base::CreateDirectory() creates missing parent directories. Since the
// target directory is a sibling to |final_log_path_|, if that file couldn't
// be opened don't attempt to create the directory either.
- if (!final_log_file_)
+ if (!final_log_file_.IsValid())
return;
if (!base::CreateDirectory(GetInprogressDirectory())) {
@@ -724,7 +728,7 @@ void FileNetLogObserver::FileWriter::CreateInprogressDirectory() const {
// stopping) however if logging does not end gracefully the comments are
// useful for recovery.
WriteToFile(
- final_log_file_.get(), "Logging is in progress writing data to:\n ",
+ &final_log_file_, "Logging is in progress writing data to:\n ",
in_progress_path,
"\n\n"
"That data will be stitched into a single file (this one) once logging\n"
@@ -735,7 +739,6 @@ void FileNetLogObserver::FileWriter::CreateInprogressDirectory() const {
"\n"
"https://chromium.googlesource.com/chromium/src/+/master/net/tools/"
"stitch_net_log_files.py\n");
- fflush(final_log_file_.get());
}
} // namespace net
diff --git a/chromium/net/log/net_log_event_type_list.h b/chromium/net/log/net_log_event_type_list.h
index e23f2e6e9d9..596c35c5be6 100644
--- a/chromium/net/log/net_log_event_type_list.h
+++ b/chromium/net/log/net_log_event_type_list.h
@@ -4,6 +4,9 @@
// NOTE: No header guards are used, since this file is intended to be expanded
// directly into net_log.h. DO NOT include this file anywhere else.
+// The following line silences a presubmit warning that would otherwise be
+// triggered by this:
+// no-include-guard-because-multiply-included
// In the event of a failure, a many end events will have a |net_error|
// parameter with the integer error code associated with the failure. Most
@@ -208,12 +211,12 @@ EVENT_TYPE(HOST_RESOLVER_IMPL_DNS_TASK)
// ------------------------------------------------------------------------
// The start/end of auto-detect + custom PAC URL configuration.
-EVENT_TYPE(PROXY_SCRIPT_DECIDER)
+EVENT_TYPE(PAC_FILE_DECIDER)
// The start/end of when proxy autoconfig was artificially paused following
// a network change event. (We wait some amount of time after being told of
// network changes to avoid hitting spurious errors during auto-detect).
-EVENT_TYPE(PROXY_SCRIPT_DECIDER_WAIT)
+EVENT_TYPE(PAC_FILE_DECIDER_WAIT)
// The start/end of download of a PAC script. This could be the well-known
// WPAD URL (if testing auto-detect), or a custom PAC URL.
@@ -227,27 +230,27 @@ EVENT_TYPE(PROXY_SCRIPT_DECIDER_WAIT)
// {
// "net_error": <Net error code integer>,
// }
-EVENT_TYPE(PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT)
+EVENT_TYPE(PAC_FILE_DECIDER_FETCH_PAC_SCRIPT)
// This event means that initialization failed because there was no
// configured script fetcher. (This indicates a configuration error).
-EVENT_TYPE(PROXY_SCRIPT_DECIDER_HAS_NO_FETCHER)
+EVENT_TYPE(PAC_FILE_DECIDER_HAS_NO_FETCHER)
// This event is emitted after deciding to fall-back to the next source
// of PAC scripts in the list.
-EVENT_TYPE(PROXY_SCRIPT_DECIDER_FALLING_BACK_TO_NEXT_PAC_SOURCE)
+EVENT_TYPE(PAC_FILE_DECIDER_FALLING_BACK_TO_NEXT_PAC_SOURCE)
// ------------------------------------------------------------------------
// ProxyResolutionService
// ------------------------------------------------------------------------
// The start/end of a proxy resolve request.
-EVENT_TYPE(PROXY_SERVICE)
+EVENT_TYPE(PROXY_RESOLUTION_SERVICE)
// The time while a request is waiting on InitProxyResolver to configure
// against either WPAD or custom PAC URL. The specifics on this time
// are found from ProxyResolutionService::init_proxy_resolver_log().
-EVENT_TYPE(PROXY_SERVICE_WAITING_FOR_INIT_PAC)
+EVENT_TYPE(PROXY_RESOLUTION_SERVICE_WAITING_FOR_INIT_PAC)
// This event is emitted to show what the PAC script returned. It can contain
// extra parameters that are either:
@@ -259,7 +262,7 @@ EVENT_TYPE(PROXY_SERVICE_WAITING_FOR_INIT_PAC)
// {
// "net_error": <Net error code that resolver failed with>,
// }
-EVENT_TYPE(PROXY_SERVICE_RESOLVED_PROXY_LIST)
+EVENT_TYPE(PROXY_RESOLUTION_SERVICE_RESOLVED_PROXY_LIST)
// This event is emitted after proxies marked as bad have been deprioritized.
//
@@ -267,7 +270,7 @@ EVENT_TYPE(PROXY_SERVICE_RESOLVED_PROXY_LIST)
// {
// "pac_string": <List of valid proxy servers, in PAC format>,
// }
-EVENT_TYPE(PROXY_SERVICE_DEPRIORITIZED_BAD_PROXIES)
+EVENT_TYPE(PROXY_RESOLUTION_SERVICE_DEPRIORITIZED_BAD_PROXIES)
// This event is emitted whenever the proxy settings used by
// ProxyResolutionService change.
@@ -1217,12 +1220,6 @@ EVENT_TYPE(HTTP_TRANSACTION_DRAIN_BODY_FOR_AUTH_RESTART)
// Measures the time taken to look up the key used for Token Binding.
EVENT_TYPE(HTTP_TRANSACTION_GET_TOKEN_BINDING_KEY)
-// Measures the time taken due to throttling by the NetworkThrottleManager.
-EVENT_TYPE(HTTP_TRANSACTION_THROTTLED)
-
-// Record priority changes on the network transaction.
-EVENT_TYPE(HTTP_TRANSACTION_SET_PRIORITY)
-
// This event is sent when we try to restart a transaction after an error.
// The following parameters are attached:
// {
@@ -2580,6 +2577,25 @@ EVENT_TYPE(CERT_VERIFIER_JOB)
// }
EVENT_TYPE(CERT_VERIFIER_REQUEST_BOUND_TO_JOB)
+// This event is created when a TrialComparisonCertVerifier starts a
+// verification using the trial verifier.
+//
+// The event parameters are:
+// {
+// "trial_success": <True if the trial verification had the same result>,
+// }
+EVENT_TYPE(TRIAL_CERT_VERIFIER_JOB)
+
+// This event is created when a TrialComparisonCertVerifier begins a trial
+// comparison job for a regular CertVerifier job.
+//
+// The event parameters are:
+// {
+// "source_dependency": <Source identifier for the trial comparison job
+// that was started>,
+// }
+EVENT_TYPE(TRIAL_CERT_VERIFIER_JOB_COMPARISON_STARTED)
+
// ------------------------------------------------------------------------
// Download start events.
// ------------------------------------------------------------------------
@@ -3080,50 +3096,6 @@ EVENT_TYPE(DATA_REDUCTION_PROXY_FALLBACK)
// }
EVENT_TYPE(DATA_REDUCTION_PROXY_CONFIG_REQUEST)
-// -----------------------------------------------------------------------------
-// Safe Browsing related events
-// -----------------------------------------------------------------------------
-
-// The start/end of an async URL check by Safe Browsing. Will only show up if
-// it can't be classified as "safe" synchronously.
-//
-// The BEGIN phase contains the following parameters:
-// {
-// "url": <The URL being checked>,
-// }
-//
-// The END phase contains the following parameters:
-// {
-// "result": <"safe", "unsafe", or "request_canceled">
-// }
-EVENT_TYPE(SAFE_BROWSING_CHECKING_URL)
-
-// The start/end of some portion of the SAFE_BROWSING_CHECKING_URL during which
-// the request is delayed due to that check.
-//
-// The BEGIN phase contains the following parameters:
-// {
-// "url": <The URL being checked>,
-// "defer_reason" : < "at_start", "at_response", "redirect",
-// "resumed_redirect", "unchecked_redirect">
-// }
-EVENT_TYPE(SAFE_BROWSING_DEFERRED)
-
-// The start/end of a Safe Browsing ping being sent.
-//
-// The BEGIN phase contains the following parameters:
-// {
-// "url": <The URL the ping is going to, which identifies the type of ping
-// that is being sent (eg: ThreatReport, SafeBrowsingHit)>
-// "data": <The base64 encoding of the payload sent with the ping>
-//
-// The END phase contains the following parameters:
-// {
-// "status": <The integer status of the report transmission. Corresponds to
-// URLRequestStatus::Status>
-// "error": <The error code returned by the server, 0 indicating success>
-EVENT_TYPE(SAFE_BROWSING_PING)
-
// Marks start of UploadDataStream that is logged on initialization.
// The END phase contains the following parameters:
// {
@@ -3219,3 +3191,55 @@ EVENT_TYPE(HOST_CACHE_PREF_WRITE)
// This event is created when the HostCachePersistenceManager starts the timer
// for writing a cache change to prefs.
EVENT_TYPE(HOST_CACHE_PERSISTENCE_START_TIMER)
+
+// -----------------------------------------------------------------------------
+// DHCP-based WPAD (Windows)
+// -----------------------------------------------------------------------------
+
+// The start/end of running DHCP based WPAD.
+//
+// The start event contains no parameters, whereas the END event describes
+// which of the "adapter fetchers" was used:
+// {
+// "fetcher_index": <Index of the fetcher that "won" the race, or -1 if no
+// fetcher won>,
+// "net_error": <The network error code for the overall result of DHCP
+// based auto-discovery>,
+// }
+EVENT_TYPE(WPAD_DHCP_WIN_FETCH)
+
+// The start/end of getting the list of network adapters.
+//
+// The END event describes all the adapters that were enumerated, as well
+// as how long it took to do the various thread-hops (from origin to worker
+// thread, and then worker thread back to origin thread):
+// {
+// "adapters": <List describing each adapter (its name, flags, and
+// status)>,
+// "origin_to_worker_thread_hop_dt": <The time in milliseconds it took
+// for the worker thread task to get
+// scheduled>,
+// "worker_to_origin_thread_hop_dt": <The time in milliseconds it took
+// for the reply task from worker
+// thread to get scheduled>,
+// "worker_dt": <The time in milliseconds it took to enumerate network
+// adapters on the worker thread>,
+// "error": <The result code returned by iphlpapi!GetAdaptersAddresses>
+// }
+EVENT_TYPE(WPAD_DHCP_WIN_GET_ADAPTERS)
+
+// This event logs when one of the "adapter fetchers" completed. (Fetchers
+// may not complete in the order that they were started):
+// {
+// "fetcher_index": <Index of the fetcher that completed>,
+// "net_error": <The network error code returned by the fetcher>,
+// }
+EVENT_TYPE(WPAD_DHCP_WIN_ON_FETCHER_DONE)
+
+// This event is logged when a timer is started to timeout remaining
+// adapter fetchers. The event has no parameters.
+EVENT_TYPE(WPAD_DHCP_WIN_START_WAIT_TIMER)
+
+// This event is emitted if the wait timer for remaining fetchers fires. It
+// has no parameters.
+EVENT_TYPE(WPAD_DHCP_WIN_ON_WAIT_TIMER)
diff --git a/chromium/net/log/net_log_source_type_list.h b/chromium/net/log/net_log_source_type_list.h
index 31e484bfde8..73ffe2aaabc 100644
--- a/chromium/net/log/net_log_source_type_list.h
+++ b/chromium/net/log/net_log_source_type_list.h
@@ -4,12 +4,15 @@
// NOTE: No header guards are used, since this file is intended to be expanded
// directly within a block where the SOURCE_TYPE macro is defined.
+// The following line silences a presubmit warning that would otherwise be
+// triggered by this:
+// no-include-guard-because-multiply-included
// Used for global events which don't correspond to a particular entity.
SOURCE_TYPE(NONE)
SOURCE_TYPE(URL_REQUEST)
-SOURCE_TYPE(PROXY_SCRIPT_DECIDER)
+SOURCE_TYPE(PAC_FILE_DECIDER)
SOURCE_TYPE(HTTP_PROXY_CONNECT_JOB)
SOURCE_TYPE(SOCKS_CONNECT_JOB)
SOURCE_TYPE(SSL_CONNECT_JOB)
@@ -41,3 +44,4 @@ SOURCE_TYPE(SERVER_PUSH_LOOKUP_TRANSACTION)
SOURCE_TYPE(QUIC_STREAM_FACTORY_JOB)
SOURCE_TYPE(HTTP_SERVER_PROPERTIES)
SOURCE_TYPE(HOST_CACHE_PERSISTENCE_MANAGER)
+SOURCE_TYPE(TRIAL_CERT_VERIFIER_JOB)
diff --git a/chromium/net/log/net_log_util.cc b/chromium/net/log/net_log_util.cc
index 4cef9606d32..38383730594 100644
--- a/chromium/net/log/net_log_util.cc
+++ b/chromium/net/log/net_log_util.cc
@@ -34,8 +34,8 @@
#include "net/log/net_log_parameters_callback.h"
#include "net/log/net_log_with_source.h"
#include "net/proxy_resolution/proxy_config.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/proxy_resolution/proxy_retry_info.h"
-#include "net/proxy_resolution/proxy_service.h"
#include "net/quic/core/quic_error_codes.h"
#include "net/quic/core/quic_packets.h"
#include "net/socket/ssl_client_socket.h"
@@ -322,9 +322,10 @@ NET_EXPORT std::unique_ptr<base::DictionaryValue> GetNetInfo(
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
if (proxy_resolution_service->fetched_config())
dict->Set("original",
- proxy_resolution_service->fetched_config()->ToValue());
+ proxy_resolution_service->fetched_config()->value().ToValue());
if (proxy_resolution_service->config())
- dict->Set("effective", proxy_resolution_service->config()->ToValue());
+ dict->Set("effective",
+ proxy_resolution_service->config()->value().ToValue());
net_info_dict->Set(NetInfoSourceToString(NET_INFO_PROXY_SETTINGS),
std::move(dict));
diff --git a/chromium/net/network_error_logging/network_error_logging_end_to_end_test.cc b/chromium/net/network_error_logging/network_error_logging_end_to_end_test.cc
index c5bc1b75b56..56fadcf5ddf 100644
--- a/chromium/net/network_error_logging/network_error_logging_end_to_end_test.cc
+++ b/chromium/net/network_error_logging/network_error_logging_end_to_end_test.cc
@@ -4,8 +4,10 @@
#include "base/macros.h"
#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/test/values_test_util.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
@@ -52,7 +54,8 @@ class HungHttpResponse : public test_server::HttpResponse {
class NetworkErrorLoggingEndToEndTest : public ::testing::Test {
protected:
NetworkErrorLoggingEndToEndTest()
- : test_server_(test_server::EmbeddedTestServer::TYPE_HTTPS),
+ : main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ test_server_(test_server::EmbeddedTestServer::TYPE_HTTPS),
upload_should_hang_(false),
upload_received_(false) {
// Make report delivery happen instantly.
@@ -61,8 +64,8 @@ class NetworkErrorLoggingEndToEndTest : public ::testing::Test {
URLRequestContextBuilder builder;
#if defined(OS_LINUX) || defined(OS_ANDROID)
- builder.set_proxy_config_service(
- std::make_unique<ProxyConfigServiceFixed>(ProxyConfig::CreateDirect()));
+ builder.set_proxy_config_service(std::make_unique<ProxyConfigServiceFixed>(
+ ProxyConfigWithAnnotation::CreateDirect()));
#endif // defined(OS_LINUX) || defined(OS_ANDROID)
builder.set_reporting_policy(std::move(policy));
builder.set_network_error_logging_enabled(true);
@@ -83,6 +86,10 @@ class NetworkErrorLoggingEndToEndTest : public ::testing::Test {
EXPECT_TRUE(test_server_.Start());
}
+ ~NetworkErrorLoggingEndToEndTest() override {
+ EXPECT_TRUE(test_server_.ShutdownAndWaitUntilComplete());
+ }
+
GURL GetConfigureURL() { return test_server_.GetURL(kConfigurePath); }
GURL GetFailURL() { return test_server_.GetURL(kFailPath); }
@@ -123,14 +130,11 @@ class NetworkErrorLoggingEndToEndTest : public ::testing::Test {
if (request.relative_url != kReportPath)
return nullptr;
- EXPECT_FALSE(upload_received_);
- upload_received_ = true;
-
EXPECT_TRUE(request.has_content);
- upload_content_ = request.content;
-
- if (!upload_closure_.is_null())
- std::move(upload_closure_).Run();
+ main_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&NetworkErrorLoggingEndToEndTest::OnUploadReceived,
+ base::Unretained(this), request.content));
if (upload_should_hang_)
return std::make_unique<HungHttpResponse>();
@@ -141,44 +145,51 @@ class NetworkErrorLoggingEndToEndTest : public ::testing::Test {
return std::move(response);
}
+ void OnUploadReceived(std::string content) {
+ upload_received_ = true;
+ upload_content_ = content;
+ upload_run_loop_.Quit();
+ }
+
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
std::unique_ptr<URLRequestContext> url_request_context_;
test_server::EmbeddedTestServer test_server_;
bool upload_should_hang_;
bool upload_received_;
std::string upload_content_;
- base::OnceClosure upload_closure_;
+ base::RunLoop upload_run_loop_;
private:
DISALLOW_COPY_AND_ASSIGN(NetworkErrorLoggingEndToEndTest);
};
-TEST_F(NetworkErrorLoggingEndToEndTest, ReportNetworkError) {
+#if defined(OS_WIN)
+// TODO(https://crbug.com/829650): Fix and re-enable these tests.
+#define MAYBE_ReportNetworkError DISABLED_ReportNetworkError
+#else
+#define MAYBE_ReportNetworkError ReportNetworkError
+#endif
+TEST_F(NetworkErrorLoggingEndToEndTest, MAYBE_ReportNetworkError) {
TestDelegate configure_delegate;
+ configure_delegate.set_quit_on_complete(false);
auto configure_request = url_request_context_->CreateRequest(
GetConfigureURL(), DEFAULT_PRIORITY, &configure_delegate,
TRAFFIC_ANNOTATION_FOR_TESTS);
configure_request->set_method("GET");
configure_request->Start();
- base::RunLoop().Run();
- EXPECT_TRUE(configure_request->status().is_success());
TestDelegate fail_delegate;
+ fail_delegate.set_quit_on_complete(false);
auto fail_request = url_request_context_->CreateRequest(
GetFailURL(), DEFAULT_PRIORITY, &fail_delegate,
TRAFFIC_ANNOTATION_FOR_TESTS);
fail_request->set_method("GET");
fail_request->Start();
- base::RunLoop().Run();
- EXPECT_EQ(URLRequestStatus::FAILED, fail_request->status().status());
- EXPECT_EQ(ERR_EMPTY_RESPONSE, fail_request->status().error());
-
- if (!upload_received_) {
- base::RunLoop run_loop;
- upload_closure_ = run_loop.QuitClosure();
- run_loop.Run();
- }
+ upload_run_loop_.Run();
+
+ EXPECT_TRUE(upload_received_);
auto reports = base::test::ParseJson(upload_content_);
base::ListValue* reports_list;
@@ -197,27 +208,34 @@ TEST_F(NetworkErrorLoggingEndToEndTest, ReportNetworkError) {
ExpectDictStringValue(GetFailURL().spec(), *body_dict, "uri");
}
+#if defined(OS_WIN)
+// TODO(https://crbug.com/829650): Fix and re-enable these tests.
+#define MAYBE_UploadAtShutdown DISABLED_UploadAtShutdown
+#else
+#define MAYBE_UploadAtShutdown UploadAtShutdown
+#endif
// Make sure an upload that is in progress at shutdown does not crash.
// This verifies that https://crbug.com/792978 is fixed.
-TEST_F(NetworkErrorLoggingEndToEndTest, UploadAtShutdown) {
+TEST_F(NetworkErrorLoggingEndToEndTest, MAYBE_UploadAtShutdown) {
upload_should_hang_ = true;
TestDelegate configure_delegate;
+ configure_delegate.set_quit_on_complete(false);
auto configure_request = url_request_context_->CreateRequest(
GetConfigureURL(), DEFAULT_PRIORITY, &configure_delegate,
TRAFFIC_ANNOTATION_FOR_TESTS);
configure_request->set_method("GET");
configure_request->Start();
- base::RunLoop().Run();
- EXPECT_TRUE(configure_request->status().is_success());
TestDelegate fail_delegate;
+ fail_delegate.set_quit_on_complete(false);
auto fail_request = url_request_context_->CreateRequest(
GetFailURL(), DEFAULT_PRIORITY, &fail_delegate,
TRAFFIC_ANNOTATION_FOR_TESTS);
fail_request->set_method("GET");
fail_request->Start();
- base::RunLoop().RunUntilIdle();
+
+ upload_run_loop_.Run();
// Let Reporting and NEL shut down with the upload still pending to see if
// they crash.
diff --git a/chromium/net/network_error_logging/network_error_logging_service.cc b/chromium/net/network_error_logging/network_error_logging_service.cc
index d8516dcee48..34dbf6e3b20 100644
--- a/chromium/net/network_error_logging/network_error_logging_service.cc
+++ b/chromium/net/network_error_logging/network_error_logging_service.cc
@@ -10,7 +10,7 @@
#include "base/json/json_reader.h"
#include "base/logging.h"
-#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
#include "base/rand_util.h"
#include "base/time/default_tick_clock.h"
#include "base/time/tick_clock.h"
@@ -20,7 +20,6 @@
#include "net/base/net_errors.h"
#include "net/network_error_logging/network_error_logging_delegate.h"
#include "net/reporting/reporting_service.h"
-#include "net/socket/next_proto.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -28,9 +27,12 @@ namespace net {
namespace {
+const int kMaxJsonSize = 16 * 1024;
+const int kMaxJsonDepth = 4;
+
const char kReportToKey[] = "report-to";
const char kMaxAgeKey[] = "max-age";
-const char kIncludeSubdomainsKey[] = "includeSubdomains";
+const char kIncludeSubdomainsKey[] = "include-subdomains";
const char kSuccessFractionKey[] = "success-fraction";
const char kFailureFractionKey[] = "failure-fraction";
@@ -114,9 +116,52 @@ bool IsHttpError(const NetworkErrorLoggingService::RequestDetails& request) {
return request.status_code >= 400 && request.status_code < 600;
}
-bool RequestWasSuccessful(
- const NetworkErrorLoggingService::RequestDetails& request) {
- return request.type == OK && !IsHttpError(request);
+enum class HeaderOutcome {
+ DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE = 0,
+ DISCARDED_INVALID_SSL_INFO = 1,
+ DISCARDED_CERT_STATUS_ERROR = 2,
+
+ DISCARDED_INSECURE_ORIGIN = 3,
+
+ DISCARDED_JSON_TOO_BIG = 4,
+ DISCARDED_JSON_INVALID = 5,
+ DISCARDED_NOT_DICTIONARY = 6,
+ DISCARDED_TTL_MISSING = 7,
+ DISCARDED_TTL_NOT_INTEGER = 8,
+ DISCARDED_TTL_NEGATIVE = 9,
+ DISCARDED_REPORT_TO_MISSING = 10,
+ DISCARDED_REPORT_TO_NOT_STRING = 11,
+
+ REMOVED = 12,
+ SET = 13,
+
+ MAX
+};
+
+void RecordHeaderOutcome(HeaderOutcome outcome) {
+ UMA_HISTOGRAM_ENUMERATION("Net.NetworkErrorLogging.HeaderOutcome", outcome,
+ HeaderOutcome::MAX);
+}
+
+enum class RequestOutcome {
+ DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE = 0,
+
+ DISCARDED_NO_REPORTING_SERVICE = 1,
+ DISCARDED_INSECURE_ORIGIN = 2,
+ DISCARDED_NO_ORIGIN_POLICY = 3,
+ DISCARDED_UNMAPPED_ERROR = 4,
+ DISCARDED_REPORTING_UPLOAD = 5,
+ DISCARDED_UNSAMPLED_SUCCESS = 6,
+ DISCARDED_UNSAMPLED_FAILURE = 7,
+
+ QUEUED = 8,
+
+ MAX
+};
+
+void RecordRequestOutcome(RequestOutcome outcome) {
+ UMA_HISTOGRAM_ENUMERATION("Net.NetworkErrorLogging.RequestOutcome", outcome,
+ RequestOutcome::MAX);
}
class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
@@ -127,18 +172,23 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
DCHECK(delegate_);
}
- // NetworkErrorLoggingService implementation:
-
~NetworkErrorLoggingServiceImpl() override = default;
+ // NetworkErrorLoggingService implementation:
+
void OnHeader(const url::Origin& origin, const std::string& value) override {
// NEL is only available to secure origins, so don't permit insecure origins
// to set policies.
- if (!origin.GetURL().SchemeIsCryptographic())
+ if (!origin.GetURL().SchemeIsCryptographic()) {
+ RecordHeaderOutcome(HeaderOutcome::DISCARDED_INSECURE_ORIGIN);
return;
+ }
OriginPolicy policy;
- if (!ParseHeader(value, tick_clock_->NowTicks(), &policy))
+ HeaderOutcome outcome =
+ ParseHeader(value, tick_clock_->NowTicks(), &policy);
+ RecordHeaderOutcome(outcome);
+ if (outcome != HeaderOutcome::SET && outcome != HeaderOutcome::REMOVED)
return;
PolicyMap::iterator it = policies_.find(origin);
@@ -156,43 +206,70 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
}
void OnRequest(const RequestDetails& details) override {
- if (!reporting_service_)
- return;
-
- // It is expected for Reporting uploads to terminate with ERR_ABORTED, since
- // the ReportingUploader cancels them after receiving the response code and
- // headers.
- if (details.is_reporting_upload && details.type == ERR_ABORTED)
+ if (!reporting_service_) {
+ RecordRequestOutcome(RequestOutcome::DISCARDED_NO_REPORTING_SERVICE);
return;
+ }
// NEL is only available to secure origins, so ignore network errors from
// insecure origins. (The check in OnHeader prevents insecure origins from
// setting policies, but this check is needed to ensure that insecure
// origins can't match wildcard policies from secure origins.)
- if (!details.uri.SchemeIsCryptographic())
+ if (!details.uri.SchemeIsCryptographic()) {
+ RecordRequestOutcome(RequestOutcome::DISCARDED_INSECURE_ORIGIN);
return;
+ }
const OriginPolicy* policy =
FindPolicyForOrigin(url::Origin::Create(details.uri));
- if (!policy)
+ if (!policy) {
+ RecordRequestOutcome(RequestOutcome::DISCARDED_NO_ORIGIN_POLICY);
return;
+ }
+
+ Error type = details.type;
+ // It is expected for Reporting uploads to terminate with ERR_ABORTED, since
+ // the ReportingUploader cancels them after receiving the response code and
+ // headers.
+ if (details.reporting_upload_depth > 0 && type == ERR_ABORTED) {
+ // TODO(juliatuttle): Modify ReportingUploader to drain successful uploads
+ // instead of aborting them, so NEL can properly report on aborted
+ // requests.
+ type = OK;
+ }
std::string type_string;
- if (!GetTypeFromNetError(details.type, &type_string))
+ if (!GetTypeFromNetError(type, &type_string)) {
+ RecordRequestOutcome(RequestOutcome::DISCARDED_UNMAPPED_ERROR);
return;
+ }
if (IsHttpError(details))
type_string = kHttpErrorType;
- double sampling_fraction = RequestWasSuccessful(details)
- ? policy->success_fraction
- : policy->failure_fraction;
- if (base::RandDouble() >= sampling_fraction)
+ // This check would go earlier, but the histogram bucket will be more
+ // meaningful if it only includes reports that otherwise could have been
+ // uploaded.
+ if (details.reporting_upload_depth > kMaxNestedReportDepth) {
+ RecordRequestOutcome(RequestOutcome::DISCARDED_REPORTING_UPLOAD);
return;
+ }
+
+ bool success = (type == OK) && !IsHttpError(details);
+ double sampling_fraction =
+ success ? policy->success_fraction : policy->failure_fraction;
+ if (base::RandDouble() >= sampling_fraction) {
+ RecordRequestOutcome(success
+ ? RequestOutcome::DISCARDED_UNSAMPLED_SUCCESS
+ : RequestOutcome::DISCARDED_UNSAMPLED_FAILURE);
+ return;
+ }
reporting_service_->QueueReport(
details.uri, policy->report_to, kReportType,
- CreateReportBody(type_string, sampling_fraction, details));
+ CreateReportBody(type_string, sampling_fraction, details),
+ details.reporting_upload_depth);
+ RecordRequestOutcome(RequestOutcome::QUEUED);
}
void RemoveBrowsingData(const base::RepeatingCallback<bool(const GURL&)>&
@@ -234,7 +311,8 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
// Would be unordered_map, but url::Origin has no hash.
using PolicyMap = std::map<url::Origin, OriginPolicy>;
- // Wildcard policies are policies for which the includeSubdomains flag is set.
+ // Wildcard policies are policies for which the include-subdomains flag is
+ // set.
//
// Wildcard policies are accessed by domain name, not full origin, so there
// can be multiple wildcard policies per domain name.
@@ -252,29 +330,41 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
PolicyMap policies_;
WildcardPolicyMap wildcard_policies_;
- bool ParseHeader(const std::string& json_value,
- base::TimeTicks now_ticks,
- OriginPolicy* policy_out) const {
+ HeaderOutcome ParseHeader(const std::string& json_value,
+ base::TimeTicks now_ticks,
+ OriginPolicy* policy_out) const {
DCHECK(policy_out);
- std::unique_ptr<base::Value> value = base::JSONReader::Read(json_value);
+ if (json_value.size() > kMaxJsonSize)
+ return HeaderOutcome::DISCARDED_JSON_TOO_BIG;
+
+ std::unique_ptr<base::Value> value =
+ base::JSONReader::Read(json_value, base::JSON_PARSE_RFC, kMaxJsonDepth);
if (!value)
- return false;
+ return HeaderOutcome::DISCARDED_JSON_INVALID;
const base::DictionaryValue* dict = nullptr;
if (!value->GetAsDictionary(&dict))
- return false;
+ return HeaderOutcome::DISCARDED_NOT_DICTIONARY;
+ if (!dict->HasKey(kMaxAgeKey))
+ return HeaderOutcome::DISCARDED_TTL_MISSING;
int max_age_sec;
- if (!dict->GetInteger(kMaxAgeKey, &max_age_sec) || max_age_sec < 0)
- return false;
+ if (!dict->GetInteger(kMaxAgeKey, &max_age_sec))
+ return HeaderOutcome::DISCARDED_TTL_NOT_INTEGER;
+ if (max_age_sec < 0)
+ return HeaderOutcome::DISCARDED_TTL_NEGATIVE;
std::string report_to;
- if (!dict->GetString(kReportToKey, &report_to) && max_age_sec > 0)
- return false;
+ if (max_age_sec > 0) {
+ if (!dict->HasKey(kReportToKey))
+ return HeaderOutcome::DISCARDED_REPORT_TO_MISSING;
+ if (!dict->GetString(kReportToKey, &report_to))
+ return HeaderOutcome::DISCARDED_REPORT_TO_NOT_STRING;
+ }
bool include_subdomains = false;
- // includeSubdomains is optional and defaults to false, so it's okay if
+ // include-subdomains is optional and defaults to false, so it's okay if
// GetBoolean fails.
dict->GetBoolean(kIncludeSubdomainsKey, &include_subdomains);
@@ -289,17 +379,17 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
dict->GetDouble(kFailureFractionKey, &failure_fraction);
policy_out->report_to = report_to;
+ policy_out->include_subdomains = include_subdomains;
+ policy_out->success_fraction = success_fraction;
+ policy_out->failure_fraction = failure_fraction;
if (max_age_sec > 0) {
policy_out->expires =
now_ticks + base::TimeDelta::FromSeconds(max_age_sec);
+ return HeaderOutcome::SET;
} else {
policy_out->expires = base::TimeTicks();
+ return HeaderOutcome::REMOVED;
}
- policy_out->include_subdomains = include_subdomains;
- policy_out->success_fraction = success_fraction;
- policy_out->failure_fraction = failure_fraction;
-
- return true;
}
const OriginPolicy* FindPolicyForOrigin(const url::Origin& origin) const {
@@ -331,7 +421,7 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
// TODO(juliatuttle): Come up with a deterministic way to resolve these.
if (it->second.size() > 1) {
LOG(WARNING) << "Domain " << domain
- << " matches multiple origins with includeSubdomains; "
+ << " matches multiple origins with include-subdomains; "
<< "choosing one arbitrarily.";
}
@@ -384,10 +474,7 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService {
body->SetString(kReferrerKey, details.referrer.spec());
body->SetDouble(kSamplingFractionKey, sampling_fraction);
body->SetString(kServerIpKey, details.server_ip.ToString());
- std::string protocol = NextProtoToString(details.protocol);
- if (protocol == "unknown")
- protocol = "";
- body->SetString(kProtocolKey, protocol);
+ body->SetString(kProtocolKey, details.protocol);
body->SetInteger(kStatusCodeKey, details.status_code);
body->SetInteger(kElapsedTimeKey, details.elapsed_time.InMilliseconds());
body->SetString(kTypeKey, type);
@@ -406,9 +493,21 @@ NetworkErrorLoggingService::RequestDetails::RequestDetails(
const RequestDetails& other) = default;
NetworkErrorLoggingService::RequestDetails::~RequestDetails() = default;
+
+// static:
+
const char NetworkErrorLoggingService::kHeaderName[] = "NEL";
const char NetworkErrorLoggingService::kReportType[] = "network-error";
+
+// Allow NEL reports on regular requests, plus NEL reports on Reporting uploads
+// containing only regular requests, but do not allow NEL reports on Reporting
+// uploads containing Reporting uploads.
+//
+// This prevents origins from building purposefully-broken Reporting endpoints
+// that generate new NEL reports to bypass the age limit on Reporting reports.
+const int NetworkErrorLoggingService::kMaxNestedReportDepth = 1;
+
const char NetworkErrorLoggingService::kUriKey[] = "uri";
const char NetworkErrorLoggingService::kReferrerKey[] = "referrer";
const char NetworkErrorLoggingService::kSamplingFractionKey[] =
@@ -420,6 +519,30 @@ const char NetworkErrorLoggingService::kElapsedTimeKey[] = "elapsed-time";
const char NetworkErrorLoggingService::kTypeKey[] = "type";
// static
+void NetworkErrorLoggingService::
+ RecordHeaderDiscardedForNoNetworkErrorLoggingService() {
+ RecordHeaderOutcome(
+ HeaderOutcome::DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE);
+}
+
+// static
+void NetworkErrorLoggingService::RecordHeaderDiscardedForInvalidSSLInfo() {
+ RecordHeaderOutcome(HeaderOutcome::DISCARDED_INVALID_SSL_INFO);
+}
+
+// static
+void NetworkErrorLoggingService::RecordHeaderDiscardedForCertStatusError() {
+ RecordHeaderOutcome(HeaderOutcome::DISCARDED_CERT_STATUS_ERROR);
+}
+
+// static
+void NetworkErrorLoggingService::
+ RecordRequestDiscardedForNoNetworkErrorLoggingService() {
+ RecordRequestOutcome(
+ RequestOutcome::DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE);
+}
+
+// static
std::unique_ptr<NetworkErrorLoggingService> NetworkErrorLoggingService::Create(
std::unique_ptr<NetworkErrorLoggingDelegate> delegate) {
return std::make_unique<NetworkErrorLoggingServiceImpl>(std::move(delegate));
@@ -433,7 +556,7 @@ void NetworkErrorLoggingService::SetReportingService(
}
void NetworkErrorLoggingService::SetTickClockForTesting(
- base::TickClock* tick_clock) {
+ const base::TickClock* tick_clock) {
tick_clock_ = tick_clock;
}
diff --git a/chromium/net/network_error_logging/network_error_logging_service.h b/chromium/net/network_error_logging/network_error_logging_service.h
index 3a7613f8b76..a25c0eea30a 100644
--- a/chromium/net/network_error_logging/network_error_logging_service.h
+++ b/chromium/net/network_error_logging/network_error_logging_service.h
@@ -17,7 +17,6 @@
#include "net/base/ip_address.h"
#include "net/base/net_errors.h"
#include "net/base/net_export.h"
-#include "net/socket/next_proto.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -51,18 +50,27 @@ class NET_EXPORT NetworkErrorLoggingService {
GURL uri;
GURL referrer;
IPAddress server_ip;
- NextProto protocol;
+ std::string protocol;
int status_code;
base::TimeDelta elapsed_time;
Error type;
- bool is_reporting_upload;
+ // Upload nesting depth of this request.
+ //
+ // If the request is not a Reporting upload, the depth is 0.
+ //
+ // If the request is a Reporting upload, the depth is the max of the depth
+ // of the requests reported within it plus 1. (Non-NEL reports are
+ // considered to have depth 0.)
+ int reporting_upload_depth;
};
static const char kHeaderName[];
static const char kReportType[];
+ static const int kMaxNestedReportDepth;
+
// Keys for data included in report bodies. Exposed for tests.
static const char kUriKey[];
@@ -74,6 +82,12 @@ class NET_EXPORT NetworkErrorLoggingService {
static const char kElapsedTimeKey[];
static const char kTypeKey[];
+ static void RecordHeaderDiscardedForNoNetworkErrorLoggingService();
+ static void RecordHeaderDiscardedForInvalidSSLInfo();
+ static void RecordHeaderDiscardedForCertStatusError();
+
+ static void RecordRequestDiscardedForNoNetworkErrorLoggingService();
+
static std::unique_ptr<NetworkErrorLoggingService> Create(
std::unique_ptr<NetworkErrorLoggingDelegate> delegate);
@@ -104,13 +118,13 @@ class NET_EXPORT NetworkErrorLoggingService {
// Sets a base::TickClock (used to track policy expiration) for tests.
// |tick_clock| must outlive the NetworkErrorLoggingService, and cannot be
// nullptr.
- void SetTickClockForTesting(base::TickClock* tick_clock);
+ void SetTickClockForTesting(const base::TickClock* tick_clock);
protected:
NetworkErrorLoggingService();
// Unowned:
- base::TickClock* tick_clock_;
+ const base::TickClock* tick_clock_;
ReportingService* reporting_service_;
private:
diff --git a/chromium/net/network_error_logging/network_error_logging_service_unittest.cc b/chromium/net/network_error_logging/network_error_logging_service_unittest.cc
index ac08be0614c..a1051402314 100644
--- a/chromium/net/network_error_logging/network_error_logging_service_unittest.cc
+++ b/chromium/net/network_error_logging/network_error_logging_service_unittest.cc
@@ -18,7 +18,6 @@
#include "net/network_error_logging/network_error_logging_service.h"
#include "net/reporting/reporting_policy.h"
#include "net/reporting/reporting_service.h"
-#include "net/socket/next_proto.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -35,13 +34,19 @@ class TestReportingService : public ReportingService {
: url(other.url),
group(other.group),
type(other.type),
- body(std::move(other.body)) {}
+ body(std::move(other.body)),
+ depth(other.depth) {}
Report(const GURL& url,
const std::string& group,
const std::string& type,
- std::unique_ptr<const base::Value> body)
- : url(url), group(group), type(type), body(std::move(body)) {}
+ std::unique_ptr<const base::Value> body,
+ int depth)
+ : url(url),
+ group(group),
+ type(type),
+ body(std::move(body)),
+ depth(depth) {}
~Report() = default;
@@ -49,6 +54,7 @@ class TestReportingService : public ReportingService {
std::string group;
std::string type;
std::unique_ptr<const base::Value> body;
+ int depth;
private:
DISALLOW_COPY(Report);
@@ -65,8 +71,9 @@ class TestReportingService : public ReportingService {
void QueueReport(const GURL& url,
const std::string& group,
const std::string& type,
- std::unique_ptr<const base::Value> body) override {
- reports_.push_back(Report(url, group, type, std::move(body)));
+ std::unique_ptr<const base::Value> body,
+ int depth) override {
+ reports_.push_back(Report(url, group, type, std::move(body), depth));
}
void ProcessHeader(const GURL& url,
@@ -80,9 +87,9 @@ class TestReportingService : public ReportingService {
NOTREACHED();
}
- bool RequestIsUpload(const URLRequest& request) override {
+ int GetUploadDepth(const URLRequest& request) override {
NOTREACHED();
- return true;
+ return 0;
}
const ReportingPolicy& GetPolicy() const override {
@@ -126,11 +133,10 @@ class NetworkErrorLoggingServiceTest : public ::testing::Test {
details.uri = url;
details.referrer = kReferrer_;
details.server_ip = IPAddress::IPv4AllZeros();
- details.protocol = kProtoUnknown;
details.status_code = status_code;
details.elapsed_time = base::TimeDelta::FromSeconds(1);
details.type = error_type;
- details.is_reporting_upload = false;
+ details.reporting_upload_depth = 0;
return details;
}
@@ -154,8 +160,14 @@ class NetworkErrorLoggingServiceTest : public ::testing::Test {
const std::string kHeader_ = "{\"report-to\":\"group\",\"max-age\":86400}";
const std::string kHeaderIncludeSubdomains_ =
- "{\"report-to\":\"group\",\"max-age\":86400,\"includeSubdomains\":true}";
+ "{\"report-to\":\"group\",\"max-age\":86400,\"include-subdomains\":true}";
const std::string kHeaderMaxAge0_ = "{\"max-age\":0}";
+ const std::string kHeaderTooLong_ =
+ "{\"report-to\":\"group\",\"max-age\":86400,\"junk\":\"" +
+ std::string(32 * 1024, 'a') + "\"}";
+ const std::string kHeaderTooDeep_ =
+ "{\"report-to\":\"group\",\"max-age\":86400,\"junk\":[[[[[[[[[[]]]]]]]]]]"
+ "}";
const std::string kGroup_ = "group";
@@ -207,6 +219,22 @@ TEST_F(NetworkErrorLoggingServiceTest, NoPolicyForOrigin) {
EXPECT_TRUE(reports().empty());
}
+TEST_F(NetworkErrorLoggingServiceTest, JsonTooLong) {
+ service()->OnHeader(kOrigin_, kHeaderTooLong_);
+
+ service()->OnRequest(MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED));
+
+ EXPECT_TRUE(reports().empty());
+}
+
+TEST_F(NetworkErrorLoggingServiceTest, JsonTooDeep) {
+ service()->OnHeader(kOrigin_, kHeaderTooDeep_);
+
+ service()->OnRequest(MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED));
+
+ EXPECT_TRUE(reports().empty());
+}
+
TEST_F(NetworkErrorLoggingServiceTest, SuccessReportQueued) {
static const std::string kHeaderSuccessFraction1 =
"{\"report-to\":\"group\",\"max-age\":86400,\"success-fraction\":1.0}";
@@ -218,6 +246,7 @@ TEST_F(NetworkErrorLoggingServiceTest, SuccessReportQueued) {
EXPECT_EQ(kUrl_, reports()[0].url);
EXPECT_EQ(kGroup_, reports()[0].group);
EXPECT_EQ(kType_, reports()[0].type);
+ EXPECT_EQ(0, reports()[0].depth);
const base::DictionaryValue* body;
ASSERT_TRUE(reports()[0].body->GetAsDictionary(&body));
@@ -251,6 +280,7 @@ TEST_F(NetworkErrorLoggingServiceTest, FailureReportQueued) {
EXPECT_EQ(kUrl_, reports()[0].url);
EXPECT_EQ(kGroup_, reports()[0].group);
EXPECT_EQ(kType_, reports()[0].type);
+ EXPECT_EQ(0, reports()[0].depth);
const base::DictionaryValue* body;
ASSERT_TRUE(reports()[0].body->GetAsDictionary(&body));
@@ -284,6 +314,7 @@ TEST_F(NetworkErrorLoggingServiceTest, HttpErrorReportQueued) {
EXPECT_EQ(kUrl_, reports()[0].url);
EXPECT_EQ(kGroup_, reports()[0].group);
EXPECT_EQ(kType_, reports()[0].type);
+ EXPECT_EQ(0, reports()[0].depth);
const base::DictionaryValue* body;
ASSERT_TRUE(reports()[0].body->GetAsDictionary(&body));
@@ -486,5 +517,31 @@ TEST_F(NetworkErrorLoggingServiceTest, RemoveSomeBrowsingData) {
ASSERT_EQ(1u, reports().size());
}
+TEST_F(NetworkErrorLoggingServiceTest, Nested) {
+ service()->OnHeader(kOrigin_, kHeader_);
+
+ NetworkErrorLoggingService::RequestDetails details =
+ MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED);
+ details.reporting_upload_depth =
+ NetworkErrorLoggingService::kMaxNestedReportDepth;
+ service()->OnRequest(details);
+
+ ASSERT_EQ(1u, reports().size());
+ EXPECT_EQ(NetworkErrorLoggingService::kMaxNestedReportDepth,
+ reports()[0].depth);
+}
+
+TEST_F(NetworkErrorLoggingServiceTest, NestedTooDeep) {
+ service()->OnHeader(kOrigin_, kHeader_);
+
+ NetworkErrorLoggingService::RequestDetails details =
+ MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED);
+ details.reporting_upload_depth =
+ NetworkErrorLoggingService::kMaxNestedReportDepth + 1;
+ service()->OnRequest(details);
+
+ EXPECT_TRUE(reports().empty());
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/nqe/effective_connection_type.h b/chromium/net/nqe/effective_connection_type.h
index 8be375c8940..518cc9083cd 100644
--- a/chromium/net/nqe/effective_connection_type.h
+++ b/chromium/net/nqe/effective_connection_type.h
@@ -33,9 +33,12 @@ enum EffectiveConnectionType {
// Effective connection type reported when the network quality is unknown.
EFFECTIVE_CONNECTION_TYPE_UNKNOWN = 0,
- // Effective connection type reported when the Internet is unreachable, either
- // because the device does not have a connection or because the
- // connection is too slow to be usable.
+ // Effective connection type reported when the Internet is unreachable
+ // because the device does not have a connection (as reported by underlying
+ // platform APIs). Note that due to rare but potential bugs in the platform
+ // APIs, it is possible that effective connection type is reported as
+ // EFFECTIVE_CONNECTION_TYPE_OFFLINE. Callers must use caution when using
+ // acting on this.
EFFECTIVE_CONNECTION_TYPE_OFFLINE,
// Effective connection type reported when the network has the quality of a
diff --git a/chromium/net/nqe/network_quality_estimator.cc b/chromium/net/nqe/network_quality_estimator.cc
index df164d15939..e7aba7f5bbc 100644
--- a/chromium/net/nqe/network_quality_estimator.cc
+++ b/chromium/net/nqe/network_quality_estimator.cc
@@ -636,8 +636,7 @@ bool NetworkQualityEstimator::RequestProvidesRTTObservation(
DCHECK(thread_checker_.CalledOnValidThread());
bool private_network_request = nqe::internal::IsPrivateHost(
- request.context()->host_resolver(),
- HostPortPair(request.url().host(), request.url().EffectiveIntPort()));
+ request.context()->host_resolver(), HostPortPair::FromURL(request.url()));
return (use_localhost_requests_ || !private_network_request) &&
// Verify that response headers are received, so it can be ensured that
@@ -1473,7 +1472,7 @@ bool NetworkQualityEstimator::ReadCachedNetworkQualityEstimate() {
}
void NetworkQualityEstimator::SetTickClockForTesting(
- base::TickClock* tick_clock) {
+ const base::TickClock* tick_clock) {
DCHECK(thread_checker_.CalledOnValidThread());
tick_clock_ = tick_clock;
http_rtt_ms_observations_.SetTickClockForTesting(tick_clock_);
diff --git a/chromium/net/nqe/network_quality_estimator.h b/chromium/net/nqe/network_quality_estimator.h
index 2c1a3d4959e..d3c3fa27e3b 100644
--- a/chromium/net/nqe/network_quality_estimator.h
+++ b/chromium/net/nqe/network_quality_estimator.h
@@ -273,7 +273,7 @@ class NET_EXPORT NetworkQualityEstimator
const;
// Overrides the tick clock used by |this| for testing.
- void SetTickClockForTesting(base::TickClock* tick_clock);
+ void SetTickClockForTesting(const base::TickClock* tick_clock);
// Returns the effective type of the current connection based on only the
// observations received after |start_time|. |http_rtt|, |transport_rtt| and
@@ -546,7 +546,7 @@ class NET_EXPORT NetworkQualityEstimator
bool disable_offline_check_;
// Tick clock used by the network quality estimator.
- base::TickClock* tick_clock_;
+ const base::TickClock* tick_clock_;
// Intervals after the main frame request arrives at which accuracy of network
// quality prediction is recorded.
diff --git a/chromium/net/nqe/network_quality_estimator_unittest.cc b/chromium/net/nqe/network_quality_estimator_unittest.cc
index b0b839e589a..f0082dad2cf 100644
--- a/chromium/net/nqe/network_quality_estimator_unittest.cc
+++ b/chromium/net/nqe/network_quality_estimator_unittest.cc
@@ -2863,8 +2863,9 @@ TEST(NetworkQualityEstimatorTest,
EXPECT_EQ(2u, rtt_observer.observations().size());
// RTT observation with source
- // NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE should be removed
- // from |estimator.rtt_ms_observations_| when a cached estimate is received.
+ // DEPRECATED_NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE should
+ // be removed from |estimator.rtt_ms_observations_| when a cached estimate is
+ // received.
EXPECT_EQ(1u, estimator.http_rtt_ms_observations_.Size());
EXPECT_EQ(1u, estimator.transport_rtt_ms_observations_.Size());
@@ -2872,7 +2873,7 @@ TEST(NetworkQualityEstimatorTest,
// estimate provider and platform must be discarded.
estimator.AddAndNotifyObserversOfRTT(nqe::internal::Observation(
1, base::TimeTicks::Now(), base::Optional<int32_t>(),
- NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE));
+ DEPRECATED_NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE));
estimator.AddAndNotifyObserversOfRTT(nqe::internal::Observation(
1, base::TimeTicks::Now(), base::Optional<int32_t>(),
NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_HTTP_FROM_PLATFORM));
@@ -2890,13 +2891,13 @@ TEST(NetworkQualityEstimatorTest,
// external estimate provider and platform must be discarded.
EXPECT_EQ(1u, throughput_observer.observations().size());
// Throughput observation with source
- // NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE should be removed
- // from |estimator.downstream_throughput_kbps_observations_| when a cached
- // estimate is received.
+ // DEPRECATED_NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE should
+ // be removed from |estimator.downstream_throughput_kbps_observations_| when a
+ // cached estimate is received.
EXPECT_EQ(1u, estimator.http_downstream_throughput_kbps_observations_.Size());
estimator.AddAndNotifyObserversOfThroughput(nqe::internal::Observation(
1, base::TimeTicks::Now(), base::Optional<int32_t>(),
- NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE));
+ DEPRECATED_NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE));
estimator.AddAndNotifyObserversOfThroughput(nqe::internal::Observation(
1, base::TimeTicks::Now(), base::Optional<int32_t>(),
NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_HTTP_FROM_PLATFORM));
diff --git a/chromium/net/nqe/network_quality_estimator_util.cc b/chromium/net/nqe/network_quality_estimator_util.cc
index 34e6b77ef86..91f5fd1b695 100644
--- a/chromium/net/nqe/network_quality_estimator_util.cc
+++ b/chromium/net/nqe/network_quality_estimator_util.cc
@@ -33,7 +33,7 @@ bool IsPrivateHost(HostResolver* host_resolver,
// Checking only the first address should be sufficient.
IPEndPoint ip_end_point = addresses.front();
net::IPAddress ip_address = ip_end_point.address();
- if (ip_address.IsReserved())
+ if (!ip_address.IsPubliclyRoutable())
return true;
}
diff --git a/chromium/net/nqe/network_quality_observation.cc b/chromium/net/nqe/network_quality_observation.cc
index 01827d5a67e..75670a9a622 100644
--- a/chromium/net/nqe/network_quality_observation.cc
+++ b/chromium/net/nqe/network_quality_observation.cc
@@ -41,7 +41,7 @@ ObservationCategory Observation::GetObservationCategory() const {
case NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP:
case NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE:
case NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_HTTP_FROM_PLATFORM:
- case NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE:
+ case DEPRECATED_NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE:
return ObservationCategory::kHttp;
case NETWORK_QUALITY_OBSERVATION_SOURCE_TRANSPORT_CACHED_ESTIMATE:
case NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_TRANSPORT_FROM_PLATFORM:
diff --git a/chromium/net/nqe/network_quality_observation_source.h b/chromium/net/nqe/network_quality_observation_source.h
index 0b49a8f6205..2a003478981 100644
--- a/chromium/net/nqe/network_quality_observation_source.h
+++ b/chromium/net/nqe/network_quality_observation_source.h
@@ -35,7 +35,8 @@ enum NetworkQualityObservationSource {
// The observation came from a Chromium-external source. The metric was
// computed by the external source at the HTTP layer.
- NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE = 5,
+ // Deprecated since external estimate provider is not currently queried.
+ DEPRECATED_NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE = 5,
// The observation is a previously cached estimate of the metric. The metric
// was computed at the transport layer.
diff --git a/chromium/net/nqe/observation_buffer.cc b/chromium/net/nqe/observation_buffer.cc
index beb93590e0f..84796058ada 100644
--- a/chromium/net/nqe/observation_buffer.cc
+++ b/chromium/net/nqe/observation_buffer.cc
@@ -23,7 +23,7 @@ namespace internal {
ObservationBuffer::ObservationBuffer(
const NetworkQualityEstimatorParams* params,
- base::TickClock* tick_clock,
+ const base::TickClock* tick_clock,
double weight_multiplier_per_second,
double weight_multiplier_per_signal_level)
: params_(params),
diff --git a/chromium/net/nqe/observation_buffer.h b/chromium/net/nqe/observation_buffer.h
index 4c4bc510531..3d59ea19f81 100644
--- a/chromium/net/nqe/observation_buffer.h
+++ b/chromium/net/nqe/observation_buffer.h
@@ -41,7 +41,7 @@ struct WeightedObservation;
class NET_EXPORT_PRIVATE ObservationBuffer {
public:
ObservationBuffer(const NetworkQualityEstimatorParams* params,
- base::TickClock* tick_clock,
+ const base::TickClock* tick_clock,
double weight_multiplier_per_second,
double weight_multiplier_per_signal_level);
@@ -75,7 +75,7 @@ class NET_EXPORT_PRIVATE ObservationBuffer {
int percentile,
size_t* observations_count) const;
- void SetTickClockForTesting(base::TickClock* tick_clock) {
+ void SetTickClockForTesting(const base::TickClock* tick_clock) {
tick_clock_ = tick_clock;
}
@@ -134,7 +134,7 @@ class NET_EXPORT_PRIVATE ObservationBuffer {
// |weight_multiplier_per_signal_level_| ^ 3.
const double weight_multiplier_per_signal_level_;
- base::TickClock* tick_clock_;
+ const base::TickClock* tick_clock_;
DISALLOW_COPY_AND_ASSIGN(ObservationBuffer);
};
diff --git a/chromium/net/nqe/socket_watcher.cc b/chromium/net/nqe/socket_watcher.cc
index d10508bfea9..8e2fb783def 100644
--- a/chromium/net/nqe/socket_watcher.cc
+++ b/chromium/net/nqe/socket_watcher.cc
@@ -61,7 +61,7 @@ SocketWatcher::SocketWatcher(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
OnUpdatedRTTAvailableCallback updated_rtt_observation_callback,
ShouldNotifyRTTCallback should_notify_rtt_callback,
- base::TickClock* tick_clock)
+ const base::TickClock* tick_clock)
: protocol_(protocol),
task_runner_(std::move(task_runner)),
updated_rtt_observation_callback_(updated_rtt_observation_callback),
@@ -69,7 +69,7 @@ SocketWatcher::SocketWatcher(
rtt_notifications_minimum_interval_(min_notification_interval),
run_rtt_callback_(allow_rtt_private_address ||
(!address_list.empty() &&
- !address_list.front().address().IsReserved())),
+ address_list.front().address().IsPubliclyRoutable())),
tick_clock_(tick_clock),
first_quic_rtt_notification_received_(false),
host_(CalculateIPHash(address_list)) {
diff --git a/chromium/net/nqe/socket_watcher.h b/chromium/net/nqe/socket_watcher.h
index 52b1d73a10f..a383dadd082 100644
--- a/chromium/net/nqe/socket_watcher.h
+++ b/chromium/net/nqe/socket_watcher.h
@@ -65,7 +65,7 @@ class NET_EXPORT_PRIVATE SocketWatcher : public SocketPerformanceWatcher {
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
OnUpdatedRTTAvailableCallback updated_rtt_observation_callback,
ShouldNotifyRTTCallback should_notify_rtt_callback,
- base::TickClock* tick_clock);
+ const base::TickClock* tick_clock);
~SocketWatcher() override;
@@ -97,7 +97,7 @@ class NET_EXPORT_PRIVATE SocketWatcher : public SocketPerformanceWatcher {
// Time when this was last notified of updated RTT.
base::TimeTicks last_rtt_notification_;
- base::TickClock* tick_clock_;
+ const base::TickClock* tick_clock_;
base::ThreadChecker thread_checker_;
diff --git a/chromium/net/nqe/socket_watcher_factory.cc b/chromium/net/nqe/socket_watcher_factory.cc
index e20cb0c7d27..884ea770345 100644
--- a/chromium/net/nqe/socket_watcher_factory.cc
+++ b/chromium/net/nqe/socket_watcher_factory.cc
@@ -18,7 +18,7 @@ SocketWatcherFactory::SocketWatcherFactory(
base::TimeDelta min_notification_interval,
OnUpdatedRTTAvailableCallback updated_rtt_observation_callback,
ShouldNotifyRTTCallback should_notify_rtt_callback,
- base::TickClock* tick_clock)
+ const base::TickClock* tick_clock)
: task_runner_(std::move(task_runner)),
min_notification_interval_(min_notification_interval),
allow_rtt_private_address_(false),
@@ -41,7 +41,8 @@ SocketWatcherFactory::CreateSocketPerformanceWatcher(
tick_clock_);
}
-void SocketWatcherFactory::SetTickClockForTesting(base::TickClock* tick_clock) {
+void SocketWatcherFactory::SetTickClockForTesting(
+ const base::TickClock* tick_clock) {
tick_clock_ = tick_clock;
}
diff --git a/chromium/net/nqe/socket_watcher_factory.h b/chromium/net/nqe/socket_watcher_factory.h
index 7634d6fc0b0..58d613338aa 100644
--- a/chromium/net/nqe/socket_watcher_factory.h
+++ b/chromium/net/nqe/socket_watcher_factory.h
@@ -57,7 +57,7 @@ class SocketWatcherFactory : public SocketPerformanceWatcherFactory {
base::TimeDelta min_notification_interval,
OnUpdatedRTTAvailableCallback updated_rtt_observation_callback,
ShouldNotifyRTTCallback should_notify_rtt_callback,
- base::TickClock* tick_clock);
+ const base::TickClock* tick_clock);
~SocketWatcherFactory() override;
@@ -71,7 +71,7 @@ class SocketWatcherFactory : public SocketPerformanceWatcherFactory {
}
// Overrides the tick clock used by |this| for testing.
- void SetTickClockForTesting(base::TickClock* tick_clock);
+ void SetTickClockForTesting(const base::TickClock* tick_clock);
private:
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
@@ -91,7 +91,7 @@ class SocketWatcherFactory : public SocketPerformanceWatcherFactory {
// notification should be notified using |updated_rtt_observation_callback_|.
ShouldNotifyRTTCallback should_notify_rtt_callback_;
- base::TickClock* tick_clock_;
+ const base::TickClock* tick_clock_;
DISALLOW_COPY_AND_ASSIGN(SocketWatcherFactory);
};
diff --git a/chromium/net/nqe/throughput_analyzer.cc b/chromium/net/nqe/throughput_analyzer.cc
index 376e9d6663b..9dfc9ab26e6 100644
--- a/chromium/net/nqe/throughput_analyzer.cc
+++ b/chromium/net/nqe/throughput_analyzer.cc
@@ -46,7 +46,7 @@ ThroughputAnalyzer::ThroughputAnalyzer(
const NetworkQualityEstimatorParams* params,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
ThroughputObservationCallback throughput_observation_callback,
- base::TickClock* tick_clock,
+ const base::TickClock* tick_clock,
const NetLogWithSource& net_log)
: network_quality_provider_(network_quality_provider),
params_(params),
@@ -118,7 +118,8 @@ bool ThroughputAnalyzer::IsCurrentlyTrackingThroughput() const {
return true;
}
-void ThroughputAnalyzer::SetTickClockForTesting(base::TickClock* tick_clock) {
+void ThroughputAnalyzer::SetTickClockForTesting(
+ const base::TickClock* tick_clock) {
DCHECK(thread_checker_.CalledOnValidThread());
tick_clock_ = tick_clock;
DCHECK(tick_clock_);
@@ -349,8 +350,7 @@ bool ThroughputAnalyzer::DegradesAccuracy(const URLRequest& request) const {
DCHECK(thread_checker_.CalledOnValidThread());
bool private_network_request = nqe::internal::IsPrivateHost(
- request.context()->host_resolver(),
- HostPortPair(request.url().host(), request.url().EffectiveIntPort()));
+ request.context()->host_resolver(), HostPortPair::FromURL(request.url()));
return !(use_localhost_requests_for_tests_ || !private_network_request) ||
request.creation_time() < last_connection_change_;
diff --git a/chromium/net/nqe/throughput_analyzer.h b/chromium/net/nqe/throughput_analyzer.h
index 77350017b3a..446a9022164 100644
--- a/chromium/net/nqe/throughput_analyzer.h
+++ b/chromium/net/nqe/throughput_analyzer.h
@@ -63,7 +63,7 @@ class NET_EXPORT_PRIVATE ThroughputAnalyzer {
const NetworkQualityEstimatorParams* params,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
ThroughputObservationCallback throughput_observation_callback,
- base::TickClock* tick_clock,
+ const base::TickClock* tick_clock,
const NetLogWithSource& net_log);
virtual ~ThroughputAnalyzer();
@@ -89,7 +89,7 @@ class NET_EXPORT_PRIVATE ThroughputAnalyzer {
bool IsCurrentlyTrackingThroughput() const;
// Overrides the tick clock used by |this| for testing.
- void SetTickClockForTesting(base::TickClock* tick_clock);
+ void SetTickClockForTesting(const base::TickClock* tick_clock);
protected:
// Exposed for testing.
@@ -173,7 +173,7 @@ class NET_EXPORT_PRIVATE ThroughputAnalyzer {
ThroughputObservationCallback throughput_observation_callback_;
// Guaranteed to be non-null during the lifetime of |this|.
- base::TickClock* tick_clock_;
+ const base::TickClock* tick_clock_;
// Time when last connection change was observed.
base::TimeTicks last_connection_change_;
diff --git a/chromium/net/nqe/throughput_analyzer_unittest.cc b/chromium/net/nqe/throughput_analyzer_unittest.cc
index 0b164dfeb07..11ea27d957f 100644
--- a/chromium/net/nqe/throughput_analyzer_unittest.cc
+++ b/chromium/net/nqe/throughput_analyzer_unittest.cc
@@ -61,7 +61,7 @@ class TestThroughputAnalyzer : public internal::ThroughputAnalyzer {
public:
TestThroughputAnalyzer(NetworkQualityProvider* network_quality_provider,
NetworkQualityEstimatorParams* params,
- base::TickClock* tick_clock)
+ const base::TickClock* tick_clock)
: internal::ThroughputAnalyzer(
network_quality_provider,
params,
@@ -127,7 +127,7 @@ TEST(ThroughputAnalyzerTest, MaximumRequests) {
}};
for (const auto& test : tests) {
- base::DefaultTickClock* tick_clock = base::DefaultTickClock::GetInstance();
+ const base::TickClock* tick_clock = base::DefaultTickClock::GetInstance();
TestNetworkQualityProvider network_quality_provider;
std::map<std::string, std::string> variation_params;
NetworkQualityEstimatorParams params(variation_params);
@@ -169,7 +169,7 @@ TEST(ThroughputAnalyzerTest, MaximumRequests) {
// Tests that the throughput observation is taken only if there are sufficient
// number of requests in-flight.
TEST(ThroughputAnalyzerTest, TestMinRequestsForThroughputSample) {
- base::DefaultTickClock* tick_clock = base::DefaultTickClock::GetInstance();
+ const base::TickClock* tick_clock = base::DefaultTickClock::GetInstance();
TestNetworkQualityProvider network_quality_provider;
std::map<std::string, std::string> variation_params;
variation_params["throughput_hanging_requests_cwnd_size_multiplier"] = "-1";
@@ -276,7 +276,7 @@ TEST(ThroughputAnalyzerTest, TestHangingRequests) {
for (const auto& test : tests) {
base::HistogramTester histogram_tester;
- base::DefaultTickClock* tick_clock = base::DefaultTickClock::GetInstance();
+ const base::TickClock* tick_clock = base::DefaultTickClock::GetInstance();
TestNetworkQualityProvider network_quality_provider;
if (test.http_rtt >= base::TimeDelta())
network_quality_provider.SetHttpRtt(test.http_rtt);
@@ -569,7 +569,7 @@ TEST(ThroughputAnalyzerTest, TestThroughputWithMultipleRequestsOverlap) {
};
for (const auto& test : tests) {
- base::DefaultTickClock* tick_clock = base::DefaultTickClock::GetInstance();
+ const base::TickClock* tick_clock = base::DefaultTickClock::GetInstance();
TestNetworkQualityProvider network_quality_provider;
// Localhost requests are not allowed for estimation purposes.
std::map<std::string, std::string> variation_params;
@@ -672,7 +672,7 @@ TEST(ThroughputAnalyzerTest, TestThroughputWithNetworkRequestsOverlap) {
};
for (const auto& test : tests) {
- base::DefaultTickClock* tick_clock = base::DefaultTickClock::GetInstance();
+ const base::TickClock* tick_clock = base::DefaultTickClock::GetInstance();
TestNetworkQualityProvider network_quality_provider;
// Localhost requests are not allowed for estimation purposes.
std::map<std::string, std::string> variation_params;
@@ -736,7 +736,7 @@ TEST(ThroughputAnalyzerTest, TestThroughputWithNetworkRequestsOverlap) {
// of network requests overlap, and the minimum number of in flight requests
// when taking an observation is more than 1.
TEST(ThroughputAnalyzerTest, TestThroughputWithMultipleNetworkRequests) {
- base::DefaultTickClock* tick_clock = base::DefaultTickClock::GetInstance();
+ const base::TickClock* tick_clock = base::DefaultTickClock::GetInstance();
TestNetworkQualityProvider network_quality_provider;
std::map<std::string, std::string> variation_params;
variation_params["throughput_min_requests_in_flight"] = "3";
diff --git a/chromium/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.cc b/chromium/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.cc
index e75d189c82d..b81f44dff40 100644
--- a/chromium/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.cc
+++ b/chromium/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.cc
@@ -32,7 +32,7 @@ const int kTimeoutMs = 2000;
namespace net {
-DhcpProxyScriptAdapterFetcher::DhcpProxyScriptAdapterFetcher(
+DhcpPacFileAdapterFetcher::DhcpPacFileAdapterFetcher(
URLRequestContext* url_request_context,
scoped_refptr<base::TaskRunner> task_runner)
: task_runner_(task_runner),
@@ -42,13 +42,15 @@ DhcpProxyScriptAdapterFetcher::DhcpProxyScriptAdapterFetcher(
DCHECK(url_request_context_);
}
-DhcpProxyScriptAdapterFetcher::~DhcpProxyScriptAdapterFetcher() {
+DhcpPacFileAdapterFetcher::~DhcpPacFileAdapterFetcher() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
Cancel();
}
-void DhcpProxyScriptAdapterFetcher::Fetch(
- const std::string& adapter_name, const CompletionCallback& callback) {
+void DhcpPacFileAdapterFetcher::Fetch(
+ const std::string& adapter_name,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag traffic_annotation) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK_EQ(state_, STATE_START);
result_ = ERR_IO_PENDING;
@@ -56,22 +58,18 @@ void DhcpProxyScriptAdapterFetcher::Fetch(
state_ = STATE_WAIT_DHCP;
callback_ = callback;
- wait_timer_.Start(FROM_HERE, ImplGetTimeout(),
- this, &DhcpProxyScriptAdapterFetcher::OnTimeout);
+ wait_timer_.Start(FROM_HERE, ImplGetTimeout(), this,
+ &DhcpPacFileAdapterFetcher::OnTimeout);
scoped_refptr<DhcpQuery> dhcp_query(ImplCreateDhcpQuery());
task_runner_->PostTaskAndReply(
FROM_HERE,
- base::Bind(
- &DhcpProxyScriptAdapterFetcher::DhcpQuery::GetPacURLForAdapter,
- dhcp_query.get(),
- adapter_name),
- base::Bind(
- &DhcpProxyScriptAdapterFetcher::OnDhcpQueryDone,
- AsWeakPtr(),
- dhcp_query));
+ base::Bind(&DhcpPacFileAdapterFetcher::DhcpQuery::GetPacURLForAdapter,
+ dhcp_query.get(), adapter_name),
+ base::Bind(&DhcpPacFileAdapterFetcher::OnDhcpQueryDone, AsWeakPtr(),
+ dhcp_query, traffic_annotation));
}
-void DhcpProxyScriptAdapterFetcher::Cancel() {
+void DhcpPacFileAdapterFetcher::Cancel() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
callback_.Reset();
wait_timer_.Stop();
@@ -96,49 +94,47 @@ void DhcpProxyScriptAdapterFetcher::Cancel() {
}
}
-bool DhcpProxyScriptAdapterFetcher::DidFinish() const {
+bool DhcpPacFileAdapterFetcher::DidFinish() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return state_ == STATE_FINISH;
}
-int DhcpProxyScriptAdapterFetcher::GetResult() const {
+int DhcpPacFileAdapterFetcher::GetResult() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return result_;
}
-base::string16 DhcpProxyScriptAdapterFetcher::GetPacScript() const {
+base::string16 DhcpPacFileAdapterFetcher::GetPacScript() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return pac_script_;
}
-GURL DhcpProxyScriptAdapterFetcher::GetPacURL() const {
+GURL DhcpPacFileAdapterFetcher::GetPacURL() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return pac_url_;
}
-DhcpProxyScriptAdapterFetcher::DhcpQuery::DhcpQuery() {
-}
+DhcpPacFileAdapterFetcher::DhcpQuery::DhcpQuery() {}
-void DhcpProxyScriptAdapterFetcher::DhcpQuery::GetPacURLForAdapter(
+void DhcpPacFileAdapterFetcher::DhcpQuery::GetPacURLForAdapter(
const std::string& adapter_name) {
url_ = ImplGetPacURLFromDhcp(adapter_name);
}
-const std::string& DhcpProxyScriptAdapterFetcher::DhcpQuery::url() const {
+const std::string& DhcpPacFileAdapterFetcher::DhcpQuery::url() const {
return url_;
}
-std::string
- DhcpProxyScriptAdapterFetcher::DhcpQuery::ImplGetPacURLFromDhcp(
- const std::string& adapter_name) {
- return DhcpProxyScriptAdapterFetcher::GetPacURLFromDhcp(adapter_name);
+std::string DhcpPacFileAdapterFetcher::DhcpQuery::ImplGetPacURLFromDhcp(
+ const std::string& adapter_name) {
+ return DhcpPacFileAdapterFetcher::GetPacURLFromDhcp(adapter_name);
}
-DhcpProxyScriptAdapterFetcher::DhcpQuery::~DhcpQuery() {
-}
+DhcpPacFileAdapterFetcher::DhcpQuery::~DhcpQuery() {}
-void DhcpProxyScriptAdapterFetcher::OnDhcpQueryDone(
- scoped_refptr<DhcpQuery> dhcp_query) {
+void DhcpPacFileAdapterFetcher::OnDhcpQueryDone(
+ scoped_refptr<DhcpQuery> dhcp_query,
+ const NetworkTrafficAnnotationTag traffic_annotation) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Because we can't cancel the call to the Win32 API, we can expect
// it to finish while we are in a few different states. The expected
@@ -158,20 +154,20 @@ void DhcpProxyScriptAdapterFetcher::OnDhcpQueryDone(
} else {
state_ = STATE_WAIT_URL;
script_fetcher_.reset(ImplCreateScriptFetcher());
- script_fetcher_->Fetch(
- pac_url_, &pac_script_,
- base::Bind(&DhcpProxyScriptAdapterFetcher::OnFetcherDone,
- base::Unretained(this)));
+ script_fetcher_->Fetch(pac_url_, &pac_script_,
+ base::Bind(&DhcpPacFileAdapterFetcher::OnFetcherDone,
+ base::Unretained(this)),
+ traffic_annotation);
}
}
-void DhcpProxyScriptAdapterFetcher::OnTimeout() {
+void DhcpPacFileAdapterFetcher::OnTimeout() {
DCHECK_EQ(state_, STATE_WAIT_DHCP);
result_ = ERR_TIMED_OUT;
TransitionToFinish();
}
-void DhcpProxyScriptAdapterFetcher::OnFetcherDone(int result) {
+void DhcpPacFileAdapterFetcher::OnFetcherDone(int result) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(state_ == STATE_WAIT_URL || state_ == STATE_CANCEL);
if (state_ == STATE_CANCEL)
@@ -183,7 +179,7 @@ void DhcpProxyScriptAdapterFetcher::OnFetcherDone(int result) {
TransitionToFinish();
}
-void DhcpProxyScriptAdapterFetcher::TransitionToFinish() {
+void DhcpPacFileAdapterFetcher::TransitionToFinish() {
DCHECK(state_ == STATE_WAIT_DHCP || state_ == STATE_WAIT_URL);
state_ = STATE_FINISH;
CompletionCallback callback = callback_;
@@ -194,26 +190,25 @@ void DhcpProxyScriptAdapterFetcher::TransitionToFinish() {
callback.Run(result_);
}
-DhcpProxyScriptAdapterFetcher::State
- DhcpProxyScriptAdapterFetcher::state() const {
+DhcpPacFileAdapterFetcher::State DhcpPacFileAdapterFetcher::state() const {
return state_;
}
-ProxyScriptFetcher* DhcpProxyScriptAdapterFetcher::ImplCreateScriptFetcher() {
- return new ProxyScriptFetcherImpl(url_request_context_);
+PacFileFetcher* DhcpPacFileAdapterFetcher::ImplCreateScriptFetcher() {
+ return new PacFileFetcherImpl(url_request_context_);
}
-DhcpProxyScriptAdapterFetcher::DhcpQuery*
- DhcpProxyScriptAdapterFetcher::ImplCreateDhcpQuery() {
+DhcpPacFileAdapterFetcher::DhcpQuery*
+DhcpPacFileAdapterFetcher::ImplCreateDhcpQuery() {
return new DhcpQuery();
}
-base::TimeDelta DhcpProxyScriptAdapterFetcher::ImplGetTimeout() const {
+base::TimeDelta DhcpPacFileAdapterFetcher::ImplGetTimeout() const {
return base::TimeDelta::FromMilliseconds(kTimeoutMs);
}
// static
-std::string DhcpProxyScriptAdapterFetcher::GetPacURLFromDhcp(
+std::string DhcpPacFileAdapterFetcher::GetPacURLFromDhcp(
const std::string& adapter_name) {
EnsureDhcpcsvcInit();
@@ -274,8 +269,9 @@ std::string DhcpProxyScriptAdapterFetcher::GetPacURLFromDhcp(
}
// static
-std::string DhcpProxyScriptAdapterFetcher::SanitizeDhcpApiString(
- const char* data, size_t count_bytes) {
+std::string DhcpPacFileAdapterFetcher::SanitizeDhcpApiString(
+ const char* data,
+ size_t count_bytes) {
// The result should be ASCII, not wide character. Some DHCP
// servers appear to count the trailing NULL in nBytesData, others
// do not. A few (we've had one report, http://crbug.com/297810)
diff --git a/chromium/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.h b/chromium/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.h
index 64603e4310f..6e07d2bef29 100644
--- a/chromium/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.h
+++ b/chromium/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.h
@@ -18,6 +18,7 @@
#include "base/timer/timer.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"
namespace base {
@@ -26,19 +27,19 @@ class TaskRunner;
namespace net {
-class ProxyScriptFetcher;
+class PacFileFetcher;
class URLRequestContext;
// For a given adapter, this class takes care of first doing a DHCP lookup
// to get the PAC URL, then if there is one, trying to fetch it.
-class NET_EXPORT_PRIVATE DhcpProxyScriptAdapterFetcher
- : public base::SupportsWeakPtr<DhcpProxyScriptAdapterFetcher> {
+class NET_EXPORT_PRIVATE DhcpPacFileAdapterFetcher
+ : public base::SupportsWeakPtr<DhcpPacFileAdapterFetcher> {
public:
- // |url_request_context| must outlive DhcpProxyScriptAdapterFetcher.
+ // |url_request_context| must outlive DhcpPacFileAdapterFetcher.
// |task_runner| will be used to post tasks to a thread.
- DhcpProxyScriptAdapterFetcher(URLRequestContext* url_request_context,
- scoped_refptr<base::TaskRunner> task_runner);
- virtual ~DhcpProxyScriptAdapterFetcher();
+ DhcpPacFileAdapterFetcher(URLRequestContext* url_request_context,
+ scoped_refptr<base::TaskRunner> task_runner);
+ virtual ~DhcpPacFileAdapterFetcher();
// Starts a fetch. On completion (but not cancellation), |callback|
// will be invoked with the network error indicating success or failure
@@ -47,9 +48,10 @@ class NET_EXPORT_PRIVATE DhcpProxyScriptAdapterFetcher
// On completion, results can be obtained via |GetPacScript()|, |GetPacURL()|.
//
// You may only call Fetch() once on a given instance of
- // DhcpProxyScriptAdapterFetcher.
+ // DhcpPacFileAdapterFetcher.
virtual void Fetch(const std::string& adapter_name,
- const CompletionCallback& callback);
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag traffic_annotation);
// Cancels the fetch on this adapter.
virtual void Cancel();
@@ -93,9 +95,9 @@ class NET_EXPORT_PRIVATE DhcpProxyScriptAdapterFetcher
//
// In state WAIT_DHCP, if the DHCP query finishes and has no URL, it
// moves to state FINISH. If there is a URL, it starts a
- // ProxyScriptFetcher to fetch it and moves to state WAIT_URL.
+ // PacFileFetcher to fetch it and moves to state WAIT_URL.
//
- // It goes from WAIT_URL->FINISH when the ProxyScriptFetcher completes.
+ // It goes from WAIT_URL->FINISH when the PacFileFetcher completes.
//
// In state FINISH, completion is indicated to the outer class, with
// the results of the fetch if a PAC script was successfully fetched.
@@ -146,13 +148,14 @@ class NET_EXPORT_PRIVATE DhcpProxyScriptAdapterFetcher
};
// Virtual methods introduced to allow unit testing.
- virtual ProxyScriptFetcher* ImplCreateScriptFetcher();
+ virtual PacFileFetcher* ImplCreateScriptFetcher();
virtual DhcpQuery* ImplCreateDhcpQuery();
virtual base::TimeDelta ImplGetTimeout() const;
private:
// Event/state transition handlers
- void OnDhcpQueryDone(scoped_refptr<DhcpQuery> dhcp_query);
+ void OnDhcpQueryDone(scoped_refptr<DhcpQuery> dhcp_query,
+ const NetworkTrafficAnnotationTag traffic_annotation);
void OnTimeout();
void OnFetcherDone(int result);
void TransitionToFinish();
@@ -177,7 +180,7 @@ class NET_EXPORT_PRIVATE DhcpProxyScriptAdapterFetcher
CompletionCallback callback_;
// Fetcher to retrieve PAC files once URL is known.
- std::unique_ptr<ProxyScriptFetcher> script_fetcher_;
+ std::unique_ptr<PacFileFetcher> script_fetcher_;
// Implements a timeout on the call to the Win32 DHCP API.
base::OneShotTimer wait_timer_;
@@ -186,7 +189,7 @@ class NET_EXPORT_PRIVATE DhcpProxyScriptAdapterFetcher
THREAD_CHECKER(thread_checker_);
- DISALLOW_IMPLICIT_CONSTRUCTORS(DhcpProxyScriptAdapterFetcher);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(DhcpPacFileAdapterFetcher);
};
} // namespace net
diff --git a/chromium/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win_unittest.cc b/chromium/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win_unittest.cc
index 0093b7787c2..ac977008fa9 100644
--- a/chromium/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win_unittest.cc
+++ b/chromium/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win_unittest.cc
@@ -17,6 +17,7 @@
#include "net/proxy_resolution/pac_file_fetcher_impl.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -30,41 +31,39 @@ namespace {
const char kPacUrl[] = "http://pacserver/script.pac";
-// In net/proxy_resolution/dhcp_proxy_script_fetcher_win_unittest.cc there are
-// a few tests that exercise DhcpProxyScriptAdapterFetcher end-to-end along with
-// DhcpProxyScriptFetcherWin, i.e. it tests the end-to-end usage of Win32 APIs
+// In net/proxy_resolution/dhcp_pac_file_fetcher_win_unittest.cc there are
+// a few tests that exercise DhcpPacFileAdapterFetcher end-to-end along with
+// DhcpPacFileFetcherWin, i.e. it tests the end-to-end usage of Win32 APIs
// and the network. In this file we test only by stubbing out functionality.
-// Version of DhcpProxyScriptAdapterFetcher that mocks out dependencies
+// Version of DhcpPacFileAdapterFetcher that mocks out dependencies
// to allow unit testing.
-class MockDhcpProxyScriptAdapterFetcher
- : public DhcpProxyScriptAdapterFetcher {
+class MockDhcpPacFileAdapterFetcher : public DhcpPacFileAdapterFetcher {
public:
- explicit MockDhcpProxyScriptAdapterFetcher(
+ explicit MockDhcpPacFileAdapterFetcher(
URLRequestContext* context,
scoped_refptr<base::TaskRunner> task_runner)
- : DhcpProxyScriptAdapterFetcher(context, task_runner),
+ : DhcpPacFileAdapterFetcher(context, task_runner),
dhcp_delay_(base::TimeDelta::FromMilliseconds(1)),
timeout_(TestTimeouts::action_timeout()),
configured_url_(kPacUrl),
fetcher_delay_ms_(1),
fetcher_result_(OK),
- pac_script_("bingo") {
- }
+ pac_script_("bingo") {}
void Cancel() override {
- DhcpProxyScriptAdapterFetcher::Cancel();
+ DhcpPacFileAdapterFetcher::Cancel();
fetcher_ = NULL;
}
- ProxyScriptFetcher* ImplCreateScriptFetcher() override {
+ PacFileFetcher* ImplCreateScriptFetcher() override {
// We don't maintain ownership of the fetcher, it is transferred to
// the caller.
- fetcher_ = new MockProxyScriptFetcher();
+ fetcher_ = new MockPacFileFetcher();
if (fetcher_delay_ms_ != -1) {
- fetcher_timer_.Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(fetcher_delay_ms_),
- this, &MockDhcpProxyScriptAdapterFetcher::OnFetcherTimer);
+ fetcher_timer_.Start(
+ FROM_HERE, base::TimeDelta::FromMilliseconds(fetcher_delay_ms_), this,
+ &MockDhcpPacFileAdapterFetcher::OnFetcherTimer);
}
return fetcher_;
}
@@ -108,11 +107,11 @@ class MockDhcpProxyScriptAdapterFetcher
void OnFetcherTimer() {
// Note that there is an assumption by this mock implementation that
- // DhcpProxyScriptAdapterFetcher::Fetch will call ImplCreateScriptFetcher
+ // DhcpPacFileAdapterFetcher::Fetch will call ImplCreateScriptFetcher
// and call Fetch on the fetcher before the message loop is re-entered.
// This holds true today, but if you hit this DCHECK the problem can
// possibly be resolved by having a separate subclass of
- // MockProxyScriptFetcher that adds the delay internally (instead of
+ // MockPacFileFetcher that adds the delay internally (instead of
// the simple approach currently used in ImplCreateScriptFetcher above).
DCHECK(fetcher_ && fetcher_->has_pending_request());
fetcher_->NotifyFetchCompletion(fetcher_result_, pac_script_);
@@ -138,7 +137,7 @@ class MockDhcpProxyScriptAdapterFetcher
int fetcher_delay_ms_;
int fetcher_result_;
std::string pac_script_;
- MockProxyScriptFetcher* fetcher_;
+ MockPacFileFetcher* fetcher_;
base::OneShotTimer fetcher_timer_;
scoped_refptr<DelayingDhcpQuery> dhcp_query_;
};
@@ -147,7 +146,7 @@ class FetcherClient {
public:
FetcherClient()
: url_request_context_(new TestURLRequestContext()),
- fetcher_(new MockDhcpProxyScriptAdapterFetcher(
+ fetcher_(new MockDhcpPacFileAdapterFetcher(
url_request_context_.get(),
base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(),
@@ -158,7 +157,8 @@ class FetcherClient {
}
void RunTest() {
- fetcher_->Fetch("adapter name", callback_.callback());
+ fetcher_->Fetch("adapter name", callback_.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
}
void FinishTestAllowCleanup() {
@@ -168,11 +168,11 @@ class FetcherClient {
TestCompletionCallback callback_;
std::unique_ptr<URLRequestContext> url_request_context_;
- std::unique_ptr<MockDhcpProxyScriptAdapterFetcher> fetcher_;
+ std::unique_ptr<MockDhcpPacFileAdapterFetcher> fetcher_;
base::string16 pac_text_;
};
-TEST(DhcpProxyScriptAdapterFetcher, NormalCaseURLNotInDhcp) {
+TEST(DhcpPacFileAdapterFetcher, NormalCaseURLNotInDhcp) {
FetcherClient client;
client.fetcher_->configured_url_ = "";
client.RunTest();
@@ -182,7 +182,7 @@ TEST(DhcpProxyScriptAdapterFetcher, NormalCaseURLNotInDhcp) {
EXPECT_EQ(base::string16(L""), client.fetcher_->GetPacScript());
}
-TEST(DhcpProxyScriptAdapterFetcher, NormalCaseURLInDhcp) {
+TEST(DhcpPacFileAdapterFetcher, NormalCaseURLInDhcp) {
FetcherClient client;
client.RunTest();
client.WaitForResult(OK);
@@ -192,7 +192,7 @@ TEST(DhcpProxyScriptAdapterFetcher, NormalCaseURLInDhcp) {
EXPECT_EQ(GURL(kPacUrl), client.fetcher_->GetPacURL());
}
-TEST(DhcpProxyScriptAdapterFetcher, TimeoutDuringDhcp) {
+TEST(DhcpPacFileAdapterFetcher, TimeoutDuringDhcp) {
// Does a Fetch() with a long enough delay on accessing DHCP that the
// fetcher should time out. This is to test a case manual testing found,
// where under certain circumstances (e.g. adapter enabled for DHCP and
@@ -216,7 +216,7 @@ TEST(DhcpProxyScriptAdapterFetcher, TimeoutDuringDhcp) {
client.FinishTestAllowCleanup();
}
-TEST(DhcpProxyScriptAdapterFetcher, CancelWhileDhcp) {
+TEST(DhcpPacFileAdapterFetcher, CancelWhileDhcp) {
FetcherClient client;
client.RunTest();
client.fetcher_->Cancel();
@@ -229,7 +229,7 @@ TEST(DhcpProxyScriptAdapterFetcher, CancelWhileDhcp) {
client.FinishTestAllowCleanup();
}
-TEST(DhcpProxyScriptAdapterFetcher, CancelWhileFetcher) {
+TEST(DhcpPacFileAdapterFetcher, CancelWhileFetcher) {
FetcherClient client;
// This causes the mock fetcher not to pretend the
// fetcher finishes after a timeout.
@@ -251,7 +251,7 @@ TEST(DhcpProxyScriptAdapterFetcher, CancelWhileFetcher) {
client.FinishTestAllowCleanup();
}
-TEST(DhcpProxyScriptAdapterFetcher, CancelAtCompletion) {
+TEST(DhcpPacFileAdapterFetcher, CancelAtCompletion) {
FetcherClient client;
client.RunTest();
client.WaitForResult(OK);
@@ -266,37 +266,35 @@ TEST(DhcpProxyScriptAdapterFetcher, CancelAtCompletion) {
}
// Does a real fetch on a mock DHCP configuration.
-class MockDhcpRealFetchProxyScriptAdapterFetcher
- : public MockDhcpProxyScriptAdapterFetcher {
+class MockDhcpRealFetchPacFileAdapterFetcher
+ : public MockDhcpPacFileAdapterFetcher {
public:
- explicit MockDhcpRealFetchProxyScriptAdapterFetcher(
+ explicit MockDhcpRealFetchPacFileAdapterFetcher(
URLRequestContext* context,
scoped_refptr<base::TaskRunner> task_runner)
- : MockDhcpProxyScriptAdapterFetcher(context, task_runner),
- url_request_context_(context) {
- }
+ : MockDhcpPacFileAdapterFetcher(context, task_runner),
+ url_request_context_(context) {}
- // Returns a real proxy script fetcher.
- ProxyScriptFetcher* ImplCreateScriptFetcher() override {
- ProxyScriptFetcher* fetcher =
- new ProxyScriptFetcherImpl(url_request_context_);
+ // Returns a real PAC file fetcher.
+ PacFileFetcher* ImplCreateScriptFetcher() override {
+ PacFileFetcher* fetcher = new PacFileFetcherImpl(url_request_context_);
return fetcher;
}
URLRequestContext* url_request_context_;
};
-TEST(DhcpProxyScriptAdapterFetcher, MockDhcpRealFetch) {
+TEST(DhcpPacFileAdapterFetcher, MockDhcpRealFetch) {
EmbeddedTestServer test_server;
test_server.ServeFilesFromSourceDirectory(
- "net/data/proxy_script_fetcher_unittest");
+ "net/data/pac_file_fetcher_unittest");
ASSERT_TRUE(test_server.Start());
GURL configured_url = test_server.GetURL("/downloadable.pac");
FetcherClient client;
TestURLRequestContext url_request_context;
- client.fetcher_.reset(new MockDhcpRealFetchProxyScriptAdapterFetcher(
+ client.fetcher_.reset(new MockDhcpRealFetchPacFileAdapterFetcher(
&url_request_context,
base::CreateTaskRunnerWithTraits(
{base::MayBlock(),
@@ -314,23 +312,20 @@ TEST(DhcpProxyScriptAdapterFetcher, MockDhcpRealFetch) {
#define BASE_URL "http://corpserver/proxy.pac"
-TEST(DhcpProxyScriptAdapterFetcher, SanitizeDhcpApiString) {
+TEST(DhcpPacFileAdapterFetcher, SanitizeDhcpApiString) {
const size_t kBaseUrlLen = strlen(BASE_URL);
// Default case.
- EXPECT_EQ(BASE_URL,
- DhcpProxyScriptAdapterFetcher::SanitizeDhcpApiString(
- BASE_URL, kBaseUrlLen));
+ EXPECT_EQ(BASE_URL, DhcpPacFileAdapterFetcher::SanitizeDhcpApiString(
+ BASE_URL, kBaseUrlLen));
// Trailing \n and no null-termination.
- EXPECT_EQ(BASE_URL,
- DhcpProxyScriptAdapterFetcher::SanitizeDhcpApiString(
- BASE_URL "\nblablabla", kBaseUrlLen + 1));
+ EXPECT_EQ(BASE_URL, DhcpPacFileAdapterFetcher::SanitizeDhcpApiString(
+ BASE_URL "\nblablabla", kBaseUrlLen + 1));
// Embedded NULLs.
- EXPECT_EQ(BASE_URL,
- DhcpProxyScriptAdapterFetcher::SanitizeDhcpApiString(
- BASE_URL "\0foo\0blat", kBaseUrlLen + 9));
+ EXPECT_EQ(BASE_URL, DhcpPacFileAdapterFetcher::SanitizeDhcpApiString(
+ BASE_URL "\0foo\0blat", kBaseUrlLen + 9));
}
#undef BASE_URL
diff --git a/chromium/net/proxy_resolution/dhcp_pac_file_fetcher.cc b/chromium/net/proxy_resolution/dhcp_pac_file_fetcher.cc
index eda798dedcb..0814f9617ab 100644
--- a/chromium/net/proxy_resolution/dhcp_pac_file_fetcher.cc
+++ b/chromium/net/proxy_resolution/dhcp_pac_file_fetcher.cc
@@ -8,32 +8,35 @@
namespace net {
-std::string DhcpProxyScriptFetcher::GetFetcherName() const {
+std::string DhcpPacFileFetcher::GetFetcherName() const {
return std::string();
}
-DhcpProxyScriptFetcher::DhcpProxyScriptFetcher() = default;
+DhcpPacFileFetcher::DhcpPacFileFetcher() = default;
-DhcpProxyScriptFetcher::~DhcpProxyScriptFetcher() = default;
+DhcpPacFileFetcher::~DhcpPacFileFetcher() = default;
-DoNothingDhcpProxyScriptFetcher::DoNothingDhcpProxyScriptFetcher() = default;
+DoNothingDhcpPacFileFetcher::DoNothingDhcpPacFileFetcher() = default;
-DoNothingDhcpProxyScriptFetcher::~DoNothingDhcpProxyScriptFetcher() = default;
+DoNothingDhcpPacFileFetcher::~DoNothingDhcpPacFileFetcher() = default;
-int DoNothingDhcpProxyScriptFetcher::Fetch(
- base::string16* utf16_text, const CompletionCallback& callback) {
+int DoNothingDhcpPacFileFetcher::Fetch(
+ base::string16* utf16_text,
+ const CompletionCallback& callback,
+ const NetLogWithSource& net_log,
+ const NetworkTrafficAnnotationTag traffic_annotation) {
return ERR_NOT_IMPLEMENTED;
}
-void DoNothingDhcpProxyScriptFetcher::Cancel() {}
+void DoNothingDhcpPacFileFetcher::Cancel() {}
-void DoNothingDhcpProxyScriptFetcher::OnShutdown() {}
+void DoNothingDhcpPacFileFetcher::OnShutdown() {}
-const GURL& DoNothingDhcpProxyScriptFetcher::GetPacURL() const {
+const GURL& DoNothingDhcpPacFileFetcher::GetPacURL() const {
return gurl_;
}
-std::string DoNothingDhcpProxyScriptFetcher::GetFetcherName() const {
+std::string DoNothingDhcpPacFileFetcher::GetFetcherName() const {
return "do nothing";
}
diff --git a/chromium/net/proxy_resolution/dhcp_pac_file_fetcher.h b/chromium/net/proxy_resolution/dhcp_pac_file_fetcher.h
index afd9793e28f..f5f93304400 100644
--- a/chromium/net/proxy_resolution/dhcp_pac_file_fetcher.h
+++ b/chromium/net/proxy_resolution/dhcp_pac_file_fetcher.h
@@ -11,11 +11,14 @@
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
#include "net/proxy_resolution/pac_file_fetcher.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"
namespace net {
-// Interface for classes that can fetch a proxy script as configured via DHCP.
+class NetLogWithSource;
+
+// Interface for classes that can fetch a PAC file as configured via DHCP.
//
// The Fetch method on this interface tries to retrieve the most appropriate
// PAC script configured via DHCP.
@@ -23,10 +26,10 @@ namespace net {
// Normally there are zero or one DHCP scripts configured, but in the
// presence of multiple adapters with DHCP enabled, the fetcher resolves
// which PAC script to use if one or more are available.
-class NET_EXPORT_PRIVATE DhcpProxyScriptFetcher {
+class NET_EXPORT_PRIVATE DhcpPacFileFetcher {
public:
// Destruction should cancel any outstanding requests.
- virtual ~DhcpProxyScriptFetcher();
+ virtual ~DhcpPacFileFetcher();
// Attempts to retrieve the most appropriate PAC script configured via DHCP,
// and invokes |callback| on completion.
@@ -57,7 +60,9 @@ class NET_EXPORT_PRIVATE DhcpProxyScriptFetcher {
//
// Only one fetch is allowed to be outstanding at a time.
virtual int Fetch(base::string16* utf16_text,
- const CompletionCallback& callback) = 0;
+ const CompletionCallback& callback,
+ const NetLogWithSource& net_log,
+ const NetworkTrafficAnnotationTag traffic_annotation) = 0;
// Aborts the in-progress fetch (if any).
virtual void Cancel() = 0;
@@ -76,22 +81,24 @@ class NET_EXPORT_PRIVATE DhcpProxyScriptFetcher {
virtual std::string GetFetcherName() const;
protected:
- DhcpProxyScriptFetcher();
+ DhcpPacFileFetcher();
private:
- DISALLOW_COPY_AND_ASSIGN(DhcpProxyScriptFetcher);
+ DISALLOW_COPY_AND_ASSIGN(DhcpPacFileFetcher);
};
// A do-nothing retriever, always returns synchronously with
// ERR_NOT_IMPLEMENTED result and empty text.
-class NET_EXPORT_PRIVATE DoNothingDhcpProxyScriptFetcher
- : public DhcpProxyScriptFetcher {
+class NET_EXPORT_PRIVATE DoNothingDhcpPacFileFetcher
+ : public DhcpPacFileFetcher {
public:
- DoNothingDhcpProxyScriptFetcher();
- ~DoNothingDhcpProxyScriptFetcher() override;
+ DoNothingDhcpPacFileFetcher();
+ ~DoNothingDhcpPacFileFetcher() override;
int Fetch(base::string16* utf16_text,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetLogWithSource& net_log,
+ const NetworkTrafficAnnotationTag traffic_annotation) override;
void Cancel() override;
void OnShutdown() override;
const GURL& GetPacURL() const override;
@@ -99,7 +106,7 @@ class NET_EXPORT_PRIVATE DoNothingDhcpProxyScriptFetcher
private:
GURL gurl_;
- DISALLOW_COPY_AND_ASSIGN(DoNothingDhcpProxyScriptFetcher);
+ DISALLOW_COPY_AND_ASSIGN(DoNothingDhcpPacFileFetcher);
};
} // namespace net
diff --git a/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_factory.cc b/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_factory.cc
index 255e013ca53..7b3f96b4050 100644
--- a/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_factory.cc
+++ b/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_factory.cc
@@ -13,16 +13,16 @@
namespace net {
-DhcpProxyScriptFetcherFactory::DhcpProxyScriptFetcherFactory() = default;
+DhcpPacFileFetcherFactory::DhcpPacFileFetcherFactory() = default;
-DhcpProxyScriptFetcherFactory::~DhcpProxyScriptFetcherFactory() = default;
+DhcpPacFileFetcherFactory::~DhcpPacFileFetcherFactory() = default;
-std::unique_ptr<DhcpProxyScriptFetcher> DhcpProxyScriptFetcherFactory::Create(
+std::unique_ptr<DhcpPacFileFetcher> DhcpPacFileFetcherFactory::Create(
URLRequestContext* context) {
#if defined(OS_WIN)
- return std::make_unique<DhcpProxyScriptFetcherWin>(context);
+ return std::make_unique<DhcpPacFileFetcherWin>(context);
#else
- return std::make_unique<DoNothingDhcpProxyScriptFetcher>();
+ return std::make_unique<DoNothingDhcpPacFileFetcher>();
#endif
}
diff --git a/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_factory.h b/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_factory.h
index ab62b6b8670..cf520a99d13 100644
--- a/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_factory.h
+++ b/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_factory.h
@@ -18,7 +18,7 @@ namespace net {
class URLRequestContext;
// Factory object for creating the appropriate concrete base class of
-// DhcpProxyScriptFetcher for your operating system and settings.
+// DhcpPacFileFetcher for your operating system and settings.
//
// You might think we could just implement a DHCP client at the protocol
// level and have cross-platform support for retrieving PAC configuration
@@ -31,24 +31,24 @@ class URLRequestContext;
//
// Therefore, we have platform-specific implementations, and so we use
// this factory to select the right one.
-class NET_EXPORT DhcpProxyScriptFetcherFactory {
+class NET_EXPORT DhcpPacFileFetcherFactory {
public:
- DhcpProxyScriptFetcherFactory();
+ DhcpPacFileFetcherFactory();
- virtual ~DhcpProxyScriptFetcherFactory();
+ virtual ~DhcpPacFileFetcherFactory();
// url_request_context must be valid and its lifetime must exceed that of the
- // returned DhcpProxyScriptFetcher.
+ // returned DhcpPacFileFetcher.
//
// Note that while a request is in progress, the fetcher may be holding a
// reference to |url_request_context|. Be careful not to create cycles
// between the fetcher and the context; you can break such cycles by calling
// Cancel().
- virtual std::unique_ptr<DhcpProxyScriptFetcher> Create(
+ virtual std::unique_ptr<DhcpPacFileFetcher> Create(
URLRequestContext* url_request_context);
private:
- DISALLOW_COPY_AND_ASSIGN(DhcpProxyScriptFetcherFactory);
+ DISALLOW_COPY_AND_ASSIGN(DhcpPacFileFetcherFactory);
};
} // namespace net
diff --git a/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_factory_unittest.cc b/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_factory_unittest.cc
index c8e73d3b360..4eb52a062bd 100644
--- a/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_factory_unittest.cc
+++ b/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_factory_unittest.cc
@@ -11,20 +11,20 @@ namespace net {
namespace {
#if defined(OS_WIN)
-TEST(DhcpProxyScriptFetcherFactoryTest, WindowsFetcherOnWindows) {
- DhcpProxyScriptFetcherFactory factory;
+TEST(DhcpPacFileFetcherFactoryTest, WindowsFetcherOnWindows) {
+ DhcpPacFileFetcherFactory factory;
TestURLRequestContext context;
- std::unique_ptr<DhcpProxyScriptFetcher> fetcher(factory.Create(&context));
+ std::unique_ptr<DhcpPacFileFetcher> fetcher(factory.Create(&context));
ASSERT_TRUE(fetcher.get());
EXPECT_EQ("win", fetcher->GetFetcherName());
}
#else // !defined(OS_WIN)
-TEST(DhcpProxyScriptFetcherFactoryTest, ReturnNullOnUnsupportedPlatforms) {
- DhcpProxyScriptFetcherFactory factory;
+TEST(DhcpPacFileFetcherFactoryTest, ReturnNullOnUnsupportedPlatforms) {
+ DhcpPacFileFetcherFactory factory;
TestURLRequestContext context;
- std::unique_ptr<DhcpProxyScriptFetcher> fetcher(factory.Create(&context));
+ std::unique_ptr<DhcpPacFileFetcher> fetcher(factory.Create(&context));
ASSERT_TRUE(fetcher.get());
EXPECT_EQ("do nothing", fetcher->GetFetcherName());
}
diff --git a/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_win.cc b/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_win.cc
index f80f9ef1450..d8440cabdee 100644
--- a/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_win.cc
+++ b/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_win.cc
@@ -15,12 +15,74 @@
#include "base/task_runner.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/scoped_blocking_call.h"
+#include "base/values.h"
#include "net/base/net_errors.h"
+#include "net/log/net_log.h"
#include "net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.h"
#include <winsock2.h>
#include <iphlpapi.h>
+namespace net {
+
+namespace {
+
+// Returns true if |adapter| should be considered when probing for WPAD via
+// DHCP.
+bool IsDhcpCapableAdapter(IP_ADAPTER_ADDRESSES* adapter) {
+ if (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK)
+ return false;
+ if ((adapter->Flags & IP_ADAPTER_DHCP_ENABLED) == 0)
+ return false;
+
+ // Don't probe interfaces which are not up and ready to pass packets.
+ //
+ // This is a speculative fix for https://crbug.com/770201, in case calling
+ // dhcpsvc!DhcpRequestParams on interfaces that aren't ready yet blocks for
+ // a long time.
+ //
+ // Since ProxyResolutionService restarts WPAD probes in response to other
+ // network level changes, this will likely get called again once the
+ // interface is up.
+ if (adapter->OperStatus != IfOperStatusUp)
+ return false;
+
+ return true;
+}
+
+} // namespace
+
+// This struct contains logging information describing how
+// GetCandidateAdapterNames() performed, for output to NetLog.
+struct DhcpAdapterNamesLoggingInfo {
+ DhcpAdapterNamesLoggingInfo() = default;
+ ~DhcpAdapterNamesLoggingInfo() = default;
+
+ // The error that iphlpapi!GetAdaptersAddresses returned.
+ ULONG error;
+
+ // The adapters list that iphlpapi!GetAdaptersAddresses returned.
+ std::unique_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> adapters;
+
+ // The time immediately before GetCandidateAdapterNames was posted to a worker
+ // thread from the origin thread.
+ base::TimeTicks origin_thread_start_time;
+
+ // The time when GetCandidateAdapterNames began running on the worker thread.
+ base::TimeTicks worker_thread_start_time;
+
+ // The time when GetCandidateAdapterNames completed running on the worker
+ // thread.
+ base::TimeTicks worker_thread_end_time;
+
+ // The time when control returned to the origin thread
+ // (OnGetCandidateAdapterNamesDone)
+ base::TimeTicks origin_thread_end_time;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DhcpAdapterNamesLoggingInfo);
+};
+
namespace {
// Maximum number of DHCP lookup tasks running concurrently. This is chosen
@@ -140,11 +202,76 @@ class TaskRunnerWithCap : public base::TaskRunner {
DISALLOW_COPY_AND_ASSIGN(TaskRunnerWithCap);
};
-} // namespace
+// Helper to set an integer value into a base::DictionaryValue. Because of
+// C++'s implicit narrowing casts to |int|, this can be called with int64_t and
+// ULONG too.
+void SetInt(base::StringPiece key, int value, base::DictionaryValue* dict) {
+ dict->SetKey(key, base::Value(value));
+}
-namespace net {
+std::unique_ptr<base::Value> NetLogGetAdaptersDoneCallback(
+ DhcpAdapterNamesLoggingInfo* info,
+ NetLogCaptureMode /* capture_mode */) {
+ std::unique_ptr<base::DictionaryValue> result =
+ std::make_unique<base::DictionaryValue>();
+
+ // Add information on each of the adapters enumerated (including those that
+ // were subsequently skipped).
+ base::ListValue adapters_value;
+ for (IP_ADAPTER_ADDRESSES* adapter = info->adapters.get(); adapter;
+ adapter = adapter->Next) {
+ base::DictionaryValue adapter_value;
+
+ adapter_value.SetKey("AdapterName", base::Value(adapter->AdapterName));
+ SetInt("IfType", adapter->IfType, &adapter_value);
+ SetInt("Flags", adapter->Flags, &adapter_value);
+ SetInt("OperStatus", adapter->OperStatus, &adapter_value);
+ SetInt("TunnelType", adapter->TunnelType, &adapter_value);
+
+ // "skipped" means the adapter was not ultimately chosen as a candidate for
+ // testing WPAD.
+ bool skipped = !IsDhcpCapableAdapter(adapter);
+ adapter_value.SetKey("skipped", base::Value(skipped));
+
+ adapters_value.GetList().push_back(std::move(adapter_value));
+ }
+ result->SetKey("adapters", std::move(adapters_value));
+
+ SetInt("origin_to_worker_thread_hop_dt",
+ (info->worker_thread_start_time - info->origin_thread_start_time)
+ .InMilliseconds(),
+ result.get());
+ SetInt("worker_to_origin_thread_hop_dt",
+ (info->origin_thread_end_time - info->worker_thread_end_time)
+ .InMilliseconds(),
+ result.get());
+ SetInt("worker_dt",
+ (info->worker_thread_end_time - info->worker_thread_start_time)
+ .InMilliseconds(),
+ result.get());
+
+ if (info->error != ERROR_SUCCESS)
+ SetInt("error", info->error, result.get());
+
+ return result;
+}
+
+std::unique_ptr<base::Value> NetLogFetcherDoneCallback(
+ int fetcher_index,
+ int net_error,
+ NetLogCaptureMode /* capture_mode */) {
+ std::unique_ptr<base::DictionaryValue> result =
+ std::make_unique<base::DictionaryValue>();
+
+ result->SetKey("fetcher_index", base::Value(fetcher_index));
+ result->SetKey("net_error", base::Value(net_error));
+
+ return result;
+}
+
+} // namespace
-DhcpProxyScriptFetcherWin::DhcpProxyScriptFetcherWin(
+DhcpPacFileFetcherWin::DhcpPacFileFetcherWin(
URLRequestContext* url_request_context)
: state_(STATE_START),
num_pending_fetchers_(0),
@@ -154,20 +281,25 @@ DhcpProxyScriptFetcherWin::DhcpProxyScriptFetcherWin(
DCHECK(url_request_context_);
}
-DhcpProxyScriptFetcherWin::~DhcpProxyScriptFetcherWin() {
+DhcpPacFileFetcherWin::~DhcpPacFileFetcherWin() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Count as user-initiated if we are not yet in STATE_DONE.
Cancel();
}
-int DhcpProxyScriptFetcherWin::Fetch(base::string16* utf16_text,
- const CompletionCallback& callback) {
+int DhcpPacFileFetcherWin::Fetch(
+ base::string16* utf16_text,
+ const CompletionCallback& callback,
+ const NetLogWithSource& net_log,
+ const NetworkTrafficAnnotationTag traffic_annotation) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (state_ != STATE_START && state_ != STATE_DONE) {
NOTREACHED();
return ERR_UNEXPECTED;
}
+ net_log_ = net_log;
+
if (!url_request_context_)
return ERR_CONTEXT_SHUT_DOWN;
@@ -175,25 +307,32 @@ int DhcpProxyScriptFetcherWin::Fetch(base::string16* utf16_text,
callback_ = callback;
destination_string_ = utf16_text;
+ net_log.BeginEvent(NetLogEventType::WPAD_DHCP_WIN_FETCH);
+
+ // TODO(eroman): This event is not ended in the case of cancellation.
+ net_log.BeginEvent(NetLogEventType::WPAD_DHCP_WIN_GET_ADAPTERS);
+
last_query_ = ImplCreateAdapterQuery();
+ last_query_->logging_info()->origin_thread_start_time =
+ base::TimeTicks::Now();
+
task_runner_->PostTaskAndReply(
FROM_HERE,
- base::Bind(
- &DhcpProxyScriptFetcherWin::AdapterQuery::GetCandidateAdapterNames,
- last_query_.get()),
- base::Bind(&DhcpProxyScriptFetcherWin::OnGetCandidateAdapterNamesDone,
- AsWeakPtr(), last_query_));
+ base::Bind(&DhcpPacFileFetcherWin::AdapterQuery::GetCandidateAdapterNames,
+ last_query_.get()),
+ base::Bind(&DhcpPacFileFetcherWin::OnGetCandidateAdapterNamesDone,
+ AsWeakPtr(), last_query_, traffic_annotation));
return ERR_IO_PENDING;
}
-void DhcpProxyScriptFetcherWin::Cancel() {
+void DhcpPacFileFetcherWin::Cancel() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
CancelImpl();
}
-void DhcpProxyScriptFetcherWin::OnShutdown() {
+void DhcpPacFileFetcherWin::OnShutdown() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Back up callback, if there is one, as CancelImpl() will destroy it.
@@ -210,7 +349,7 @@ void DhcpProxyScriptFetcherWin::OnShutdown() {
callback.Run(ERR_CONTEXT_SHUT_DOWN);
}
-void DhcpProxyScriptFetcherWin::CancelImpl() {
+void DhcpPacFileFetcherWin::CancelImpl() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (state_ != STATE_DONE) {
@@ -228,8 +367,9 @@ void DhcpProxyScriptFetcherWin::CancelImpl() {
}
}
-void DhcpProxyScriptFetcherWin::OnGetCandidateAdapterNamesDone(
- scoped_refptr<AdapterQuery> query) {
+void DhcpPacFileFetcherWin::OnGetCandidateAdapterNamesDone(
+ scoped_refptr<AdapterQuery> query,
+ const NetworkTrafficAnnotationTag traffic_annotation) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// This can happen if this object is reused for multiple queries,
@@ -238,6 +378,13 @@ void DhcpProxyScriptFetcherWin::OnGetCandidateAdapterNamesDone(
return;
last_query_ = NULL;
+ DhcpAdapterNamesLoggingInfo* logging_info = query->logging_info();
+ logging_info->origin_thread_end_time = base::TimeTicks::Now();
+
+ net_log_.EndEvent(NetLogEventType::WPAD_DHCP_WIN_GET_ADAPTERS,
+ base::Bind(&NetLogGetAdaptersDoneCallback,
+ base::Unretained(logging_info)));
+
// Enable unit tests to wait for this to happen; in production this function
// call is a no-op.
ImplOnGetCandidateAdapterNamesDone();
@@ -255,34 +402,39 @@ void DhcpProxyScriptFetcherWin::OnGetCandidateAdapterNamesDone(
return;
}
- for (std::set<std::string>::const_iterator it = adapter_names.begin();
- it != adapter_names.end();
- ++it) {
- std::unique_ptr<DhcpProxyScriptAdapterFetcher> fetcher(
+ for (const std::string& adapter_name : adapter_names) {
+ std::unique_ptr<DhcpPacFileAdapterFetcher> fetcher(
ImplCreateAdapterFetcher());
- fetcher->Fetch(
- *it, base::Bind(&DhcpProxyScriptFetcherWin::OnFetcherDone,
- base::Unretained(this)));
+ size_t fetcher_index = fetchers_.size();
+ fetcher->Fetch(adapter_name,
+ base::Bind(&DhcpPacFileFetcherWin::OnFetcherDone,
+ base::Unretained(this), fetcher_index),
+ traffic_annotation);
fetchers_.push_back(std::move(fetcher));
}
num_pending_fetchers_ = fetchers_.size();
}
-std::string DhcpProxyScriptFetcherWin::GetFetcherName() const {
+std::string DhcpPacFileFetcherWin::GetFetcherName() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return "win";
}
-const GURL& DhcpProxyScriptFetcherWin::GetPacURL() const {
+const GURL& DhcpPacFileFetcherWin::GetPacURL() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK_EQ(state_, STATE_DONE);
return pac_url_;
}
-void DhcpProxyScriptFetcherWin::OnFetcherDone(int result) {
+void DhcpPacFileFetcherWin::OnFetcherDone(size_t fetcher_index,
+ int result) {
DCHECK(state_ == STATE_NO_RESULTS || state_ == STATE_SOME_RESULTS);
+ net_log_.AddEvent(
+ NetLogEventType::WPAD_DHCP_WIN_ON_FETCHER_DONE,
+ base::Bind(&NetLogFetcherDoneCallback, fetcher_index, result));
+
if (--num_pending_fetchers_ == 0) {
TransitionToDone();
return;
@@ -308,20 +460,23 @@ void DhcpProxyScriptFetcherWin::OnFetcherDone(int result) {
// for the rest of the results.
if (state_ == STATE_NO_RESULTS) {
state_ = STATE_SOME_RESULTS;
+ net_log_.AddEvent(NetLogEventType::WPAD_DHCP_WIN_START_WAIT_TIMER);
wait_timer_.Start(FROM_HERE,
- ImplGetMaxWait(), this, &DhcpProxyScriptFetcherWin::OnWaitTimer);
+ ImplGetMaxWait(), this, &DhcpPacFileFetcherWin::OnWaitTimer);
}
}
-void DhcpProxyScriptFetcherWin::OnWaitTimer() {
+void DhcpPacFileFetcherWin::OnWaitTimer() {
DCHECK_EQ(state_, STATE_SOME_RESULTS);
+ net_log_.AddEvent(NetLogEventType::WPAD_DHCP_WIN_ON_WAIT_TIMER);
TransitionToDone();
}
-void DhcpProxyScriptFetcherWin::TransitionToDone() {
+void DhcpPacFileFetcherWin::TransitionToDone() {
DCHECK(state_ == STATE_NO_RESULTS || state_ == STATE_SOME_RESULTS);
+ int used_fetcher_index = -1;
int result = ERR_PAC_NOT_IN_DHCP; // Default if no fetchers.
if (!fetchers_.empty()) {
// Scan twice for the result; once through the whole list for success,
@@ -329,23 +484,23 @@ void DhcpProxyScriptFetcherWin::TransitionToDone() {
// preferring "real" network errors to the ERR_PAC_NOT_IN_DHCP error.
// Default to ERR_ABORTED if no fetcher completed.
result = ERR_ABORTED;
- for (FetcherVector::iterator it = fetchers_.begin();
- it != fetchers_.end();
- ++it) {
- if ((*it)->DidFinish() && (*it)->GetResult() == OK) {
+ for (size_t i = 0; i < fetchers_.size(); ++i) {
+ const auto& fetcher = fetchers_[i];
+ if (fetcher->DidFinish() && fetcher->GetResult() == OK) {
result = OK;
- *destination_string_ = (*it)->GetPacScript();
- pac_url_ = (*it)->GetPacURL();
+ *destination_string_ = fetcher->GetPacScript();
+ pac_url_ = fetcher->GetPacURL();
+ used_fetcher_index = i;
break;
}
}
if (result != OK) {
destination_string_->clear();
- for (FetcherVector::iterator it = fetchers_.begin();
- it != fetchers_.end();
- ++it) {
- if ((*it)->DidFinish()) {
- result = (*it)->GetResult();
+ for (size_t i = 0; i < fetchers_.size(); ++i) {
+ const auto& fetcher = fetchers_[i];
+ if (fetcher->DidFinish()) {
+ result = fetcher->GetResult();
+ used_fetcher_index = i;
if (result != ERR_PAC_NOT_IN_DHCP) {
break;
}
@@ -360,38 +515,42 @@ void DhcpProxyScriptFetcherWin::TransitionToDone() {
DCHECK(fetchers_.empty());
DCHECK(callback_.is_null()); // Invariant of data.
+ net_log_.EndEvent(
+ NetLogEventType::WPAD_DHCP_WIN_FETCH,
+ base::Bind(&NetLogFetcherDoneCallback, used_fetcher_index, result));
+
// We may be deleted re-entrantly within this outcall.
callback.Run(result);
}
-int DhcpProxyScriptFetcherWin::num_pending_fetchers() const {
+int DhcpPacFileFetcherWin::num_pending_fetchers() const {
return num_pending_fetchers_;
}
-URLRequestContext* DhcpProxyScriptFetcherWin::url_request_context() const {
+URLRequestContext* DhcpPacFileFetcherWin::url_request_context() const {
return url_request_context_;
}
-scoped_refptr<base::TaskRunner> DhcpProxyScriptFetcherWin::GetTaskRunner() {
+scoped_refptr<base::TaskRunner> DhcpPacFileFetcherWin::GetTaskRunner() {
return task_runner_;
}
-DhcpProxyScriptAdapterFetcher*
- DhcpProxyScriptFetcherWin::ImplCreateAdapterFetcher() {
- return new DhcpProxyScriptAdapterFetcher(url_request_context_, task_runner_);
+DhcpPacFileAdapterFetcher* DhcpPacFileFetcherWin::ImplCreateAdapterFetcher() {
+ return new DhcpPacFileAdapterFetcher(url_request_context_, task_runner_);
}
-DhcpProxyScriptFetcherWin::AdapterQuery*
- DhcpProxyScriptFetcherWin::ImplCreateAdapterQuery() {
+DhcpPacFileFetcherWin::AdapterQuery*
+DhcpPacFileFetcherWin::ImplCreateAdapterQuery() {
return new AdapterQuery();
}
-base::TimeDelta DhcpProxyScriptFetcherWin::ImplGetMaxWait() {
+base::TimeDelta DhcpPacFileFetcherWin::ImplGetMaxWait() {
return kMaxWaitAfterFirstResult;
}
-bool DhcpProxyScriptFetcherWin::GetCandidateAdapterNames(
- std::set<std::string>* adapter_names) {
+bool DhcpPacFileFetcherWin::GetCandidateAdapterNames(
+ std::set<std::string>* adapter_names,
+ DhcpAdapterNamesLoggingInfo* info) {
DCHECK(adapter_names);
adapter_names->clear();
@@ -418,6 +577,9 @@ bool DhcpProxyScriptFetcherWin::GetCandidateAdapterNames(
++num_tries;
} while (error == ERROR_BUFFER_OVERFLOW && num_tries <= 3);
+ if (info)
+ info->error = error;
+
if (error == ERROR_NO_DATA) {
// There are no adapters that we care about.
return true;
@@ -430,36 +592,44 @@ bool DhcpProxyScriptFetcherWin::GetCandidateAdapterNames(
IP_ADAPTER_ADDRESSES* adapter = NULL;
for (adapter = adapters.get(); adapter; adapter = adapter->Next) {
- if (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK)
- continue;
- if ((adapter->Flags & IP_ADAPTER_DHCP_ENABLED) == 0)
- continue;
-
- DCHECK(adapter->AdapterName);
- adapter_names->insert(adapter->AdapterName);
+ if (IsDhcpCapableAdapter(adapter)) {
+ DCHECK(adapter->AdapterName);
+ adapter_names->insert(adapter->AdapterName);
+ }
}
+ // Transfer the buffer containing the adapters, so it can be used later for
+ // emitting NetLog parameters from the origin thread.
+ if (info)
+ info->adapters = std::move(adapters);
return true;
}
-DhcpProxyScriptFetcherWin::AdapterQuery::AdapterQuery() {
-}
+DhcpPacFileFetcherWin::AdapterQuery::AdapterQuery()
+ : logging_info_(new DhcpAdapterNamesLoggingInfo()) {}
-void DhcpProxyScriptFetcherWin::AdapterQuery::GetCandidateAdapterNames() {
- ImplGetCandidateAdapterNames(&adapter_names_);
+void DhcpPacFileFetcherWin::AdapterQuery::GetCandidateAdapterNames() {
+ logging_info_->error = ERROR_NO_DATA;
+ logging_info_->adapters.reset();
+ logging_info_->worker_thread_start_time = base::TimeTicks::Now();
+
+ ImplGetCandidateAdapterNames(&adapter_names_, logging_info_.get());
+
+ logging_info_->worker_thread_end_time = base::TimeTicks::Now();
}
const std::set<std::string>&
- DhcpProxyScriptFetcherWin::AdapterQuery::adapter_names() const {
+DhcpPacFileFetcherWin::AdapterQuery::adapter_names() const {
return adapter_names_;
}
-bool DhcpProxyScriptFetcherWin::AdapterQuery::ImplGetCandidateAdapterNames(
- std::set<std::string>* adapter_names) {
- return DhcpProxyScriptFetcherWin::GetCandidateAdapterNames(adapter_names);
+bool DhcpPacFileFetcherWin::AdapterQuery::ImplGetCandidateAdapterNames(
+ std::set<std::string>* adapter_names,
+ DhcpAdapterNamesLoggingInfo* info) {
+ return DhcpPacFileFetcherWin::GetCandidateAdapterNames(adapter_names,
+ info);
}
-DhcpProxyScriptFetcherWin::AdapterQuery::~AdapterQuery() {
-}
+DhcpPacFileFetcherWin::AdapterQuery::~AdapterQuery() {}
} // namespace net
diff --git a/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_win.h b/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_win.h
index 3cc16586f08..078b2dd9274 100644
--- a/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_win.h
+++ b/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_win.h
@@ -16,7 +16,9 @@
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/net_export.h"
+#include "net/log/net_log_with_source.h"
#include "net/proxy_resolution/dhcp_pac_file_fetcher.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace base {
class TaskRunner;
@@ -24,32 +26,37 @@ class TaskRunner;
namespace net {
-class DhcpProxyScriptAdapterFetcher;
+struct DhcpAdapterNamesLoggingInfo;
+class DhcpPacFileAdapterFetcher;
class URLRequestContext;
// Windows-specific implementation.
-class NET_EXPORT_PRIVATE DhcpProxyScriptFetcherWin
- : public DhcpProxyScriptFetcher,
- public base::SupportsWeakPtr<DhcpProxyScriptFetcherWin> {
+class NET_EXPORT_PRIVATE DhcpPacFileFetcherWin
+ : public DhcpPacFileFetcher,
+ public base::SupportsWeakPtr<DhcpPacFileFetcherWin> {
public:
- // Creates a DhcpProxyScriptFetcherWin that issues requests through
+ // Creates a DhcpPacFileFetcherWin that issues requests through
// |url_request_context|. |url_request_context| must remain valid for
- // the lifetime of DhcpProxyScriptFetcherWin.
- explicit DhcpProxyScriptFetcherWin(URLRequestContext* url_request_context);
- ~DhcpProxyScriptFetcherWin() override;
+ // the lifetime of DhcpPacFileFetcherWin.
+ explicit DhcpPacFileFetcherWin(URLRequestContext* url_request_context);
+ ~DhcpPacFileFetcherWin() override;
- // DhcpProxyScriptFetcher implementation.
+ // DhcpPacFileFetcher implementation.
int Fetch(base::string16* utf16_text,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetLogWithSource& net_log,
+ const NetworkTrafficAnnotationTag traffic_annotation) override;
void Cancel() override;
void OnShutdown() override;
const GURL& GetPacURL() const override;
std::string GetFetcherName() const override;
// Sets |adapter_names| to contain the name of each network adapter on
- // this machine that has DHCP enabled and is not a loop-back adapter. Returns
- // false on error.
- static bool GetCandidateAdapterNames(std::set<std::string>* adapter_names);
+ // this machine that has DHCP enabled and is not a loop-back adapter. May
+ // optionally update |info| (if non-null) with information for logging.
+ // Returns false on error.
+ static bool GetCandidateAdapterNames(std::set<std::string>* adapter_names,
+ DhcpAdapterNamesLoggingInfo* info);
protected:
int num_pending_fetchers() const;
@@ -73,25 +80,29 @@ class NET_EXPORT_PRIVATE DhcpProxyScriptFetcherWin
// been run. Its lifetime is scoped by this object.
const std::set<std::string>& adapter_names() const;
+ DhcpAdapterNamesLoggingInfo* logging_info() { return logging_info_.get(); }
+
protected:
// Virtual method introduced to allow unit testing.
virtual bool ImplGetCandidateAdapterNames(
- std::set<std::string>* adapter_names);
+ std::set<std::string>* adapter_names,
+ DhcpAdapterNamesLoggingInfo* info);
friend class base::RefCountedThreadSafe<AdapterQuery>;
virtual ~AdapterQuery();
private:
- // This is constructed on the originating thread, then used on the
+ // These are constructed on the originating thread, then used on the
// worker thread, then used again on the originating thread only when
// the task has completed on the worker thread. No locking required.
std::set<std::string> adapter_names_;
+ std::unique_ptr<DhcpAdapterNamesLoggingInfo> logging_info_;
DISALLOW_COPY_AND_ASSIGN(AdapterQuery);
};
// Virtual methods introduced to allow unit testing.
- virtual DhcpProxyScriptAdapterFetcher* ImplCreateAdapterFetcher();
+ virtual DhcpPacFileAdapterFetcher* ImplCreateAdapterFetcher();
virtual AdapterQuery* ImplCreateAdapterQuery();
virtual base::TimeDelta ImplGetMaxWait();
virtual void ImplOnGetCandidateAdapterNamesDone() {}
@@ -99,14 +110,16 @@ class NET_EXPORT_PRIVATE DhcpProxyScriptFetcherWin
private:
// Event/state transition handlers
void CancelImpl();
- void OnGetCandidateAdapterNamesDone(scoped_refptr<AdapterQuery> query);
- void OnFetcherDone(int result);
+ void OnGetCandidateAdapterNamesDone(
+ scoped_refptr<AdapterQuery> query,
+ const NetworkTrafficAnnotationTag traffic_annotation);
+ void OnFetcherDone(size_t fetcher_i, int result);
void OnWaitTimer();
void TransitionToDone();
// This is the outer state machine for fetching PAC configuration from
// DHCP. It relies for sub-states on the state machine of the
- // DhcpProxyScriptAdapterFetcher class.
+ // DhcpPacFileAdapterFetcher class.
//
// The goal of the implementation is to the following work in parallel
// for all network adapters that are using DHCP:
@@ -119,7 +132,7 @@ class NET_EXPORT_PRIVATE DhcpProxyScriptFetcherWin
// The state machine goes from START->WAIT_ADAPTERS when it starts a
// worker thread to get the list of adapters with DHCP enabled.
// It then goes from WAIT_ADAPTERS->NO_RESULTS when it creates
- // and starts an DhcpProxyScriptAdapterFetcher for each adapter. It goes
+ // and starts an DhcpPacFileAdapterFetcher for each adapter. It goes
// from NO_RESULTS->SOME_RESULTS when it gets the first result; at this
// point a wait timer is started. It goes from SOME_RESULTS->DONE in
// two cases: All results are known, or the wait timer expired. A call
@@ -139,22 +152,26 @@ class NET_EXPORT_PRIVATE DhcpProxyScriptFetcherWin
STATE_DONE,
};
- // Current state of this state machine.
- State state_;
-
// Vector, in Windows' network adapter preference order, of
- // DhcpProxyScriptAdapterFetcher objects that are or were attempting
+ // DhcpPacFileAdapterFetcher objects that are or were attempting
// to fetch a PAC file based on DHCP configuration.
- using FetcherVector =
- std::vector<std::unique_ptr<DhcpProxyScriptAdapterFetcher>>;
+ using FetcherVector = std::vector<std::unique_ptr<DhcpPacFileAdapterFetcher>>;
FetcherVector fetchers_;
+ // Current state of this state machine.
+ State state_;
+
+ // The following members are associated with the latest call to Fetch().
+
// Number of fetchers we are waiting for.
int num_pending_fetchers_;
// Lets our client know we're done. Not valid in states START or DONE.
CompletionCallback callback_;
+ // The NetLog to use for the current Fetch().
+ NetLogWithSource net_log_;
+
// Pointer to string we will write results to. Not valid in states
// START and DONE.
base::string16* destination_string_;
@@ -170,15 +187,12 @@ class NET_EXPORT_PRIVATE DhcpProxyScriptFetcherWin
// NULL or the AdapterQuery currently in flight.
scoped_refptr<AdapterQuery> last_query_;
- // Time |Fetch()| was last called, 0 if never.
- base::TimeTicks fetch_start_time_;
-
// TaskRunner used for all DHCP lookup tasks.
const scoped_refptr<base::TaskRunner> task_runner_;
THREAD_CHECKER(thread_checker_);
- DISALLOW_IMPLICIT_CONSTRUCTORS(DhcpProxyScriptFetcherWin);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(DhcpPacFileFetcherWin);
};
} // namespace net
diff --git a/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_win_unittest.cc b/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_win_unittest.cc
index 3490ef37921..44c128281f4 100644
--- a/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_win_unittest.cc
+++ b/chromium/net/proxy_resolution/dhcp_pac_file_fetcher_win_unittest.cc
@@ -16,6 +16,7 @@
#include "net/base/completion_callback.h"
#include "net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -27,7 +28,7 @@ namespace net {
namespace {
-TEST(DhcpProxyScriptFetcherWin, AdapterNamesAndPacURLFromDhcp) {
+TEST(DhcpPacFileFetcherWin, AdapterNamesAndPacURLFromDhcp) {
// This tests our core Win32 implementation without any of the wrappers
// we layer on top to achieve asynchronous and parallel operations.
//
@@ -36,12 +37,9 @@ TEST(DhcpProxyScriptFetcherWin, AdapterNamesAndPacURLFromDhcp) {
// is no crash and no error returned, but does not assert on the number
// of interfaces or the information returned via DHCP.
std::set<std::string> adapter_names;
- DhcpProxyScriptFetcherWin::GetCandidateAdapterNames(&adapter_names);
- for (std::set<std::string>::const_iterator it = adapter_names.begin();
- it != adapter_names.end();
- ++it) {
- const std::string& adapter_name = *it;
- DhcpProxyScriptAdapterFetcher::GetPacURLFromDhcp(adapter_name);
+ DhcpPacFileFetcherWin::GetCandidateAdapterNames(&adapter_names, nullptr);
+ for (const std::string& adapter_name : adapter_names) {
+ DhcpPacFileAdapterFetcher::GetPacURLFromDhcp(adapter_name);
}
}
@@ -50,7 +48,7 @@ class RealFetchTester {
public:
RealFetchTester()
: context_(new TestURLRequestContext),
- fetcher_(new DhcpProxyScriptFetcherWin(context_.get())),
+ fetcher_(new DhcpPacFileFetcherWin(context_.get())),
finished_(false),
on_completion_is_error_(false) {
// Make sure the test ends.
@@ -61,7 +59,8 @@ class RealFetchTester {
void RunTest() {
int result = fetcher_->Fetch(
&pac_text_,
- base::Bind(&RealFetchTester::OnCompletion, base::Unretained(this)));
+ base::Bind(&RealFetchTester::OnCompletion, base::Unretained(this)),
+ NetLogWithSource(), TRAFFIC_ANNOTATION_FOR_TESTS);
if (result != ERR_IO_PENDING)
finished_ = true;
}
@@ -108,13 +107,13 @@ class RealFetchTester {
// immediately "detaches" any worker threads, so the best we can do is give
// them a little time. If we start running into Valgrind leaks, we can
// do something a bit more clever to track worker threads even when the
- // DhcpProxyScriptFetcherWin state machine has finished.
+ // DhcpPacFileFetcherWin state machine has finished.
void FinishTestAllowCleanup() {
base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(30));
}
std::unique_ptr<URLRequestContext> context_;
- std::unique_ptr<DhcpProxyScriptFetcherWin> fetcher_;
+ std::unique_ptr<DhcpPacFileFetcherWin> fetcher_;
bool finished_;
base::string16 pac_text_;
base::OneShotTimer timeout_;
@@ -122,7 +121,7 @@ class RealFetchTester {
bool on_completion_is_error_;
};
-TEST(DhcpProxyScriptFetcherWin, RealFetch) {
+TEST(DhcpPacFileFetcherWin, RealFetch) {
// This tests a call to Fetch() with no stubbing out of dependencies.
//
// We don't make assumptions about the environment this unit test is
@@ -138,7 +137,7 @@ TEST(DhcpProxyScriptFetcherWin, RealFetch) {
fetcher.FinishTestAllowCleanup();
}
-TEST(DhcpProxyScriptFetcherWin, RealFetchWithCancel) {
+TEST(DhcpPacFileFetcherWin, RealFetchWithCancel) {
// Does a Fetch() with an immediate cancel. As before, just
// exercises the code without stubbing out dependencies.
RealFetchTester fetcher;
@@ -151,14 +150,11 @@ TEST(DhcpProxyScriptFetcherWin, RealFetchWithCancel) {
}
// For RealFetchWithDeferredCancel, below.
-class DelayingDhcpProxyScriptAdapterFetcher
- : public DhcpProxyScriptAdapterFetcher {
+class DelayingDhcpPacFileAdapterFetcher : public DhcpPacFileAdapterFetcher {
public:
- DelayingDhcpProxyScriptAdapterFetcher(
- URLRequestContext* url_request_context,
- scoped_refptr<base::TaskRunner> task_runner)
- : DhcpProxyScriptAdapterFetcher(url_request_context, task_runner) {
- }
+ DelayingDhcpPacFileAdapterFetcher(URLRequestContext* url_request_context,
+ scoped_refptr<base::TaskRunner> task_runner)
+ : DhcpPacFileAdapterFetcher(url_request_context, task_runner) {}
class DelayingDhcpQuery : public DhcpQuery {
public:
@@ -180,28 +176,25 @@ class DelayingDhcpProxyScriptAdapterFetcher
};
// For RealFetchWithDeferredCancel, below.
-class DelayingDhcpProxyScriptFetcherWin
- : public DhcpProxyScriptFetcherWin {
+class DelayingDhcpPacFileFetcherWin : public DhcpPacFileFetcherWin {
public:
- explicit DelayingDhcpProxyScriptFetcherWin(
- URLRequestContext* context)
- : DhcpProxyScriptFetcherWin(context) {
- }
+ explicit DelayingDhcpPacFileFetcherWin(URLRequestContext* context)
+ : DhcpPacFileFetcherWin(context) {}
- DhcpProxyScriptAdapterFetcher* ImplCreateAdapterFetcher() override {
- return new DelayingDhcpProxyScriptAdapterFetcher(url_request_context(),
- GetTaskRunner());
+ DhcpPacFileAdapterFetcher* ImplCreateAdapterFetcher() override {
+ return new DelayingDhcpPacFileAdapterFetcher(url_request_context(),
+ GetTaskRunner());
}
};
-TEST(DhcpProxyScriptFetcherWin, RealFetchWithDeferredCancel) {
+TEST(DhcpPacFileFetcherWin, RealFetchWithDeferredCancel) {
// Does a Fetch() with a slightly delayed cancel. As before, just
// exercises the code without stubbing out dependencies, but
// introduces a guaranteed 20 ms delay on the worker threads so that
// the cancel is called before they complete.
RealFetchTester fetcher;
fetcher.fetcher_.reset(
- new DelayingDhcpProxyScriptFetcherWin(fetcher.context_.get()));
+ new DelayingDhcpPacFileFetcherWin(fetcher.context_.get()));
fetcher.on_completion_is_error_ = true;
fetcher.RunTestWithDeferredCancel();
fetcher.WaitUntilDone();
@@ -210,23 +203,22 @@ TEST(DhcpProxyScriptFetcherWin, RealFetchWithDeferredCancel) {
// The remaining tests are to exercise our state machine in various
// situations, with actual network access fully stubbed out.
-class DummyDhcpProxyScriptAdapterFetcher
- : public DhcpProxyScriptAdapterFetcher {
+class DummyDhcpPacFileAdapterFetcher : public DhcpPacFileAdapterFetcher {
public:
- DummyDhcpProxyScriptAdapterFetcher(URLRequestContext* context,
- scoped_refptr<base::TaskRunner> runner)
- : DhcpProxyScriptAdapterFetcher(context, runner),
+ DummyDhcpPacFileAdapterFetcher(URLRequestContext* context,
+ scoped_refptr<base::TaskRunner> runner)
+ : DhcpPacFileAdapterFetcher(context, runner),
did_finish_(false),
result_(OK),
pac_script_(L"bingo"),
- fetch_delay_ms_(1) {
- }
+ fetch_delay_ms_(1) {}
void Fetch(const std::string& adapter_name,
- const CompletionCallback& callback) override {
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag traffic_annotation) override {
callback_ = callback;
timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(fetch_delay_ms_),
- this, &DummyDhcpProxyScriptAdapterFetcher::OnTimer);
+ this, &DummyDhcpPacFileAdapterFetcher::OnTimer);
}
void Cancel() override {
@@ -268,7 +260,7 @@ class DummyDhcpProxyScriptAdapterFetcher
base::OneShotTimer timer_;
};
-class MockDhcpProxyScriptFetcherWin : public DhcpProxyScriptFetcherWin {
+class MockDhcpPacFileFetcherWin : public DhcpPacFileFetcherWin {
public:
class MockAdapterQuery : public AdapterQuery {
public:
@@ -276,9 +268,10 @@ class MockDhcpProxyScriptFetcherWin : public DhcpProxyScriptFetcherWin {
}
bool ImplGetCandidateAdapterNames(
- std::set<std::string>* adapter_names) override {
- adapter_names->insert(
- mock_adapter_names_.begin(), mock_adapter_names_.end());
+ std::set<std::string>* adapter_names,
+ DhcpAdapterNamesLoggingInfo* logging) override {
+ adapter_names->insert(mock_adapter_names_.begin(),
+ mock_adapter_names_.end());
return true;
}
@@ -288,8 +281,8 @@ class MockDhcpProxyScriptFetcherWin : public DhcpProxyScriptFetcherWin {
~MockAdapterQuery() override {}
};
- MockDhcpProxyScriptFetcherWin(URLRequestContext* context)
- : DhcpProxyScriptFetcherWin(context),
+ MockDhcpPacFileFetcherWin(URLRequestContext* context)
+ : DhcpPacFileFetcherWin(context),
num_fetchers_created_(0),
worker_finished_event_(
base::WaitableEvent::ResetPolicy::MANUAL,
@@ -297,15 +290,15 @@ class MockDhcpProxyScriptFetcherWin : public DhcpProxyScriptFetcherWin {
ResetTestState();
}
- ~MockDhcpProxyScriptFetcherWin() override { ResetTestState(); }
+ ~MockDhcpPacFileFetcherWin() override { ResetTestState(); }
- using DhcpProxyScriptFetcherWin::GetTaskRunner;
+ using DhcpPacFileFetcherWin::GetTaskRunner;
// Adds a fetcher object to the queue of fetchers used by
// |ImplCreateAdapterFetcher()|, and its name to the list of adapters
// returned by ImplGetCandidateAdapterNames.
void PushBackAdapter(const std::string& adapter_name,
- DhcpProxyScriptAdapterFetcher* fetcher) {
+ DhcpPacFileAdapterFetcher* fetcher) {
adapter_query_->mock_adapter_names_.push_back(adapter_name);
adapter_fetchers_.push_back(fetcher);
}
@@ -315,15 +308,15 @@ class MockDhcpProxyScriptFetcherWin : public DhcpProxyScriptFetcherWin {
int result,
base::string16 pac_script,
base::TimeDelta fetch_delay) {
- std::unique_ptr<DummyDhcpProxyScriptAdapterFetcher> adapter_fetcher(
- new DummyDhcpProxyScriptAdapterFetcher(url_request_context(),
- GetTaskRunner()));
+ std::unique_ptr<DummyDhcpPacFileAdapterFetcher> adapter_fetcher(
+ new DummyDhcpPacFileAdapterFetcher(url_request_context(),
+ GetTaskRunner()));
adapter_fetcher->Configure(
did_finish, result, pac_script, fetch_delay.InMilliseconds());
PushBackAdapter(adapter_name, adapter_fetcher.release());
}
- DhcpProxyScriptAdapterFetcher* ImplCreateAdapterFetcher() override {
+ DhcpPacFileAdapterFetcher* ImplCreateAdapterFetcher() override {
++num_fetchers_created_;
return adapter_fetchers_[next_adapter_fetcher_index_++];
}
@@ -343,8 +336,8 @@ class MockDhcpProxyScriptFetcherWin : public DhcpProxyScriptFetcherWin {
void ResetTestState() {
// Delete any adapter fetcher objects we didn't hand out.
- std::vector<DhcpProxyScriptAdapterFetcher*>::const_iterator it
- = adapter_fetchers_.begin();
+ std::vector<DhcpPacFileAdapterFetcher*>::const_iterator it =
+ adapter_fetchers_.begin();
for (; it != adapter_fetchers_.end(); ++it) {
if (num_fetchers_created_-- <= 0) {
delete (*it);
@@ -367,7 +360,7 @@ class MockDhcpProxyScriptFetcherWin : public DhcpProxyScriptFetcherWin {
// Ownership gets transferred to the implementation class via
// ImplCreateAdapterFetcher, but any objects not handed out are
// deleted on destruction.
- std::vector<DhcpProxyScriptAdapterFetcher*> adapter_fetchers_;
+ std::vector<DhcpPacFileAdapterFetcher*> adapter_fetchers_;
scoped_refptr<MockAdapterQuery> adapter_query_;
@@ -388,14 +381,16 @@ class FetcherClient {
void RunTest() {
int result = fetcher_.Fetch(
&pac_text_,
- base::Bind(&FetcherClient::OnCompletion, base::Unretained(this)));
+ base::Bind(&FetcherClient::OnCompletion, base::Unretained(this)),
+ NetLogWithSource(), TRAFFIC_ANNOTATION_FOR_TESTS);
ASSERT_THAT(result, IsError(ERR_IO_PENDING));
}
int RunTestThatMayFailSync() {
int result = fetcher_.Fetch(
&pac_text_,
- base::Bind(&FetcherClient::OnCompletion, base::Unretained(this)));
+ base::Bind(&FetcherClient::OnCompletion, base::Unretained(this)),
+ NetLogWithSource(), TRAFFIC_ANNOTATION_FOR_TESTS);
if (result != ERR_IO_PENDING)
result_ = result;
return result;
@@ -433,7 +428,7 @@ class FetcherClient {
}
std::unique_ptr<URLRequestContext> context_;
- MockDhcpProxyScriptFetcherWin fetcher_;
+ MockDhcpPacFileFetcherWin fetcher_;
bool finished_;
int result_;
base::string16 pac_text_;
@@ -443,9 +438,8 @@ class FetcherClient {
// the ReuseFetcher test at the bottom.
void TestNormalCaseURLConfiguredOneAdapter(FetcherClient* client) {
TestURLRequestContext context;
- std::unique_ptr<DummyDhcpProxyScriptAdapterFetcher> adapter_fetcher(
- new DummyDhcpProxyScriptAdapterFetcher(&context,
- client->GetTaskRunner()));
+ std::unique_ptr<DummyDhcpPacFileAdapterFetcher> adapter_fetcher(
+ new DummyDhcpPacFileAdapterFetcher(&context, client->GetTaskRunner()));
adapter_fetcher->Configure(true, OK, L"bingo", 1);
client->fetcher_.PushBackAdapter("a", adapter_fetcher.release());
client->RunTest();
@@ -454,7 +448,7 @@ void TestNormalCaseURLConfiguredOneAdapter(FetcherClient* client) {
ASSERT_EQ(L"bingo", client->pac_text_);
}
-TEST(DhcpProxyScriptFetcherWin, NormalCaseURLConfiguredOneAdapter) {
+TEST(DhcpPacFileFetcherWin, NormalCaseURLConfiguredOneAdapter) {
FetcherClient client;
TestNormalCaseURLConfiguredOneAdapter(&client);
}
@@ -473,7 +467,7 @@ void TestNormalCaseURLConfiguredMultipleAdapters(FetcherClient* client) {
ASSERT_EQ(L"bingo", client->pac_text_);
}
-TEST(DhcpProxyScriptFetcherWin, NormalCaseURLConfiguredMultipleAdapters) {
+TEST(DhcpPacFileFetcherWin, NormalCaseURLConfiguredMultipleAdapters) {
FetcherClient client;
TestNormalCaseURLConfiguredMultipleAdapters(&client);
}
@@ -495,7 +489,7 @@ void TestNormalCaseURLConfiguredMultipleAdaptersWithTimeout(
ASSERT_EQ(L"rocko", client->pac_text_);
}
-TEST(DhcpProxyScriptFetcherWin,
+TEST(DhcpPacFileFetcherWin,
NormalCaseURLConfiguredMultipleAdaptersWithTimeout) {
FetcherClient client;
TestNormalCaseURLConfiguredMultipleAdaptersWithTimeout(&client);
@@ -524,7 +518,7 @@ void TestFailureCaseURLConfiguredMultipleAdaptersWithTimeout(
ASSERT_EQ(L"", client->pac_text_);
}
-TEST(DhcpProxyScriptFetcherWin,
+TEST(DhcpPacFileFetcherWin,
FailureCaseURLConfiguredMultipleAdaptersWithTimeout) {
FetcherClient client;
TestFailureCaseURLConfiguredMultipleAdaptersWithTimeout(&client);
@@ -549,7 +543,7 @@ void TestFailureCaseNoURLConfigured(FetcherClient* client) {
ASSERT_EQ(L"", client->pac_text_);
}
-TEST(DhcpProxyScriptFetcherWin, FailureCaseNoURLConfigured) {
+TEST(DhcpPacFileFetcherWin, FailureCaseNoURLConfigured) {
FetcherClient client;
TestFailureCaseNoURLConfigured(&client);
}
@@ -562,7 +556,7 @@ void TestFailureCaseNoDhcpAdapters(FetcherClient* client) {
ASSERT_EQ(0, client->fetcher_.num_fetchers_created_);
}
-TEST(DhcpProxyScriptFetcherWin, FailureCaseNoDhcpAdapters) {
+TEST(DhcpPacFileFetcherWin, FailureCaseNoDhcpAdapters) {
FetcherClient client;
TestFailureCaseNoDhcpAdapters(&client);
}
@@ -597,16 +591,15 @@ void TestShortCircuitLessPreferredAdapters(FetcherClient* client) {
timer.Elapsed());
}
-TEST(DhcpProxyScriptFetcherWin, ShortCircuitLessPreferredAdapters) {
+TEST(DhcpPacFileFetcherWin, ShortCircuitLessPreferredAdapters) {
FetcherClient client;
TestShortCircuitLessPreferredAdapters(&client);
}
void TestImmediateCancel(FetcherClient* client) {
TestURLRequestContext context;
- std::unique_ptr<DummyDhcpProxyScriptAdapterFetcher> adapter_fetcher(
- new DummyDhcpProxyScriptAdapterFetcher(&context,
- client->GetTaskRunner()));
+ std::unique_ptr<DummyDhcpPacFileAdapterFetcher> adapter_fetcher(
+ new DummyDhcpPacFileAdapterFetcher(&context, client->GetTaskRunner()));
adapter_fetcher->Configure(true, OK, L"bingo", 1);
client->fetcher_.PushBackAdapter("a", adapter_fetcher.release());
client->RunTest();
@@ -617,15 +610,15 @@ void TestImmediateCancel(FetcherClient* client) {
// Regression test to check that when we cancel immediately, no
// adapter fetchers get created.
-TEST(DhcpProxyScriptFetcherWin, ImmediateCancel) {
+TEST(DhcpPacFileFetcherWin, ImmediateCancel) {
FetcherClient client;
TestImmediateCancel(&client);
}
-TEST(DhcpProxyScriptFetcherWin, ReuseFetcher) {
+TEST(DhcpPacFileFetcherWin, ReuseFetcher) {
FetcherClient client;
- // The ProxyScriptFetcher interface stipulates that only a single
+ // The PacFileFetcher interface stipulates that only a single
// |Fetch()| may be in flight at once, but allows reuse, so test
// that the state transitions correctly from done to start in all
// cases we're testing.
@@ -659,11 +652,11 @@ TEST(DhcpProxyScriptFetcherWin, ReuseFetcher) {
(*test_functions.begin())(&client);
}
-TEST(DhcpProxyScriptFetcherWin, OnShutdown) {
+TEST(DhcpPacFileFetcherWin, OnShutdown) {
FetcherClient client;
TestURLRequestContext context;
- std::unique_ptr<DummyDhcpProxyScriptAdapterFetcher> adapter_fetcher(
- new DummyDhcpProxyScriptAdapterFetcher(&context, client.GetTaskRunner()));
+ std::unique_ptr<DummyDhcpPacFileAdapterFetcher> adapter_fetcher(
+ new DummyDhcpPacFileAdapterFetcher(&context, client.GetTaskRunner()));
adapter_fetcher->Configure(true, OK, L"bingo", 1);
client.fetcher_.PushBackAdapter("a", adapter_fetcher.release());
client.RunTest();
diff --git a/chromium/net/proxy_resolution/mock_pac_file_fetcher.cc b/chromium/net/proxy_resolution/mock_pac_file_fetcher.cc
index 4c172c865db..a4d10a4a259 100644
--- a/chromium/net/proxy_resolution/mock_pac_file_fetcher.cc
+++ b/chromium/net/proxy_resolution/mock_pac_file_fetcher.cc
@@ -13,16 +13,19 @@
namespace net {
-MockProxyScriptFetcher::MockProxyScriptFetcher()
+MockPacFileFetcher::MockPacFileFetcher()
: pending_request_text_(NULL),
waiting_for_fetch_(false),
is_shutdown_(false) {}
-MockProxyScriptFetcher::~MockProxyScriptFetcher() = default;
+MockPacFileFetcher::~MockPacFileFetcher() = default;
-// ProxyScriptFetcher implementation.
-int MockProxyScriptFetcher::Fetch(const GURL& url, base::string16* text,
- const CompletionCallback& callback) {
+// PacFileFetcher implementation.
+int MockPacFileFetcher::Fetch(
+ const GURL& url,
+ base::string16* text,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag traffic_annotation) {
DCHECK(!has_pending_request());
if (waiting_for_fetch_)
@@ -39,37 +42,37 @@ int MockProxyScriptFetcher::Fetch(const GURL& url, base::string16* text,
return ERR_IO_PENDING;
}
-void MockProxyScriptFetcher::NotifyFetchCompletion(
- int result, const std::string& ascii_text) {
+void MockPacFileFetcher::NotifyFetchCompletion(int result,
+ const std::string& ascii_text) {
DCHECK(has_pending_request());
*pending_request_text_ = base::ASCIIToUTF16(ascii_text);
base::ResetAndReturn(&pending_request_callback_).Run(result);
}
-void MockProxyScriptFetcher::Cancel() {
+void MockPacFileFetcher::Cancel() {
pending_request_callback_.Reset();
}
-void MockProxyScriptFetcher::OnShutdown() {
+void MockPacFileFetcher::OnShutdown() {
is_shutdown_ = true;
if (pending_request_callback_) {
base::ResetAndReturn(&pending_request_callback_).Run(ERR_CONTEXT_SHUT_DOWN);
}
}
-URLRequestContext* MockProxyScriptFetcher::GetRequestContext() const {
+URLRequestContext* MockPacFileFetcher::GetRequestContext() const {
return NULL;
}
-const GURL& MockProxyScriptFetcher::pending_request_url() const {
+const GURL& MockPacFileFetcher::pending_request_url() const {
return pending_request_url_;
}
-bool MockProxyScriptFetcher::has_pending_request() const {
+bool MockPacFileFetcher::has_pending_request() const {
return !pending_request_callback_.is_null();
}
-void MockProxyScriptFetcher::WaitUntilFetch() {
+void MockPacFileFetcher::WaitUntilFetch() {
DCHECK(!has_pending_request());
waiting_for_fetch_ = true;
base::RunLoop().Run();
diff --git a/chromium/net/proxy_resolution/mock_pac_file_fetcher.h b/chromium/net/proxy_resolution/mock_pac_file_fetcher.h
index 218dc77ee42..d59e3d1ca79 100644
--- a/chromium/net/proxy_resolution/mock_pac_file_fetcher.h
+++ b/chromium/net/proxy_resolution/mock_pac_file_fetcher.h
@@ -7,6 +7,7 @@
#include "base/compiler_specific.h"
#include "net/proxy_resolution/pac_file_fetcher.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"
#include <string>
@@ -15,17 +16,18 @@ namespace net {
class URLRequestContext;
-// A mock ProxyScriptFetcher. No result will be returned to the fetch client
+// A mock PacFileFetcher. No result will be returned to the fetch client
// until we call NotifyFetchCompletion() to set the results.
-class MockProxyScriptFetcher : public ProxyScriptFetcher {
+class MockPacFileFetcher : public PacFileFetcher {
public:
- MockProxyScriptFetcher();
- ~MockProxyScriptFetcher() override;
+ MockPacFileFetcher();
+ ~MockPacFileFetcher() override;
- // ProxyScriptFetcher implementation.
+ // PacFileFetcher implementation.
int Fetch(const GURL& url,
base::string16* text,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag traffic_annotation) override;
void Cancel() override;
void OnShutdown() override;
URLRequestContext* GetRequestContext() const override;
diff --git a/chromium/net/proxy_resolution/mock_proxy_resolver.cc b/chromium/net/proxy_resolution/mock_proxy_resolver.cc
index 56ac53a29cf..b7076ead0ff 100644
--- a/chromium/net/proxy_resolution/mock_proxy_resolver.cc
+++ b/chromium/net/proxy_resolution/mock_proxy_resolver.cc
@@ -81,7 +81,7 @@ MockAsyncProxyResolver::MockAsyncProxyResolver() = default;
MockAsyncProxyResolverFactory::Request::Request(
MockAsyncProxyResolverFactory* factory,
- const scoped_refptr<ProxyResolverScriptData>& script_data,
+ const scoped_refptr<PacFileData>& script_data,
std::unique_ptr<ProxyResolver>* resolver,
const CompletionCallback& callback)
: factory_(factory),
@@ -137,7 +137,7 @@ MockAsyncProxyResolverFactory::MockAsyncProxyResolverFactory(
}
int MockAsyncProxyResolverFactory::CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
+ const scoped_refptr<PacFileData>& pac_script,
std::unique_ptr<ProxyResolver>* resolver,
const net::CompletionCallback& callback,
std::unique_ptr<ProxyResolverFactory::Request>* request_handle) {
diff --git a/chromium/net/proxy_resolution/mock_proxy_resolver.h b/chromium/net/proxy_resolution/mock_proxy_resolver.h
index df8c6c1ff8c..9270a5fa402 100644
--- a/chromium/net/proxy_resolution/mock_proxy_resolver.h
+++ b/chromium/net/proxy_resolution/mock_proxy_resolver.h
@@ -90,7 +90,7 @@ class MockAsyncProxyResolverFactory : public ProxyResolverFactory {
~MockAsyncProxyResolverFactory() override;
int CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
+ const scoped_refptr<PacFileData>& pac_script,
std::unique_ptr<ProxyResolver>* resolver,
const CompletionCallback& callback,
std::unique_ptr<ProxyResolverFactory::Request>* request) override;
@@ -111,13 +111,11 @@ class MockAsyncProxyResolverFactory::Request
: public base::RefCounted<Request> {
public:
Request(MockAsyncProxyResolverFactory* factory,
- const scoped_refptr<ProxyResolverScriptData>& script_data,
+ const scoped_refptr<PacFileData>& script_data,
std::unique_ptr<ProxyResolver>* resolver,
const CompletionCallback& callback);
- const scoped_refptr<ProxyResolverScriptData>& script_data() const {
- return script_data_;
- }
+ const scoped_refptr<PacFileData>& script_data() const { return script_data_; }
// Completes this request. A ForwardingProxyResolver that forwards to
// |resolver| will be returned to the requester. |resolver| must not be
@@ -137,7 +135,7 @@ class MockAsyncProxyResolverFactory::Request
void FactoryDestroyed();
MockAsyncProxyResolverFactory* factory_;
- const scoped_refptr<ProxyResolverScriptData> script_data_;
+ const scoped_refptr<PacFileData> script_data_;
std::unique_ptr<ProxyResolver>* resolver_;
CompletionCallback callback_;
};
diff --git a/chromium/net/proxy_resolution/multi_threaded_proxy_resolver.cc b/chromium/net/proxy_resolution/multi_threaded_proxy_resolver.cc
index 01fbf393f7b..d8c8e837719 100644
--- a/chromium/net/proxy_resolution/multi_threaded_proxy_resolver.cc
+++ b/chromium/net/proxy_resolution/multi_threaded_proxy_resolver.cc
@@ -110,7 +110,7 @@ class MultiThreadedProxyResolver : public ProxyResolver,
MultiThreadedProxyResolver(
std::unique_ptr<ProxyResolverFactory> resolver_factory,
size_t max_num_threads,
- const scoped_refptr<ProxyResolverScriptData>& script_data,
+ const scoped_refptr<PacFileData>& script_data,
scoped_refptr<Executor> executor);
~MultiThreadedProxyResolver() override;
@@ -144,7 +144,7 @@ class MultiThreadedProxyResolver : public ProxyResolver,
const size_t max_num_threads_;
PendingJobsQueue pending_jobs_;
ExecutorList executors_;
- scoped_refptr<ProxyResolverScriptData> script_data_;
+ scoped_refptr<PacFileData> script_data_;
THREAD_CHECKER(thread_checker_);
};
@@ -251,7 +251,7 @@ class MultiThreadedProxyResolver::RequestImpl : public ProxyResolver::Request {
// Runs on the worker thread to call ProxyResolverFactory::CreateProxyResolver.
class CreateResolverJob : public Job {
public:
- CreateResolverJob(const scoped_refptr<ProxyResolverScriptData>& script_data,
+ CreateResolverJob(const scoped_refptr<PacFileData>& script_data,
ProxyResolverFactory* factory)
: Job(TYPE_CREATE_RESOLVER, CompletionCallback()),
script_data_(script_data),
@@ -282,7 +282,7 @@ class CreateResolverJob : public Job {
OnJobCompleted();
}
- const scoped_refptr<ProxyResolverScriptData> script_data_;
+ const scoped_refptr<PacFileData> script_data_;
ProxyResolverFactory* factory_;
std::unique_ptr<ProxyResolver> resolver_;
};
@@ -436,7 +436,7 @@ Executor::~Executor() {
MultiThreadedProxyResolver::MultiThreadedProxyResolver(
std::unique_ptr<ProxyResolverFactory> resolver_factory,
size_t max_num_threads,
- const scoped_refptr<ProxyResolverScriptData>& script_data,
+ const scoped_refptr<PacFileData>& script_data,
scoped_refptr<Executor> executor)
: resolver_factory_(std::move(resolver_factory)),
max_num_threads_(max_num_threads),
@@ -535,7 +535,7 @@ class MultiThreadedProxyResolverFactory::Job
public Executor::Coordinator {
public:
Job(MultiThreadedProxyResolverFactory* factory,
- const scoped_refptr<ProxyResolverScriptData>& script_data,
+ const scoped_refptr<PacFileData>& script_data,
std::unique_ptr<ProxyResolver>* resolver,
std::unique_ptr<ProxyResolverFactory> resolver_factory,
size_t max_num_threads,
@@ -584,7 +584,7 @@ class MultiThreadedProxyResolverFactory::Job
std::unique_ptr<ProxyResolver>* const resolver_out_;
std::unique_ptr<ProxyResolverFactory> resolver_factory_;
const size_t max_num_threads_;
- scoped_refptr<ProxyResolverScriptData> script_data_;
+ scoped_refptr<PacFileData> script_data_;
scoped_refptr<Executor> executor_;
const CompletionCallback callback_;
};
@@ -604,7 +604,7 @@ MultiThreadedProxyResolverFactory::~MultiThreadedProxyResolverFactory() {
}
int MultiThreadedProxyResolverFactory::CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
+ const scoped_refptr<PacFileData>& pac_script,
std::unique_ptr<ProxyResolver>* resolver,
const CompletionCallback& callback,
std::unique_ptr<Request>* request) {
diff --git a/chromium/net/proxy_resolution/multi_threaded_proxy_resolver.h b/chromium/net/proxy_resolution/multi_threaded_proxy_resolver.h
index caf36faa7bb..8daa17ef7fa 100644
--- a/chromium/net/proxy_resolution/multi_threaded_proxy_resolver.h
+++ b/chromium/net/proxy_resolution/multi_threaded_proxy_resolver.h
@@ -55,11 +55,10 @@ class NET_EXPORT_PRIVATE MultiThreadedProxyResolverFactory
bool factory_expects_bytes);
~MultiThreadedProxyResolverFactory() override;
- int CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
- std::unique_ptr<ProxyResolver>* resolver,
- const CompletionCallback& callback,
- std::unique_ptr<Request>* request) override;
+ int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
+ std::unique_ptr<ProxyResolver>* resolver,
+ const CompletionCallback& callback,
+ std::unique_ptr<Request>* request) override;
private:
class Job;
diff --git a/chromium/net/proxy_resolution/multi_threaded_proxy_resolver_unittest.cc b/chromium/net/proxy_resolution/multi_threaded_proxy_resolver_unittest.cc
index 53ce0aa15e2..3f559d9fe11 100644
--- a/chromium/net/proxy_resolution/multi_threaded_proxy_resolver_unittest.cc
+++ b/chromium/net/proxy_resolution/multi_threaded_proxy_resolver_unittest.cc
@@ -13,8 +13,8 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
-#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
@@ -90,31 +90,44 @@ class MockProxyResolver : public ProxyResolver {
// A mock synchronous ProxyResolver which can be set to block upon reaching
// GetProxyForURL().
-// TODO(eroman): WaitUntilBlocked() *must* be called before calling Unblock(),
-// otherwise there will be a race on |should_block_| since it is
-// read without any synchronization.
class BlockableProxyResolver : public MockProxyResolver {
public:
- BlockableProxyResolver()
- : should_block_(false),
- unblocked_(base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::SIGNALED),
- blocked_(base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED) {}
+ enum class State {
+ NONE,
+ BLOCKED,
+ WILL_BLOCK,
+ };
+ BlockableProxyResolver() : state_(State::NONE), condition_(&lock_) {}
+
+ ~BlockableProxyResolver() override {
+ base::AutoLock lock(lock_);
+ EXPECT_NE(State::BLOCKED, state_);
+ }
+
+ // Causes the next call into GetProxyForURL() to block. Must be followed by
+ // a call to Unblock().
void Block() {
- should_block_ = true;
- unblocked_.Reset();
+ base::AutoLock lock(lock_);
+ EXPECT_EQ(State::NONE, state_);
+ state_ = State::WILL_BLOCK;
+ condition_.Broadcast();
}
+ // Unblocks the ProxyResolver. The ProxyResolver must already be in a
+ // blocked state prior to calling.
void Unblock() {
- should_block_ = false;
- blocked_.Reset();
- unblocked_.Signal();
+ base::AutoLock lock(lock_);
+ EXPECT_EQ(State::BLOCKED, state_);
+ state_ = State::NONE;
+ condition_.Broadcast();
}
+ // Waits until the proxy resolver is blocked within GetProxyForURL().
void WaitUntilBlocked() {
- blocked_.Wait();
+ base::AutoLock lock(lock_);
+ while (state_ != State::BLOCKED)
+ condition_.Wait();
}
int GetProxyForURL(const GURL& query_url,
@@ -122,9 +135,18 @@ class BlockableProxyResolver : public MockProxyResolver {
const CompletionCallback& callback,
std::unique_ptr<Request>* request,
const NetLogWithSource& net_log) override {
- if (should_block_) {
- blocked_.Signal();
- unblocked_.Wait();
+ {
+ base::AutoLock lock(lock_);
+
+ EXPECT_NE(State::BLOCKED, state_);
+
+ if (state_ == State::WILL_BLOCK) {
+ state_ = State::BLOCKED;
+ condition_.Broadcast();
+
+ while (state_ == State::BLOCKED)
+ condition_.Wait();
+ }
}
return MockProxyResolver::GetProxyForURL(
@@ -132,9 +154,11 @@ class BlockableProxyResolver : public MockProxyResolver {
}
private:
- bool should_block_;
- base::WaitableEvent unblocked_;
- base::WaitableEvent blocked_;
+ State state_;
+ base::Lock lock_;
+ base::ConditionVariable condition_;
+
+ DISALLOW_COPY_AND_ASSIGN(BlockableProxyResolver);
};
// This factory returns new instances of BlockableProxyResolver.
@@ -144,11 +168,10 @@ class BlockableProxyResolverFactory : public ProxyResolverFactory {
~BlockableProxyResolverFactory() override = default;
- int CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& script_data,
- std::unique_ptr<ProxyResolver>* result,
- const CompletionCallback& callback,
- std::unique_ptr<Request>* request) override {
+ int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
+ std::unique_ptr<ProxyResolver>* result,
+ const CompletionCallback& callback,
+ std::unique_ptr<Request>* request) override {
BlockableProxyResolver* resolver = new BlockableProxyResolver;
result->reset(resolver);
base::AutoLock lock(lock_);
@@ -162,14 +185,14 @@ class BlockableProxyResolverFactory : public ProxyResolverFactory {
return resolvers_;
}
- const std::vector<scoped_refptr<ProxyResolverScriptData>> script_data() {
+ const std::vector<scoped_refptr<PacFileData>> script_data() {
base::AutoLock lock(lock_);
return script_data_;
}
private:
std::vector<BlockableProxyResolver*> resolvers_;
- std::vector<scoped_refptr<ProxyResolverScriptData>> script_data_;
+ std::vector<scoped_refptr<PacFileData>> script_data_;
base::Lock lock_;
};
@@ -202,7 +225,7 @@ class MultiThreadedProxyResolverTest : public testing::Test {
TestCompletionCallback ready_callback;
std::unique_ptr<ProxyResolverFactory::Request> request;
resolver_factory_->CreateProxyResolver(
- ProxyResolverScriptData::FromUTF8("pac script bytes"), &resolver_,
+ PacFileData::FromUTF8("pac script bytes"), &resolver_,
ready_callback.callback(), &request);
EXPECT_TRUE(request);
ASSERT_THAT(ready_callback.WaitForResult(), IsOk());
@@ -682,11 +705,10 @@ class FailingProxyResolverFactory : public ProxyResolverFactory {
FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
// ProxyResolverFactory override.
- int CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& script_data,
- std::unique_ptr<ProxyResolver>* result,
- const CompletionCallback& callback,
- std::unique_ptr<Request>* request) override {
+ int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
+ std::unique_ptr<ProxyResolver>* result,
+ const CompletionCallback& callback,
+ std::unique_ptr<Request>* request) override {
return ERR_PAC_SCRIPT_FAILED;
}
};
@@ -702,8 +724,8 @@ TEST_F(MultiThreadedProxyResolverTest, ProxyResolverFactoryError) {
std::unique_ptr<ProxyResolver> resolver;
EXPECT_EQ(ERR_IO_PENDING,
resolver_factory.CreateProxyResolver(
- ProxyResolverScriptData::FromUTF8("pac script bytes"),
- &resolver, ready_callback.callback(), &request));
+ PacFileData::FromUTF8("pac script bytes"), &resolver,
+ ready_callback.callback(), &request));
EXPECT_TRUE(request);
EXPECT_THAT(ready_callback.WaitForResult(), IsError(ERR_PAC_SCRIPT_FAILED));
EXPECT_FALSE(resolver);
@@ -721,10 +743,9 @@ TEST_F(MultiThreadedProxyResolverTest, CancelCreate) {
kNumThreads, std::make_unique<BlockableProxyResolverFactory>());
std::unique_ptr<ProxyResolverFactory::Request> request;
std::unique_ptr<ProxyResolver> resolver;
- EXPECT_EQ(ERR_IO_PENDING,
- resolver_factory.CreateProxyResolver(
- ProxyResolverScriptData::FromUTF8("pac script bytes"),
- &resolver, base::Bind(&Fail), &request));
+ EXPECT_EQ(ERR_IO_PENDING, resolver_factory.CreateProxyResolver(
+ PacFileData::FromUTF8("pac script bytes"),
+ &resolver, base::Bind(&Fail), &request));
EXPECT_TRUE(request);
request.reset();
}
@@ -751,9 +772,9 @@ TEST_F(MultiThreadedProxyResolverTest, DeleteRequestInFactoryCallback) {
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
resolver_factory.CreateProxyResolver(
- ProxyResolverScriptData::FromUTF8("pac script bytes"),
- &resolver, base::Bind(&DeleteRequest, callback.callback(),
- base::Unretained(&request)),
+ PacFileData::FromUTF8("pac script bytes"), &resolver,
+ base::Bind(&DeleteRequest, callback.callback(),
+ base::Unretained(&request)),
&request));
EXPECT_TRUE(request);
EXPECT_THAT(callback.WaitForResult(), IsOk());
@@ -767,10 +788,9 @@ TEST_F(MultiThreadedProxyResolverTest, DestroyFactoryWithRequestsInProgress) {
{
SingleShotMultiThreadedProxyResolverFactory resolver_factory(
kNumThreads, std::make_unique<BlockableProxyResolverFactory>());
- EXPECT_EQ(ERR_IO_PENDING,
- resolver_factory.CreateProxyResolver(
- ProxyResolverScriptData::FromUTF8("pac script bytes"),
- &resolver, base::Bind(&Fail), &request));
+ EXPECT_EQ(ERR_IO_PENDING, resolver_factory.CreateProxyResolver(
+ PacFileData::FromUTF8("pac script bytes"),
+ &resolver, base::Bind(&Fail), &request));
EXPECT_TRUE(request);
}
// The factory destructor will block until the worker thread stops, but it may
diff --git a/chromium/net/proxy_resolution/pac_file_data.cc b/chromium/net/proxy_resolution/pac_file_data.cc
index c0f8cc1889b..e96d27394d6 100644
--- a/chromium/net/proxy_resolution/pac_file_data.cc
+++ b/chromium/net/proxy_resolution/pac_file_data.cc
@@ -10,43 +10,36 @@
namespace net {
// static
-scoped_refptr<ProxyResolverScriptData> ProxyResolverScriptData::FromUTF8(
- const std::string& utf8) {
- return new ProxyResolverScriptData(TYPE_SCRIPT_CONTENTS, GURL(),
- base::UTF8ToUTF16(utf8));
+scoped_refptr<PacFileData> PacFileData::FromUTF8(const std::string& utf8) {
+ return new PacFileData(TYPE_SCRIPT_CONTENTS, GURL(), base::UTF8ToUTF16(utf8));
}
// static
-scoped_refptr<ProxyResolverScriptData> ProxyResolverScriptData::FromUTF16(
- const base::string16& utf16) {
- return new ProxyResolverScriptData(TYPE_SCRIPT_CONTENTS, GURL(), utf16);
+scoped_refptr<PacFileData> PacFileData::FromUTF16(const base::string16& utf16) {
+ return new PacFileData(TYPE_SCRIPT_CONTENTS, GURL(), utf16);
}
// static
-scoped_refptr<ProxyResolverScriptData> ProxyResolverScriptData::FromURL(
- const GURL& url) {
- return new ProxyResolverScriptData(TYPE_SCRIPT_URL, url, base::string16());
+scoped_refptr<PacFileData> PacFileData::FromURL(const GURL& url) {
+ return new PacFileData(TYPE_SCRIPT_URL, url, base::string16());
}
// static
-scoped_refptr<ProxyResolverScriptData>
-ProxyResolverScriptData::ForAutoDetect() {
- return new ProxyResolverScriptData(TYPE_AUTO_DETECT, GURL(),
- base::string16());
+scoped_refptr<PacFileData> PacFileData::ForAutoDetect() {
+ return new PacFileData(TYPE_AUTO_DETECT, GURL(), base::string16());
}
-const base::string16& ProxyResolverScriptData::utf16() const {
+const base::string16& PacFileData::utf16() const {
DCHECK_EQ(TYPE_SCRIPT_CONTENTS, type_);
return utf16_;
}
-const GURL& ProxyResolverScriptData::url() const {
+const GURL& PacFileData::url() const {
DCHECK_EQ(TYPE_SCRIPT_URL, type_);
return url_;
}
-bool ProxyResolverScriptData::Equals(
- const ProxyResolverScriptData* other) const {
+bool PacFileData::Equals(const PacFileData* other) const {
if (type() != other->type())
return false;
@@ -62,11 +55,11 @@ bool ProxyResolverScriptData::Equals(
return false; // Shouldn't be reached.
}
-ProxyResolverScriptData::ProxyResolverScriptData(Type type,
- const GURL& url,
- const base::string16& utf16)
+PacFileData::PacFileData(Type type,
+ const GURL& url,
+ const base::string16& utf16)
: type_(type), url_(url), utf16_(utf16) {}
-ProxyResolverScriptData::~ProxyResolverScriptData() = default;
+PacFileData::~PacFileData() = default;
} // namespace net
diff --git a/chromium/net/proxy_resolution/pac_file_data.h b/chromium/net/proxy_resolution/pac_file_data.h
index 88dc1ef0b8d..5f75cf5b712 100644
--- a/chromium/net/proxy_resolution/pac_file_data.h
+++ b/chromium/net/proxy_resolution/pac_file_data.h
@@ -18,8 +18,8 @@ namespace net {
//
// This is thread-safe so it can be used by multi-threaded implementations of
// ProxyResolver to share the data between threads.
-class NET_EXPORT_PRIVATE ProxyResolverScriptData
- : public base::RefCountedThreadSafe<ProxyResolverScriptData> {
+class NET_EXPORT_PRIVATE PacFileData
+ : public base::RefCountedThreadSafe<PacFileData> {
public:
enum Type {
TYPE_SCRIPT_CONTENTS,
@@ -28,18 +28,16 @@ class NET_EXPORT_PRIVATE ProxyResolverScriptData
};
// Creates a script data given the UTF8 bytes of the content.
- static scoped_refptr<ProxyResolverScriptData> FromUTF8(
- const std::string& utf8);
+ static scoped_refptr<PacFileData> FromUTF8(const std::string& utf8);
// Creates a script data given the UTF16 bytes of the content.
- static scoped_refptr<ProxyResolverScriptData> FromUTF16(
- const base::string16& utf16);
+ static scoped_refptr<PacFileData> FromUTF16(const base::string16& utf16);
// Creates a script data given a URL to the PAC script.
- static scoped_refptr<ProxyResolverScriptData> FromURL(const GURL& url);
+ static scoped_refptr<PacFileData> FromURL(const GURL& url);
// Creates a script data for using an automatically detected PAC URL.
- static scoped_refptr<ProxyResolverScriptData> ForAutoDetect();
+ static scoped_refptr<PacFileData> ForAutoDetect();
Type type() const { return type_; }
@@ -52,14 +50,12 @@ class NET_EXPORT_PRIVATE ProxyResolverScriptData
const GURL& url() const;
// Returns true if |this| matches |other|.
- bool Equals(const ProxyResolverScriptData* other) const;
+ bool Equals(const PacFileData* other) const;
private:
- friend class base::RefCountedThreadSafe<ProxyResolverScriptData>;
- ProxyResolverScriptData(Type type,
- const GURL& url,
- const base::string16& utf16);
- virtual ~ProxyResolverScriptData();
+ friend class base::RefCountedThreadSafe<PacFileData>;
+ PacFileData(Type type, const GURL& url, const base::string16& utf16);
+ virtual ~PacFileData();
const Type type_;
const GURL url_;
diff --git a/chromium/net/proxy_resolution/pac_file_decider.cc b/chromium/net/proxy_resolution/pac_file_decider.cc
index 29e8413a3e2..db7efcfd6bb 100644
--- a/chromium/net/proxy_resolution/pac_file_decider.cc
+++ b/chromium/net/proxy_resolution/pac_file_decider.cc
@@ -58,7 +58,7 @@ const char kWpadUrl[] = "http://wpad/wpad.dat";
const int kQuickCheckDelayMs = 1000;
}; // namespace
-std::unique_ptr<base::Value> ProxyScriptDecider::PacSource::NetLogCallback(
+std::unique_ptr<base::Value> PacFileDecider::PacSource::NetLogCallback(
const GURL* effective_pac_url,
NetLogCaptureMode /* capture_mode */) const {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
@@ -80,34 +80,33 @@ std::unique_ptr<base::Value> ProxyScriptDecider::PacSource::NetLogCallback(
return std::move(dict);
}
-ProxyScriptDecider::ProxyScriptDecider(
- ProxyScriptFetcher* proxy_script_fetcher,
- DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher,
- NetLog* net_log)
- : proxy_script_fetcher_(proxy_script_fetcher),
- dhcp_proxy_script_fetcher_(dhcp_proxy_script_fetcher),
+PacFileDecider::PacFileDecider(PacFileFetcher* pac_file_fetcher,
+ DhcpPacFileFetcher* dhcp_pac_file_fetcher,
+ NetLog* net_log)
+ : pac_file_fetcher_(pac_file_fetcher),
+ dhcp_pac_file_fetcher_(dhcp_pac_file_fetcher),
current_pac_source_index_(0u),
pac_mandatory_(false),
next_state_(STATE_NONE),
- net_log_(NetLogWithSource::Make(net_log,
- NetLogSourceType::PROXY_SCRIPT_DECIDER)),
+ net_log_(
+ NetLogWithSource::Make(net_log, NetLogSourceType::PAC_FILE_DECIDER)),
fetch_pac_bytes_(false),
quick_check_enabled_(true) {}
-ProxyScriptDecider::~ProxyScriptDecider() {
+PacFileDecider::~PacFileDecider() {
if (next_state_ != STATE_NONE)
Cancel();
}
-int ProxyScriptDecider::Start(const ProxyConfig& config,
- const base::TimeDelta wait_delay,
- bool fetch_pac_bytes,
- const CompletionCallback& callback) {
+int PacFileDecider::Start(const ProxyConfigWithAnnotation& config,
+ const base::TimeDelta wait_delay,
+ bool fetch_pac_bytes,
+ const CompletionCallback& callback) {
DCHECK_EQ(STATE_NONE, next_state_);
DCHECK(!callback.is_null());
- DCHECK(config.HasAutomaticSettings());
+ DCHECK(config.value().HasAutomaticSettings());
- net_log_.BeginEvent(NetLogEventType::PROXY_SCRIPT_DECIDER);
+ net_log_.BeginEvent(NetLogEventType::PAC_FILE_DECIDER);
fetch_pac_bytes_ = fetch_pac_bytes;
@@ -116,12 +115,14 @@ int ProxyScriptDecider::Start(const ProxyConfig& config,
if (wait_delay_ < base::TimeDelta())
wait_delay_ = base::TimeDelta();
- pac_mandatory_ = config.pac_mandatory();
- have_custom_pac_url_ = config.has_pac_url();
+ pac_mandatory_ = config.value().pac_mandatory();
+ have_custom_pac_url_ = config.value().has_pac_url();
- pac_sources_ = BuildPacSourcesFallbackList(config);
+ pac_sources_ = BuildPacSourcesFallbackList(config.value());
DCHECK(!pac_sources_.empty());
+ traffic_annotation_ =
+ net::MutableNetworkTrafficAnnotationTag(config.traffic_annotation());
next_state_ = STATE_WAIT;
int rv = DoLoop(OK);
@@ -133,7 +134,7 @@ int ProxyScriptDecider::Start(const ProxyConfig& config,
return rv;
}
-void ProxyScriptDecider::OnShutdown() {
+void PacFileDecider::OnShutdown() {
// Don't do anything if idle.
if (next_state_ == STATE_NONE)
return;
@@ -147,13 +148,12 @@ void ProxyScriptDecider::OnShutdown() {
callback.Run(ERR_CONTEXT_SHUT_DOWN);
}
-const ProxyConfig& ProxyScriptDecider::effective_config() const {
+const ProxyConfigWithAnnotation& PacFileDecider::effective_config() const {
DCHECK_EQ(STATE_NONE, next_state_);
return effective_config_;
}
-const scoped_refptr<ProxyResolverScriptData>& ProxyScriptDecider::script_data()
- const {
+const scoped_refptr<PacFileData>& PacFileDecider::script_data() const {
DCHECK_EQ(STATE_NONE, next_state_);
return script_data_;
}
@@ -162,8 +162,7 @@ const scoped_refptr<ProxyResolverScriptData>& ProxyScriptDecider::script_data()
// (1) WPAD (DHCP).
// (2) WPAD (DNS).
// (3) Custom PAC URL.
-ProxyScriptDecider::PacSourceList
-ProxyScriptDecider::BuildPacSourcesFallbackList(
+PacFileDecider::PacSourceList PacFileDecider::BuildPacSourcesFallbackList(
const ProxyConfig& config) const {
PacSourceList pac_sources;
if (config.auto_detect()) {
@@ -175,7 +174,7 @@ ProxyScriptDecider::BuildPacSourcesFallbackList(
return pac_sources;
}
-void ProxyScriptDecider::OnIOCompletion(int result) {
+void PacFileDecider::OnIOCompletion(int result) {
DCHECK_NE(STATE_NONE, next_state_);
int rv = DoLoop(result);
if (rv != ERR_IO_PENDING) {
@@ -184,7 +183,7 @@ void ProxyScriptDecider::OnIOCompletion(int result) {
}
}
-int ProxyScriptDecider::DoLoop(int result) {
+int PacFileDecider::DoLoop(int result) {
DCHECK_NE(next_state_, STATE_NONE);
int rv = result;
do {
@@ -228,13 +227,13 @@ int ProxyScriptDecider::DoLoop(int result) {
return rv;
}
-void ProxyScriptDecider::DoCallback(int result) {
+void PacFileDecider::DoCallback(int result) {
DCHECK_NE(ERR_IO_PENDING, result);
DCHECK(!callback_.is_null());
callback_.Run(result);
}
-int ProxyScriptDecider::DoWait() {
+int PacFileDecider::DoWait() {
next_state_ = STATE_WAIT_COMPLETE;
// If no waiting is required, continue on to the next state.
@@ -243,16 +242,16 @@ int ProxyScriptDecider::DoWait() {
// Otherwise wait the specified amount of time.
wait_timer_.Start(FROM_HERE, wait_delay_, this,
- &ProxyScriptDecider::OnWaitTimerFired);
- net_log_.BeginEvent(NetLogEventType::PROXY_SCRIPT_DECIDER_WAIT);
+ &PacFileDecider::OnWaitTimerFired);
+ net_log_.BeginEvent(NetLogEventType::PAC_FILE_DECIDER_WAIT);
return ERR_IO_PENDING;
}
-int ProxyScriptDecider::DoWaitComplete(int result) {
+int PacFileDecider::DoWaitComplete(int result) {
DCHECK_EQ(OK, result);
if (wait_delay_.ToInternalValue() != 0) {
- net_log_.EndEventWithNetErrorCode(
- NetLogEventType::PROXY_SCRIPT_DECIDER_WAIT, result);
+ net_log_.EndEventWithNetErrorCode(NetLogEventType::PAC_FILE_DECIDER_WAIT,
+ result);
}
if (quick_check_enabled_ && current_pac_source().type == PacSource::WPAD_DNS)
next_state_ = STATE_QUICK_CHECK;
@@ -261,10 +260,10 @@ int ProxyScriptDecider::DoWaitComplete(int result) {
return OK;
}
-int ProxyScriptDecider::DoQuickCheck() {
+int PacFileDecider::DoQuickCheck() {
DCHECK(quick_check_enabled_);
- if (!proxy_script_fetcher_ || !proxy_script_fetcher_->GetRequestContext() ||
- !proxy_script_fetcher_->GetRequestContext()->host_resolver()) {
+ if (!pac_file_fetcher_ || !pac_file_fetcher_->GetRequestContext() ||
+ !pac_file_fetcher_->GetRequestContext()->host_resolver()) {
// If we have no resolver, skip QuickCheck altogether.
next_state_ = GetStartState();
return OK;
@@ -275,7 +274,7 @@ int ProxyScriptDecider::DoQuickCheck() {
HostResolver::RequestInfo reqinfo(HostPortPair(host, 80));
reqinfo.set_host_resolver_flags(HOST_RESOLVER_SYSTEM_ONLY);
CompletionCallback callback =
- base::Bind(&ProxyScriptDecider::OnIOCompletion, base::Unretained(this));
+ base::Bind(&PacFileDecider::OnIOCompletion, base::Unretained(this));
next_state_ = STATE_QUICK_CHECK_COMPLETE;
quick_check_timer_.Start(
@@ -283,14 +282,14 @@ int ProxyScriptDecider::DoQuickCheck() {
base::Bind(callback, ERR_NAME_NOT_RESOLVED));
HostResolver* host_resolver =
- proxy_script_fetcher_->GetRequestContext()->host_resolver();
+ pac_file_fetcher_->GetRequestContext()->host_resolver();
// We use HIGHEST here because proxy decision blocks doing any other requests.
return host_resolver->Resolve(reqinfo, HIGHEST, &wpad_addresses_, callback,
&request_, net_log_);
}
-int ProxyScriptDecider::DoQuickCheckComplete(int result) {
+int PacFileDecider::DoQuickCheckComplete(int result) {
DCHECK(quick_check_enabled_);
base::TimeDelta delta = base::Time::Now() - quick_check_start_time_;
if (result == OK)
@@ -305,7 +304,7 @@ int ProxyScriptDecider::DoQuickCheckComplete(int result) {
return result;
}
-int ProxyScriptDecider::DoFetchPacScript() {
+int PacFileDecider::DoFetchPacScript() {
DCHECK(fetch_pac_bytes_);
next_state_ = STATE_FETCH_PAC_SCRIPT_COMPLETE;
@@ -316,36 +315,38 @@ int ProxyScriptDecider::DoFetchPacScript() {
DetermineURL(pac_source, &effective_pac_url);
net_log_.BeginEvent(
- NetLogEventType::PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT,
+ NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT,
base::Bind(&PacSource::NetLogCallback, base::Unretained(&pac_source),
&effective_pac_url));
if (pac_source.type == PacSource::WPAD_DHCP) {
- if (!dhcp_proxy_script_fetcher_) {
- net_log_.AddEvent(NetLogEventType::PROXY_SCRIPT_DECIDER_HAS_NO_FETCHER);
+ if (!dhcp_pac_file_fetcher_) {
+ net_log_.AddEvent(NetLogEventType::PAC_FILE_DECIDER_HAS_NO_FETCHER);
return ERR_UNEXPECTED;
}
- return dhcp_proxy_script_fetcher_->Fetch(
- &pac_script_, base::Bind(&ProxyScriptDecider::OnIOCompletion,
- base::Unretained(this)));
+ return dhcp_pac_file_fetcher_->Fetch(
+ &pac_script_,
+ base::Bind(&PacFileDecider::OnIOCompletion, base::Unretained(this)),
+ net_log_, NetworkTrafficAnnotationTag(traffic_annotation_));
}
- if (!proxy_script_fetcher_) {
- net_log_.AddEvent(NetLogEventType::PROXY_SCRIPT_DECIDER_HAS_NO_FETCHER);
+ if (!pac_file_fetcher_) {
+ net_log_.AddEvent(NetLogEventType::PAC_FILE_DECIDER_HAS_NO_FETCHER);
return ERR_UNEXPECTED;
}
- return proxy_script_fetcher_->Fetch(
+ return pac_file_fetcher_->Fetch(
effective_pac_url, &pac_script_,
- base::Bind(&ProxyScriptDecider::OnIOCompletion, base::Unretained(this)));
+ base::Bind(&PacFileDecider::OnIOCompletion, base::Unretained(this)),
+ NetworkTrafficAnnotationTag(traffic_annotation_));
}
-int ProxyScriptDecider::DoFetchPacScriptComplete(int result) {
+int PacFileDecider::DoFetchPacScriptComplete(int result) {
DCHECK(fetch_pac_bytes_);
net_log_.EndEventWithNetErrorCode(
- NetLogEventType::PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT, result);
+ NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT, result);
if (result != OK)
return TryToFallbackPacSource(result);
@@ -353,7 +354,7 @@ int ProxyScriptDecider::DoFetchPacScriptComplete(int result) {
return result;
}
-int ProxyScriptDecider::DoVerifyPacScript() {
+int PacFileDecider::DoVerifyPacScript() {
next_state_ = STATE_VERIFY_PAC_SCRIPT_COMPLETE;
// This is just a heuristic. Ideally we would try to parse the script.
@@ -363,7 +364,7 @@ int ProxyScriptDecider::DoVerifyPacScript() {
return OK;
}
-int ProxyScriptDecider::DoVerifyPacScriptComplete(int result) {
+int PacFileDecider::DoVerifyPacScriptComplete(int result) {
if (result != OK)
return TryToFallbackPacSource(result);
@@ -371,26 +372,26 @@ int ProxyScriptDecider::DoVerifyPacScriptComplete(int result) {
// Extract the current script data.
if (fetch_pac_bytes_) {
- script_data_ = ProxyResolverScriptData::FromUTF16(pac_script_);
+ script_data_ = PacFileData::FromUTF16(pac_script_);
} else {
script_data_ = pac_source.type == PacSource::CUSTOM
- ? ProxyResolverScriptData::FromURL(pac_source.url)
- : ProxyResolverScriptData::ForAutoDetect();
+ ? PacFileData::FromURL(pac_source.url)
+ : PacFileData::ForAutoDetect();
}
// Let the caller know which automatic setting we ended up initializing the
// resolver for (there may have been multiple fallbacks to choose from.)
+ ProxyConfig config;
if (current_pac_source().type == PacSource::CUSTOM) {
- effective_config_ =
- ProxyConfig::CreateFromCustomPacURL(current_pac_source().url);
- effective_config_.set_pac_mandatory(pac_mandatory_);
+ config = ProxyConfig::CreateFromCustomPacURL(current_pac_source().url);
+ config.set_pac_mandatory(pac_mandatory_);
} else {
if (fetch_pac_bytes_) {
GURL auto_detected_url;
switch (current_pac_source().type) {
case PacSource::WPAD_DHCP:
- auto_detected_url = dhcp_proxy_script_fetcher_->GetPacURL();
+ auto_detected_url = dhcp_pac_file_fetcher_->GetPacURL();
break;
case PacSource::WPAD_DNS:
@@ -401,20 +402,22 @@ int ProxyScriptDecider::DoVerifyPacScriptComplete(int result) {
NOTREACHED();
}
- effective_config_ =
- ProxyConfig::CreateFromCustomPacURL(auto_detected_url);
+ config = ProxyConfig::CreateFromCustomPacURL(auto_detected_url);
} else {
// The resolver does its own resolution so we cannot know the
// URL. Just do the best we can and state that the configuration
// is to auto-detect proxy settings.
- effective_config_ = ProxyConfig::CreateAutoDetect();
+ config = ProxyConfig::CreateAutoDetect();
}
}
+ effective_config_ = ProxyConfigWithAnnotation(
+ config, net::NetworkTrafficAnnotationTag(traffic_annotation_));
+
return OK;
}
-int ProxyScriptDecider::TryToFallbackPacSource(int error) {
+int PacFileDecider::TryToFallbackPacSource(int error) {
DCHECK_LT(error, 0);
if (current_pac_source_index_ + 1 >= pac_sources_.size()) {
@@ -426,7 +429,7 @@ int ProxyScriptDecider::TryToFallbackPacSource(int error) {
++current_pac_source_index_;
net_log_.AddEvent(
- NetLogEventType::PROXY_SCRIPT_DECIDER_FALLING_BACK_TO_NEXT_PAC_SOURCE);
+ NetLogEventType::PAC_FILE_DECIDER_FALLING_BACK_TO_NEXT_PAC_SOURCE);
if (quick_check_enabled_ && current_pac_source().type == PacSource::WPAD_DNS)
next_state_ = STATE_QUICK_CHECK;
else
@@ -435,12 +438,12 @@ int ProxyScriptDecider::TryToFallbackPacSource(int error) {
return OK;
}
-ProxyScriptDecider::State ProxyScriptDecider::GetStartState() const {
+PacFileDecider::State PacFileDecider::GetStartState() const {
return fetch_pac_bytes_ ? STATE_FETCH_PAC_SCRIPT : STATE_VERIFY_PAC_SCRIPT;
}
-void ProxyScriptDecider::DetermineURL(const PacSource& pac_source,
- GURL* effective_pac_url) {
+void PacFileDecider::DetermineURL(const PacSource& pac_source,
+ GURL* effective_pac_url) {
DCHECK(effective_pac_url);
switch (pac_source.type) {
@@ -455,21 +458,20 @@ void ProxyScriptDecider::DetermineURL(const PacSource& pac_source,
}
}
-const ProxyScriptDecider::PacSource& ProxyScriptDecider::current_pac_source()
- const {
+const PacFileDecider::PacSource& PacFileDecider::current_pac_source() const {
DCHECK_LT(current_pac_source_index_, pac_sources_.size());
return pac_sources_[current_pac_source_index_];
}
-void ProxyScriptDecider::OnWaitTimerFired() {
+void PacFileDecider::OnWaitTimerFired() {
OnIOCompletion(OK);
}
-void ProxyScriptDecider::DidComplete() {
- net_log_.EndEvent(NetLogEventType::PROXY_SCRIPT_DECIDER);
+void PacFileDecider::DidComplete() {
+ net_log_.EndEvent(NetLogEventType::PAC_FILE_DECIDER);
}
-void ProxyScriptDecider::Cancel() {
+void PacFileDecider::Cancel() {
DCHECK_NE(STATE_NONE, next_state_);
net_log_.AddEvent(NetLogEventType::CANCELLED);
@@ -482,7 +484,7 @@ void ProxyScriptDecider::Cancel() {
wait_timer_.Stop();
break;
case STATE_FETCH_PAC_SCRIPT_COMPLETE:
- proxy_script_fetcher_->Cancel();
+ pac_file_fetcher_->Cancel();
break;
default:
break;
@@ -491,8 +493,8 @@ void ProxyScriptDecider::Cancel() {
next_state_ = STATE_NONE;
// This is safe to call in any state.
- if (dhcp_proxy_script_fetcher_)
- dhcp_proxy_script_fetcher_->Cancel();
+ if (dhcp_pac_file_fetcher_)
+ dhcp_pac_file_fetcher_->Cancel();
DCHECK(!request_);
diff --git a/chromium/net/proxy_resolution/pac_file_decider.h b/chromium/net/proxy_resolution/pac_file_decider.h
index 82ec9f1983d..90d5ed9ec4a 100644
--- a/chromium/net/proxy_resolution/pac_file_decider.h
+++ b/chromium/net/proxy_resolution/pac_file_decider.h
@@ -20,7 +20,7 @@
#include "net/base/net_export.h"
#include "net/dns/host_resolver.h"
#include "net/log/net_log_with_source.h"
-#include "net/proxy_resolution/proxy_config.h"
+#include "net/proxy_resolution/proxy_config_with_annotation.h"
#include "net/proxy_resolution/proxy_resolver.h"
#include "url/gurl.h"
@@ -30,13 +30,13 @@ class Value;
namespace net {
-class DhcpProxyScriptFetcher;
+class DhcpPacFileFetcher;
class NetLog;
class NetLogCaptureMode;
class ProxyResolver;
-class ProxyScriptFetcher;
+class PacFileFetcher;
-// ProxyScriptDecider is a helper class used by ProxyResolutionService to
+// PacFileDecider is a helper class used by ProxyResolutionService to
// determine which PAC script to use given our proxy configuration.
//
// This involves trying to use PAC scripts in this order:
@@ -52,19 +52,19 @@ class ProxyScriptFetcher;
// On successful completion, the fetched PAC script data can be accessed using
// script_data().
//
-// Deleting ProxyScriptDecider while Init() is in progress, will
+// Deleting PacFileDecider while Init() is in progress, will
// cancel the request.
//
-class NET_EXPORT_PRIVATE ProxyScriptDecider {
+class NET_EXPORT_PRIVATE PacFileDecider {
public:
- // |proxy_script_fetcher|, |dhcp_proxy_script_fetcher| and
- // |net_log| must remain valid for the lifespan of ProxyScriptDecider.
- ProxyScriptDecider(ProxyScriptFetcher* proxy_script_fetcher,
- DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher,
- NetLog* net_log);
+ // |pac_file_fetcher|, |dhcp_pac_file_fetcher| and
+ // |net_log| must remain valid for the lifespan of PacFileDecider.
+ PacFileDecider(PacFileFetcher* pac_file_fetcher,
+ DhcpPacFileFetcher* dhcp_pac_file_fetcher,
+ NetLog* net_log);
// Aborts any in-progress request.
- ~ProxyScriptDecider();
+ ~PacFileDecider();
// Evaluates the effective proxy settings for |config|, and downloads the
// associated PAC script.
@@ -76,18 +76,18 @@ class NET_EXPORT_PRIVATE ProxyScriptDecider {
// manual settings, and decided whether to use auto-detect or the custom PAC
// URL. Finally, if auto-detect was used we may now have resolved that to a
// specific script URL.
- int Start(const ProxyConfig& config,
+ int Start(const ProxyConfigWithAnnotation& config,
const base::TimeDelta wait_delay,
bool fetch_pac_bytes,
const CompletionCallback& callback);
// Shuts down any in-progress DNS requests, and cancels any ScriptFetcher
- // requests. Does not call OnShutdown on the [Dhcp]ProxyScriptFetcher.
+ // requests. Does not call OnShutdown on the [Dhcp]PacFileFetcher.
void OnShutdown();
- const ProxyConfig& effective_config() const;
+ const ProxyConfigWithAnnotation& effective_config() const;
- const scoped_refptr<ProxyResolverScriptData>& script_data() const;
+ const scoped_refptr<PacFileData>& script_data() const;
void set_quick_check_enabled(bool enabled) { quick_check_enabled_ = enabled; }
@@ -164,8 +164,8 @@ class NET_EXPORT_PRIVATE ProxyScriptDecider {
void DidComplete();
void Cancel();
- ProxyScriptFetcher* proxy_script_fetcher_;
- DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher_;
+ PacFileFetcher* pac_file_fetcher_;
+ DhcpPacFileFetcher* dhcp_pac_file_fetcher_;
CompletionCallback callback_;
@@ -174,7 +174,7 @@ class NET_EXPORT_PRIVATE ProxyScriptDecider {
// Filled when the PAC script fetch completes.
base::string16 pac_script_;
- // Flag indicating whether the caller requested a mandatory pac script
+ // Flag indicating whether the caller requested a mandatory PAC script
// (i.e. fallback to direct connections are prohibited).
bool pac_mandatory_;
@@ -191,19 +191,21 @@ class NET_EXPORT_PRIVATE ProxyScriptDecider {
base::TimeDelta wait_delay_;
base::OneShotTimer wait_timer_;
+ net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
+
// Whether to do DNS quick check
bool quick_check_enabled_;
// Results.
- ProxyConfig effective_config_;
- scoped_refptr<ProxyResolverScriptData> script_data_;
+ ProxyConfigWithAnnotation effective_config_;
+ scoped_refptr<PacFileData> script_data_;
AddressList wpad_addresses_;
base::OneShotTimer quick_check_timer_;
std::unique_ptr<HostResolver::Request> request_;
base::Time quick_check_start_time_;
- DISALLOW_COPY_AND_ASSIGN(ProxyScriptDecider);
+ DISALLOW_COPY_AND_ASSIGN(PacFileDecider);
};
} // namespace net
diff --git a/chromium/net/proxy_resolution/pac_file_decider_unittest.cc b/chromium/net/proxy_resolution/pac_file_decider_unittest.cc
index 4d7a392e0b7..fed25de8dc9 100644
--- a/chromium/net/proxy_resolution/pac_file_decider_unittest.cc
+++ b/chromium/net/proxy_resolution/pac_file_decider_unittest.cc
@@ -28,6 +28,7 @@
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_resolver.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_context.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -104,19 +105,20 @@ class Rules {
RuleList rules_;
};
-class RuleBasedProxyScriptFetcher : public ProxyScriptFetcher {
+class RuleBasedPacFileFetcher : public PacFileFetcher {
public:
- explicit RuleBasedProxyScriptFetcher(const Rules* rules)
+ explicit RuleBasedPacFileFetcher(const Rules* rules)
: rules_(rules), request_context_(NULL) {}
virtual void SetRequestContext(URLRequestContext* context) {
request_context_ = context;
}
- // ProxyScriptFetcher implementation.
+ // PacFileFetcher implementation.
int Fetch(const GURL& url,
base::string16* text,
- const CompletionCallback& callback) override {
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag traffic_annotation) override {
const Rules::Rule& rule = rules_->GetRuleByUrl(url);
int rv = rule.fetch_error;
EXPECT_NE(ERR_UNEXPECTED, rv);
@@ -139,13 +141,15 @@ class RuleBasedProxyScriptFetcher : public ProxyScriptFetcher {
};
// A mock retriever, returns asynchronously when CompleteRequests() is called.
-class MockDhcpProxyScriptFetcher : public DhcpProxyScriptFetcher {
+class MockDhcpPacFileFetcher : public DhcpPacFileFetcher {
public:
- MockDhcpProxyScriptFetcher();
- ~MockDhcpProxyScriptFetcher() override;
+ MockDhcpPacFileFetcher();
+ ~MockDhcpPacFileFetcher() override;
int Fetch(base::string16* utf16_text,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetLogWithSource& net_log,
+ const NetworkTrafficAnnotationTag traffic_annotation) override;
void Cancel() override;
void OnShutdown() override;
const GURL& GetPacURL() const override;
@@ -158,44 +162,46 @@ class MockDhcpProxyScriptFetcher : public DhcpProxyScriptFetcher {
CompletionCallback callback_;
base::string16* utf16_text_;
GURL gurl_;
- DISALLOW_COPY_AND_ASSIGN(MockDhcpProxyScriptFetcher);
+ DISALLOW_COPY_AND_ASSIGN(MockDhcpPacFileFetcher);
};
-MockDhcpProxyScriptFetcher::MockDhcpProxyScriptFetcher() = default;
+MockDhcpPacFileFetcher::MockDhcpPacFileFetcher() = default;
-MockDhcpProxyScriptFetcher::~MockDhcpProxyScriptFetcher() = default;
+MockDhcpPacFileFetcher::~MockDhcpPacFileFetcher() = default;
-int MockDhcpProxyScriptFetcher::Fetch(base::string16* utf16_text,
- const CompletionCallback& callback) {
+int MockDhcpPacFileFetcher::Fetch(
+ base::string16* utf16_text,
+ const CompletionCallback& callback,
+ const NetLogWithSource& net_log,
+ const NetworkTrafficAnnotationTag traffic_annotation) {
utf16_text_ = utf16_text;
callback_ = callback;
return ERR_IO_PENDING;
}
-void MockDhcpProxyScriptFetcher::Cancel() {}
+void MockDhcpPacFileFetcher::Cancel() {}
-void MockDhcpProxyScriptFetcher::OnShutdown() {}
+void MockDhcpPacFileFetcher::OnShutdown() {}
-const GURL& MockDhcpProxyScriptFetcher::GetPacURL() const {
+const GURL& MockDhcpPacFileFetcher::GetPacURL() const {
return gurl_;
}
-void MockDhcpProxyScriptFetcher::SetPacURL(const GURL& url) {
+void MockDhcpPacFileFetcher::SetPacURL(const GURL& url) {
gurl_ = url;
}
-void MockDhcpProxyScriptFetcher::CompleteRequests(
- int result,
- const base::string16& script) {
+void MockDhcpPacFileFetcher::CompleteRequests(int result,
+ const base::string16& script) {
*utf16_text_ = script;
callback_.Run(result);
}
// Succeed using custom PAC script.
-TEST(ProxyScriptDeciderTest, CustomPacSucceeds) {
+TEST(PacFileDeciderTest, CustomPacSucceeds) {
Rules rules;
- RuleBasedProxyScriptFetcher fetcher(&rules);
- DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+ RuleBasedPacFileFetcher fetcher(&rules);
+ DoNothingDhcpPacFileFetcher dhcp_fetcher;
ProxyConfig config;
config.set_pac_url(GURL("http://custom/proxy.pac"));
@@ -204,9 +210,10 @@ TEST(ProxyScriptDeciderTest, CustomPacSucceeds) {
TestCompletionCallback callback;
TestNetLog log;
- ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, &log);
- EXPECT_EQ(
- OK, decider.Start(config, base::TimeDelta(), true, callback.callback()));
+ PacFileDecider decider(&fetcher, &dhcp_fetcher, &log);
+ EXPECT_EQ(OK, decider.Start(ProxyConfigWithAnnotation(
+ config, TRAFFIC_ANNOTATION_FOR_TESTS),
+ base::TimeDelta(), true, callback.callback()));
EXPECT_EQ(rule.text(), decider.script_data()->utf16());
// Check the NetLog was filled correctly.
@@ -215,23 +222,23 @@ TEST(ProxyScriptDeciderTest, CustomPacSucceeds) {
EXPECT_EQ(4u, entries.size());
EXPECT_TRUE(
- LogContainsBeginEvent(entries, 0, NetLogEventType::PROXY_SCRIPT_DECIDER));
+ LogContainsBeginEvent(entries, 0, NetLogEventType::PAC_FILE_DECIDER));
EXPECT_TRUE(LogContainsBeginEvent(
- entries, 1, NetLogEventType::PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+ entries, 1, NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT));
EXPECT_TRUE(LogContainsEndEvent(
- entries, 2, NetLogEventType::PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+ entries, 2, NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT));
EXPECT_TRUE(
- LogContainsEndEvent(entries, 3, NetLogEventType::PROXY_SCRIPT_DECIDER));
+ LogContainsEndEvent(entries, 3, NetLogEventType::PAC_FILE_DECIDER));
- EXPECT_TRUE(decider.effective_config().has_pac_url());
- EXPECT_EQ(config.pac_url(), decider.effective_config().pac_url());
+ EXPECT_TRUE(decider.effective_config().value().has_pac_url());
+ EXPECT_EQ(config.pac_url(), decider.effective_config().value().pac_url());
}
// Fail downloading the custom PAC script.
-TEST(ProxyScriptDeciderTest, CustomPacFails1) {
+TEST(PacFileDeciderTest, CustomPacFails1) {
Rules rules;
- RuleBasedProxyScriptFetcher fetcher(&rules);
- DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+ RuleBasedPacFileFetcher fetcher(&rules);
+ DoNothingDhcpPacFileFetcher dhcp_fetcher;
ProxyConfig config;
config.set_pac_url(GURL("http://custom/proxy.pac"));
@@ -240,9 +247,11 @@ TEST(ProxyScriptDeciderTest, CustomPacFails1) {
TestCompletionCallback callback;
TestNetLog log;
- ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, &log);
- EXPECT_EQ(kFailedDownloading, decider.Start(config, base::TimeDelta(), true,
- callback.callback()));
+ PacFileDecider decider(&fetcher, &dhcp_fetcher, &log);
+ EXPECT_EQ(kFailedDownloading,
+ decider.Start(
+ ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS),
+ base::TimeDelta(), true, callback.callback()));
EXPECT_FALSE(decider.script_data());
// Check the NetLog was filled correctly.
@@ -251,22 +260,22 @@ TEST(ProxyScriptDeciderTest, CustomPacFails1) {
EXPECT_EQ(4u, entries.size());
EXPECT_TRUE(
- LogContainsBeginEvent(entries, 0, NetLogEventType::PROXY_SCRIPT_DECIDER));
+ LogContainsBeginEvent(entries, 0, NetLogEventType::PAC_FILE_DECIDER));
EXPECT_TRUE(LogContainsBeginEvent(
- entries, 1, NetLogEventType::PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+ entries, 1, NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT));
EXPECT_TRUE(LogContainsEndEvent(
- entries, 2, NetLogEventType::PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+ entries, 2, NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT));
EXPECT_TRUE(
- LogContainsEndEvent(entries, 3, NetLogEventType::PROXY_SCRIPT_DECIDER));
+ LogContainsEndEvent(entries, 3, NetLogEventType::PAC_FILE_DECIDER));
- EXPECT_FALSE(decider.effective_config().has_pac_url());
+ EXPECT_FALSE(decider.effective_config().value().has_pac_url());
}
// Fail parsing the custom PAC script.
-TEST(ProxyScriptDeciderTest, CustomPacFails2) {
+TEST(PacFileDeciderTest, CustomPacFails2) {
Rules rules;
- RuleBasedProxyScriptFetcher fetcher(&rules);
- DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+ RuleBasedPacFileFetcher fetcher(&rules);
+ DoNothingDhcpPacFileFetcher dhcp_fetcher;
ProxyConfig config;
config.set_pac_url(GURL("http://custom/proxy.pac"));
@@ -274,32 +283,36 @@ TEST(ProxyScriptDeciderTest, CustomPacFails2) {
rules.AddFailParsingRule("http://custom/proxy.pac");
TestCompletionCallback callback;
- ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, NULL);
- EXPECT_EQ(kFailedParsing, decider.Start(config, base::TimeDelta(), true,
- callback.callback()));
+ PacFileDecider decider(&fetcher, &dhcp_fetcher, NULL);
+ EXPECT_EQ(kFailedParsing,
+ decider.Start(
+ ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS),
+ base::TimeDelta(), true, callback.callback()));
EXPECT_FALSE(decider.script_data());
}
// Fail downloading the custom PAC script, because the fetcher was NULL.
-TEST(ProxyScriptDeciderTest, HasNullProxyScriptFetcher) {
+TEST(PacFileDeciderTest, HasNullPacFileFetcher) {
Rules rules;
- DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+ DoNothingDhcpPacFileFetcher dhcp_fetcher;
ProxyConfig config;
config.set_pac_url(GURL("http://custom/proxy.pac"));
TestCompletionCallback callback;
- ProxyScriptDecider decider(NULL, &dhcp_fetcher, NULL);
- EXPECT_EQ(ERR_UNEXPECTED, decider.Start(config, base::TimeDelta(), true,
- callback.callback()));
+ PacFileDecider decider(NULL, &dhcp_fetcher, NULL);
+ EXPECT_EQ(ERR_UNEXPECTED,
+ decider.Start(
+ ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS),
+ base::TimeDelta(), true, callback.callback()));
EXPECT_FALSE(decider.script_data());
}
// Succeeds in choosing autodetect (WPAD DNS).
-TEST(ProxyScriptDeciderTest, AutodetectSuccess) {
+TEST(PacFileDeciderTest, AutodetectSuccess) {
Rules rules;
- RuleBasedProxyScriptFetcher fetcher(&rules);
- DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+ RuleBasedPacFileFetcher fetcher(&rules);
+ DoNothingDhcpPacFileFetcher dhcp_fetcher;
ProxyConfig config;
config.set_auto_detect(true);
@@ -307,18 +320,19 @@ TEST(ProxyScriptDeciderTest, AutodetectSuccess) {
Rules::Rule rule = rules.AddSuccessRule("http://wpad/wpad.dat");
TestCompletionCallback callback;
- ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, NULL);
- EXPECT_EQ(
- OK, decider.Start(config, base::TimeDelta(), true, callback.callback()));
+ PacFileDecider decider(&fetcher, &dhcp_fetcher, NULL);
+ EXPECT_EQ(OK, decider.Start(ProxyConfigWithAnnotation(
+ config, TRAFFIC_ANNOTATION_FOR_TESTS),
+ base::TimeDelta(), true, callback.callback()));
EXPECT_EQ(rule.text(), decider.script_data()->utf16());
- EXPECT_TRUE(decider.effective_config().has_pac_url());
- EXPECT_EQ(rule.url, decider.effective_config().pac_url());
+ EXPECT_TRUE(decider.effective_config().value().has_pac_url());
+ EXPECT_EQ(rule.url, decider.effective_config().value().pac_url());
}
-class ProxyScriptDeciderQuickCheckTest : public ::testing::Test {
+class PacFileDeciderQuickCheckTest : public ::testing::Test {
public:
- ProxyScriptDeciderQuickCheckTest()
+ PacFileDeciderQuickCheckTest()
: rule_(rules_.AddSuccessRule("http://wpad/wpad.dat")),
fetcher_(&rules_) {}
@@ -326,12 +340,13 @@ class ProxyScriptDeciderQuickCheckTest : public ::testing::Test {
request_context_.set_host_resolver(&resolver_);
fetcher_.SetRequestContext(&request_context_);
config_.set_auto_detect(true);
- decider_.reset(new ProxyScriptDecider(&fetcher_, &dhcp_fetcher_, NULL));
+ decider_.reset(new PacFileDecider(&fetcher_, &dhcp_fetcher_, NULL));
}
int StartDecider() {
- return decider_->Start(config_, base::TimeDelta(), true,
- callback_.callback());
+ return decider_->Start(
+ ProxyConfigWithAnnotation(config_, TRAFFIC_ANNOTATION_FOR_TESTS),
+ base::TimeDelta(), true, callback_.callback());
}
protected:
@@ -339,30 +354,30 @@ class ProxyScriptDeciderQuickCheckTest : public ::testing::Test {
Rules rules_;
Rules::Rule rule_;
TestCompletionCallback callback_;
- RuleBasedProxyScriptFetcher fetcher_;
+ RuleBasedPacFileFetcher fetcher_;
ProxyConfig config_;
- DoNothingDhcpProxyScriptFetcher dhcp_fetcher_;
- std::unique_ptr<ProxyScriptDecider> decider_;
+ DoNothingDhcpPacFileFetcher dhcp_fetcher_;
+ std::unique_ptr<PacFileDecider> decider_;
private:
URLRequestContext request_context_;
};
// Fails if a synchronous DNS lookup success for wpad causes QuickCheck to fail.
-TEST_F(ProxyScriptDeciderQuickCheckTest, SyncSuccess) {
+TEST_F(PacFileDeciderQuickCheckTest, SyncSuccess) {
resolver_.set_synchronous_mode(true);
resolver_.rules()->AddRule("wpad", "1.2.3.4");
EXPECT_THAT(StartDecider(), IsOk());
EXPECT_EQ(rule_.text(), decider_->script_data()->utf16());
- EXPECT_TRUE(decider_->effective_config().has_pac_url());
- EXPECT_EQ(rule_.url, decider_->effective_config().pac_url());
+ EXPECT_TRUE(decider_->effective_config().value().has_pac_url());
+ EXPECT_EQ(rule_.url, decider_->effective_config().value().pac_url());
}
// Fails if an asynchronous DNS lookup success for wpad causes QuickCheck to
// fail.
-TEST_F(ProxyScriptDeciderQuickCheckTest, AsyncSuccess) {
+TEST_F(PacFileDeciderQuickCheckTest, AsyncSuccess) {
resolver_.set_ondemand_mode(true);
resolver_.rules()->AddRule("wpad", "1.2.3.4");
@@ -372,63 +387,63 @@ TEST_F(ProxyScriptDeciderQuickCheckTest, AsyncSuccess) {
callback_.WaitForResult();
EXPECT_FALSE(resolver_.has_pending_requests());
EXPECT_EQ(rule_.text(), decider_->script_data()->utf16());
- EXPECT_TRUE(decider_->effective_config().has_pac_url());
- EXPECT_EQ(rule_.url, decider_->effective_config().pac_url());
+ EXPECT_TRUE(decider_->effective_config().value().has_pac_url());
+ EXPECT_EQ(rule_.url, decider_->effective_config().value().pac_url());
}
// Fails if an asynchronous DNS lookup failure (i.e. an NXDOMAIN) still causes
-// ProxyScriptDecider to yield a PAC URL.
-TEST_F(ProxyScriptDeciderQuickCheckTest, AsyncFail) {
+// PacFileDecider to yield a PAC URL.
+TEST_F(PacFileDeciderQuickCheckTest, AsyncFail) {
resolver_.set_ondemand_mode(true);
resolver_.rules()->AddSimulatedFailure("wpad");
EXPECT_THAT(StartDecider(), IsError(ERR_IO_PENDING));
ASSERT_TRUE(resolver_.has_pending_requests());
resolver_.ResolveAllPending();
callback_.WaitForResult();
- EXPECT_FALSE(decider_->effective_config().has_pac_url());
+ EXPECT_FALSE(decider_->effective_config().value().has_pac_url());
}
-// Fails if a DNS lookup timeout either causes ProxyScriptDecider to yield a PAC
-// URL or causes ProxyScriptDecider not to cancel its pending resolution.
-TEST_F(ProxyScriptDeciderQuickCheckTest, AsyncTimeout) {
+// Fails if a DNS lookup timeout either causes PacFileDecider to yield a PAC
+// URL or causes PacFileDecider not to cancel its pending resolution.
+TEST_F(PacFileDeciderQuickCheckTest, AsyncTimeout) {
resolver_.set_ondemand_mode(true);
EXPECT_THAT(StartDecider(), IsError(ERR_IO_PENDING));
ASSERT_TRUE(resolver_.has_pending_requests());
callback_.WaitForResult();
EXPECT_FALSE(resolver_.has_pending_requests());
- EXPECT_FALSE(decider_->effective_config().has_pac_url());
+ EXPECT_FALSE(decider_->effective_config().value().has_pac_url());
}
// Fails if DHCP check doesn't take place before QuickCheck.
-TEST_F(ProxyScriptDeciderQuickCheckTest, QuickCheckInhibitsDhcp) {
- MockDhcpProxyScriptFetcher dhcp_fetcher;
+TEST_F(PacFileDeciderQuickCheckTest, QuickCheckInhibitsDhcp) {
+ MockDhcpPacFileFetcher dhcp_fetcher;
const char* kPac = "function FindProxyForURL(u,h) { return \"DIRECT\"; }";
base::string16 pac_contents = base::UTF8ToUTF16(kPac);
GURL url("http://foobar/baz");
dhcp_fetcher.SetPacURL(url);
- decider_.reset(new ProxyScriptDecider(&fetcher_, &dhcp_fetcher, NULL));
+ decider_.reset(new PacFileDecider(&fetcher_, &dhcp_fetcher, NULL));
EXPECT_THAT(StartDecider(), IsError(ERR_IO_PENDING));
dhcp_fetcher.CompleteRequests(OK, pac_contents);
- EXPECT_TRUE(decider_->effective_config().has_pac_url());
- EXPECT_EQ(decider_->effective_config().pac_url(), url);
+ EXPECT_TRUE(decider_->effective_config().value().has_pac_url());
+ EXPECT_EQ(decider_->effective_config().value().pac_url(), url);
}
// Fails if QuickCheck still happens when disabled. To ensure QuickCheck is not
// happening, we add a synchronous failing resolver, which would ordinarily
-// mean a QuickCheck failure, then ensure that our ProxyScriptFetcher is still
+// mean a QuickCheck failure, then ensure that our PacFileFetcher is still
// asked to fetch.
-TEST_F(ProxyScriptDeciderQuickCheckTest, QuickCheckDisabled) {
+TEST_F(PacFileDeciderQuickCheckTest, QuickCheckDisabled) {
const char* kPac = "function FindProxyForURL(u,h) { return \"DIRECT\"; }";
resolver_.set_synchronous_mode(true);
resolver_.rules()->AddSimulatedFailure("wpad");
- MockProxyScriptFetcher fetcher;
- decider_.reset(new ProxyScriptDecider(&fetcher, &dhcp_fetcher_, NULL));
+ MockPacFileFetcher fetcher;
+ decider_.reset(new PacFileDecider(&fetcher, &dhcp_fetcher_, NULL));
EXPECT_THAT(StartDecider(), IsError(ERR_IO_PENDING));
EXPECT_TRUE(fetcher.has_pending_request());
fetcher.NotifyFetchCompletion(OK, kPac);
}
-TEST_F(ProxyScriptDeciderQuickCheckTest, ExplicitPacUrl) {
+TEST_F(PacFileDeciderQuickCheckTest, ExplicitPacUrl) {
const char* kCustomUrl = "http://custom/proxy.pac";
config_.set_pac_url(GURL(kCustomUrl));
Rules::Rule rule = rules_.AddSuccessRule(kCustomUrl);
@@ -436,11 +451,11 @@ TEST_F(ProxyScriptDeciderQuickCheckTest, ExplicitPacUrl) {
resolver_.rules()->AddRule("custom", "1.2.3.4");
EXPECT_THAT(StartDecider(), IsError(ERR_IO_PENDING));
callback_.WaitForResult();
- EXPECT_TRUE(decider_->effective_config().has_pac_url());
- EXPECT_EQ(rule.url, decider_->effective_config().pac_url());
+ EXPECT_TRUE(decider_->effective_config().value().has_pac_url());
+ EXPECT_EQ(rule.url, decider_->effective_config().value().pac_url());
}
-TEST_F(ProxyScriptDeciderQuickCheckTest, ShutdownDuringResolve) {
+TEST_F(PacFileDeciderQuickCheckTest, ShutdownDuringResolve) {
resolver_.set_ondemand_mode(true);
EXPECT_THAT(StartDecider(), IsError(ERR_IO_PENDING));
@@ -454,7 +469,7 @@ TEST_F(ProxyScriptDeciderQuickCheckTest, ShutdownDuringResolve) {
// Regression test for http://crbug.com/409698.
// This test lets the state machine get into state QUICK_CHECK_COMPLETE, then
// destroys the decider, causing a cancel.
-TEST_F(ProxyScriptDeciderQuickCheckTest, CancelPartway) {
+TEST_F(PacFileDeciderQuickCheckTest, CancelPartway) {
resolver_.set_synchronous_mode(false);
resolver_.set_ondemand_mode(true);
EXPECT_THAT(StartDecider(), IsError(ERR_IO_PENDING));
@@ -462,10 +477,10 @@ TEST_F(ProxyScriptDeciderQuickCheckTest, CancelPartway) {
}
// Fails at WPAD (downloading), but succeeds in choosing the custom PAC.
-TEST(ProxyScriptDeciderTest, AutodetectFailCustomSuccess1) {
+TEST(PacFileDeciderTest, AutodetectFailCustomSuccess1) {
Rules rules;
- RuleBasedProxyScriptFetcher fetcher(&rules);
- DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+ RuleBasedPacFileFetcher fetcher(&rules);
+ DoNothingDhcpPacFileFetcher dhcp_fetcher;
ProxyConfig config;
config.set_auto_detect(true);
@@ -475,21 +490,22 @@ TEST(ProxyScriptDeciderTest, AutodetectFailCustomSuccess1) {
Rules::Rule rule = rules.AddSuccessRule("http://custom/proxy.pac");
TestCompletionCallback callback;
- ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, NULL);
- EXPECT_EQ(
- OK, decider.Start(config, base::TimeDelta(), true, callback.callback()));
+ PacFileDecider decider(&fetcher, &dhcp_fetcher, NULL);
+ EXPECT_EQ(OK, decider.Start(ProxyConfigWithAnnotation(
+ config, TRAFFIC_ANNOTATION_FOR_TESTS),
+ base::TimeDelta(), true, callback.callback()));
EXPECT_EQ(rule.text(), decider.script_data()->utf16());
- EXPECT_TRUE(decider.effective_config().has_pac_url());
- EXPECT_EQ(rule.url, decider.effective_config().pac_url());
+ EXPECT_TRUE(decider.effective_config().value().has_pac_url());
+ EXPECT_EQ(rule.url, decider.effective_config().value().pac_url());
}
// Fails at WPAD (no DHCP config, DNS PAC fails parsing), but succeeds in
// choosing the custom PAC.
-TEST(ProxyScriptDeciderTest, AutodetectFailCustomSuccess2) {
+TEST(PacFileDeciderTest, AutodetectFailCustomSuccess2) {
Rules rules;
- RuleBasedProxyScriptFetcher fetcher(&rules);
- DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+ RuleBasedPacFileFetcher fetcher(&rules);
+ DoNothingDhcpPacFileFetcher dhcp_fetcher;
ProxyConfig config;
config.set_auto_detect(true);
@@ -502,14 +518,15 @@ TEST(ProxyScriptDeciderTest, AutodetectFailCustomSuccess2) {
TestCompletionCallback callback;
TestNetLog log;
- ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, &log);
- EXPECT_EQ(
- OK, decider.Start(config, base::TimeDelta(), true, callback.callback()));
+ PacFileDecider decider(&fetcher, &dhcp_fetcher, &log);
+ EXPECT_EQ(OK, decider.Start(ProxyConfigWithAnnotation(
+ config, TRAFFIC_ANNOTATION_FOR_TESTS),
+ base::TimeDelta(), true, callback.callback()));
EXPECT_EQ(rule.text(), decider.script_data()->utf16());
// Verify that the effective configuration no longer contains auto detect or
// any of the manual settings.
- EXPECT_TRUE(decider.effective_config().Equals(
+ EXPECT_TRUE(decider.effective_config().value().Equals(
ProxyConfig::CreateFromCustomPacURL(GURL("http://custom/proxy.pac"))));
// Check the NetLog was filled correctly.
@@ -520,40 +537,40 @@ TEST(ProxyScriptDeciderTest, AutodetectFailCustomSuccess2) {
EXPECT_EQ(10u, entries.size());
EXPECT_TRUE(
- LogContainsBeginEvent(entries, 0, NetLogEventType::PROXY_SCRIPT_DECIDER));
+ LogContainsBeginEvent(entries, 0, NetLogEventType::PAC_FILE_DECIDER));
// This is the DHCP phase, which fails fetching rather than parsing, so
// there is no pair of SET_PAC_SCRIPT events.
EXPECT_TRUE(LogContainsBeginEvent(
- entries, 1, NetLogEventType::PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+ entries, 1, NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT));
EXPECT_TRUE(LogContainsEndEvent(
- entries, 2, NetLogEventType::PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+ entries, 2, NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT));
EXPECT_TRUE(LogContainsEvent(
entries, 3,
- NetLogEventType::PROXY_SCRIPT_DECIDER_FALLING_BACK_TO_NEXT_PAC_SOURCE,
+ NetLogEventType::PAC_FILE_DECIDER_FALLING_BACK_TO_NEXT_PAC_SOURCE,
NetLogEventPhase::NONE));
// This is the DNS phase, which attempts a fetch but fails.
EXPECT_TRUE(LogContainsBeginEvent(
- entries, 4, NetLogEventType::PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+ entries, 4, NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT));
EXPECT_TRUE(LogContainsEndEvent(
- entries, 5, NetLogEventType::PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+ entries, 5, NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT));
EXPECT_TRUE(LogContainsEvent(
entries, 6,
- NetLogEventType::PROXY_SCRIPT_DECIDER_FALLING_BACK_TO_NEXT_PAC_SOURCE,
+ NetLogEventType::PAC_FILE_DECIDER_FALLING_BACK_TO_NEXT_PAC_SOURCE,
NetLogEventPhase::NONE));
// Finally, the custom PAC URL phase.
EXPECT_TRUE(LogContainsBeginEvent(
- entries, 7, NetLogEventType::PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+ entries, 7, NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT));
EXPECT_TRUE(LogContainsEndEvent(
- entries, 8, NetLogEventType::PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+ entries, 8, NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT));
EXPECT_TRUE(
- LogContainsEndEvent(entries, 9, NetLogEventType::PROXY_SCRIPT_DECIDER));
+ LogContainsEndEvent(entries, 9, NetLogEventType::PAC_FILE_DECIDER));
}
// Fails at WPAD (downloading), and fails at custom PAC (downloading).
-TEST(ProxyScriptDeciderTest, AutodetectFailCustomFails1) {
+TEST(PacFileDeciderTest, AutodetectFailCustomFails1) {
Rules rules;
- RuleBasedProxyScriptFetcher fetcher(&rules);
- DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+ RuleBasedPacFileFetcher fetcher(&rules);
+ DoNothingDhcpPacFileFetcher dhcp_fetcher;
ProxyConfig config;
config.set_auto_detect(true);
@@ -563,17 +580,19 @@ TEST(ProxyScriptDeciderTest, AutodetectFailCustomFails1) {
rules.AddFailDownloadRule("http://custom/proxy.pac");
TestCompletionCallback callback;
- ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, NULL);
- EXPECT_EQ(kFailedDownloading, decider.Start(config, base::TimeDelta(), true,
- callback.callback()));
+ PacFileDecider decider(&fetcher, &dhcp_fetcher, NULL);
+ EXPECT_EQ(kFailedDownloading,
+ decider.Start(
+ ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS),
+ base::TimeDelta(), true, callback.callback()));
EXPECT_FALSE(decider.script_data());
}
// Fails at WPAD (downloading), and fails at custom PAC (parsing).
-TEST(ProxyScriptDeciderTest, AutodetectFailCustomFails2) {
+TEST(PacFileDeciderTest, AutodetectFailCustomFails2) {
Rules rules;
- RuleBasedProxyScriptFetcher fetcher(&rules);
- DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+ RuleBasedPacFileFetcher fetcher(&rules);
+ DoNothingDhcpPacFileFetcher dhcp_fetcher;
ProxyConfig config;
config.set_auto_detect(true);
@@ -583,19 +602,21 @@ TEST(ProxyScriptDeciderTest, AutodetectFailCustomFails2) {
rules.AddFailParsingRule("http://custom/proxy.pac");
TestCompletionCallback callback;
- ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, NULL);
- EXPECT_EQ(kFailedParsing, decider.Start(config, base::TimeDelta(), true,
- callback.callback()));
+ PacFileDecider decider(&fetcher, &dhcp_fetcher, NULL);
+ EXPECT_EQ(kFailedParsing,
+ decider.Start(
+ ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS),
+ base::TimeDelta(), true, callback.callback()));
EXPECT_FALSE(decider.script_data());
}
// This is a copy-paste of CustomPacFails1, with the exception that we give it
// a 1 millisecond delay. This means it will now complete asynchronously.
// Moreover, we test the NetLog to make sure it logged the pause.
-TEST(ProxyScriptDeciderTest, CustomPacFails1_WithPositiveDelay) {
+TEST(PacFileDeciderTest, CustomPacFails1_WithPositiveDelay) {
Rules rules;
- RuleBasedProxyScriptFetcher fetcher(&rules);
- DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+ RuleBasedPacFileFetcher fetcher(&rules);
+ DoNothingDhcpPacFileFetcher dhcp_fetcher;
ProxyConfig config;
config.set_pac_url(GURL("http://custom/proxy.pac"));
@@ -604,10 +625,12 @@ TEST(ProxyScriptDeciderTest, CustomPacFails1_WithPositiveDelay) {
TestCompletionCallback callback;
TestNetLog log;
- ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, &log);
- EXPECT_EQ(ERR_IO_PENDING,
- decider.Start(config, base::TimeDelta::FromMilliseconds(1), true,
- callback.callback()));
+ PacFileDecider decider(&fetcher, &dhcp_fetcher, &log);
+ EXPECT_EQ(
+ ERR_IO_PENDING,
+ decider.Start(
+ ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS),
+ base::TimeDelta::FromMilliseconds(1), true, callback.callback()));
EXPECT_EQ(kFailedDownloading, callback.WaitForResult());
EXPECT_FALSE(decider.script_data());
@@ -618,26 +641,26 @@ TEST(ProxyScriptDeciderTest, CustomPacFails1_WithPositiveDelay) {
EXPECT_EQ(6u, entries.size());
EXPECT_TRUE(
- LogContainsBeginEvent(entries, 0, NetLogEventType::PROXY_SCRIPT_DECIDER));
- EXPECT_TRUE(LogContainsBeginEvent(
- entries, 1, NetLogEventType::PROXY_SCRIPT_DECIDER_WAIT));
- EXPECT_TRUE(LogContainsEndEvent(entries, 2,
- NetLogEventType::PROXY_SCRIPT_DECIDER_WAIT));
+ LogContainsBeginEvent(entries, 0, NetLogEventType::PAC_FILE_DECIDER));
+ EXPECT_TRUE(LogContainsBeginEvent(entries, 1,
+ NetLogEventType::PAC_FILE_DECIDER_WAIT));
+ EXPECT_TRUE(
+ LogContainsEndEvent(entries, 2, NetLogEventType::PAC_FILE_DECIDER_WAIT));
EXPECT_TRUE(LogContainsBeginEvent(
- entries, 3, NetLogEventType::PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+ entries, 3, NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT));
EXPECT_TRUE(LogContainsEndEvent(
- entries, 4, NetLogEventType::PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+ entries, 4, NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT));
EXPECT_TRUE(
- LogContainsEndEvent(entries, 5, NetLogEventType::PROXY_SCRIPT_DECIDER));
+ LogContainsEndEvent(entries, 5, NetLogEventType::PAC_FILE_DECIDER));
}
// This is a copy-paste of CustomPacFails1, with the exception that we give it
// a -5 second delay instead of a 0 ms delay. This change should have no effect
// so the rest of the test is unchanged.
-TEST(ProxyScriptDeciderTest, CustomPacFails1_WithNegativeDelay) {
+TEST(PacFileDeciderTest, CustomPacFails1_WithNegativeDelay) {
Rules rules;
- RuleBasedProxyScriptFetcher fetcher(&rules);
- DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+ RuleBasedPacFileFetcher fetcher(&rules);
+ DoNothingDhcpPacFileFetcher dhcp_fetcher;
ProxyConfig config;
config.set_pac_url(GURL("http://custom/proxy.pac"));
@@ -646,10 +669,11 @@ TEST(ProxyScriptDeciderTest, CustomPacFails1_WithNegativeDelay) {
TestCompletionCallback callback;
TestNetLog log;
- ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, &log);
+ PacFileDecider decider(&fetcher, &dhcp_fetcher, &log);
EXPECT_EQ(kFailedDownloading,
- decider.Start(config, base::TimeDelta::FromSeconds(-5), true,
- callback.callback()));
+ decider.Start(
+ ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS),
+ base::TimeDelta::FromSeconds(-5), true, callback.callback()));
EXPECT_FALSE(decider.script_data());
// Check the NetLog was filled correctly.
@@ -658,22 +682,24 @@ TEST(ProxyScriptDeciderTest, CustomPacFails1_WithNegativeDelay) {
EXPECT_EQ(4u, entries.size());
EXPECT_TRUE(
- LogContainsBeginEvent(entries, 0, NetLogEventType::PROXY_SCRIPT_DECIDER));
+ LogContainsBeginEvent(entries, 0, NetLogEventType::PAC_FILE_DECIDER));
EXPECT_TRUE(LogContainsBeginEvent(
- entries, 1, NetLogEventType::PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+ entries, 1, NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT));
EXPECT_TRUE(LogContainsEndEvent(
- entries, 2, NetLogEventType::PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+ entries, 2, NetLogEventType::PAC_FILE_DECIDER_FETCH_PAC_SCRIPT));
EXPECT_TRUE(
- LogContainsEndEvent(entries, 3, NetLogEventType::PROXY_SCRIPT_DECIDER));
+ LogContainsEndEvent(entries, 3, NetLogEventType::PAC_FILE_DECIDER));
}
-class SynchronousSuccessDhcpFetcher : public DhcpProxyScriptFetcher {
+class SynchronousSuccessDhcpFetcher : public DhcpPacFileFetcher {
public:
explicit SynchronousSuccessDhcpFetcher(const base::string16& expected_text)
: gurl_("http://dhcppac/"), expected_text_(expected_text) {}
int Fetch(base::string16* utf16_text,
- const CompletionCallback& callback) override {
+ const CompletionCallback& callback,
+ const NetLogWithSource& net_log,
+ const NetworkTrafficAnnotationTag traffic_annotation) override {
*utf16_text = expected_text_;
return OK;
}
@@ -693,14 +719,14 @@ class SynchronousSuccessDhcpFetcher : public DhcpProxyScriptFetcher {
DISALLOW_COPY_AND_ASSIGN(SynchronousSuccessDhcpFetcher);
};
-// All of the tests above that use ProxyScriptDecider have tested
+// All of the tests above that use PacFileDecider have tested
// failure to fetch a PAC file via DHCP configuration, so we now test
// success at downloading and parsing, and then success at downloading,
// failure at parsing.
-TEST(ProxyScriptDeciderTest, AutodetectDhcpSuccess) {
+TEST(PacFileDeciderTest, AutodetectDhcpSuccess) {
Rules rules;
- RuleBasedProxyScriptFetcher fetcher(&rules);
+ RuleBasedPacFileFetcher fetcher(&rules);
SynchronousSuccessDhcpFetcher dhcp_fetcher(
base::WideToUTF16(L"http://bingo/!FindProxyForURL"));
@@ -711,18 +737,20 @@ TEST(ProxyScriptDeciderTest, AutodetectDhcpSuccess) {
rules.AddFailDownloadRule("http://wpad/wpad.dat");
TestCompletionCallback callback;
- ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, NULL);
- EXPECT_EQ(
- OK, decider.Start(config, base::TimeDelta(), true, callback.callback()));
+ PacFileDecider decider(&fetcher, &dhcp_fetcher, NULL);
+ EXPECT_EQ(OK, decider.Start(ProxyConfigWithAnnotation(
+ config, TRAFFIC_ANNOTATION_FOR_TESTS),
+ base::TimeDelta(), true, callback.callback()));
EXPECT_EQ(dhcp_fetcher.expected_text(), decider.script_data()->utf16());
- EXPECT_TRUE(decider.effective_config().has_pac_url());
- EXPECT_EQ(GURL("http://dhcppac/"), decider.effective_config().pac_url());
+ EXPECT_TRUE(decider.effective_config().value().has_pac_url());
+ EXPECT_EQ(GURL("http://dhcppac/"),
+ decider.effective_config().value().pac_url());
}
-TEST(ProxyScriptDeciderTest, AutodetectDhcpFailParse) {
+TEST(PacFileDeciderTest, AutodetectDhcpFailParse) {
Rules rules;
- RuleBasedProxyScriptFetcher fetcher(&rules);
+ RuleBasedPacFileFetcher fetcher(&rules);
SynchronousSuccessDhcpFetcher dhcp_fetcher(
base::WideToUTF16(L"http://bingo/!invalid-script"));
@@ -733,25 +761,29 @@ TEST(ProxyScriptDeciderTest, AutodetectDhcpFailParse) {
rules.AddFailDownloadRule("http://wpad/wpad.dat");
TestCompletionCallback callback;
- ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, NULL);
+ PacFileDecider decider(&fetcher, &dhcp_fetcher, NULL);
// Since there is fallback to DNS-based WPAD, the final error will be that
// it failed downloading, not that it failed parsing.
- EXPECT_EQ(kFailedDownloading, decider.Start(config, base::TimeDelta(), true,
- callback.callback()));
+ EXPECT_EQ(kFailedDownloading,
+ decider.Start(
+ ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS),
+ base::TimeDelta(), true, callback.callback()));
EXPECT_FALSE(decider.script_data());
- EXPECT_FALSE(decider.effective_config().has_pac_url());
+ EXPECT_FALSE(decider.effective_config().value().has_pac_url());
}
class AsyncFailDhcpFetcher
- : public DhcpProxyScriptFetcher,
+ : public DhcpPacFileFetcher,
public base::SupportsWeakPtr<AsyncFailDhcpFetcher> {
public:
AsyncFailDhcpFetcher() = default;
~AsyncFailDhcpFetcher() override = default;
int Fetch(base::string16* utf16_text,
- const CompletionCallback& callback) override {
+ const CompletionCallback& callback,
+ const NetLogWithSource& net_log,
+ const NetworkTrafficAnnotationTag traffic_annotation) override {
callback_ = callback;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
@@ -775,13 +807,13 @@ class AsyncFailDhcpFetcher
CompletionCallback callback_;
};
-TEST(ProxyScriptDeciderTest, DhcpCancelledByDestructor) {
+TEST(PacFileDeciderTest, DhcpCancelledByDestructor) {
// This regression test would crash before
// http://codereview.chromium.org/7044058/
// Thus, we don't care much about actual results (hence no EXPECT or ASSERT
// macros below), just that it doesn't crash.
Rules rules;
- RuleBasedProxyScriptFetcher fetcher(&rules);
+ RuleBasedPacFileFetcher fetcher(&rules);
std::unique_ptr<AsyncFailDhcpFetcher> dhcp_fetcher(
new AsyncFailDhcpFetcher());
@@ -792,15 +824,17 @@ TEST(ProxyScriptDeciderTest, DhcpCancelledByDestructor) {
TestCompletionCallback callback;
- // Scope so ProxyScriptDecider gets destroyed early.
+ // Scope so PacFileDecider gets destroyed early.
{
- ProxyScriptDecider decider(&fetcher, dhcp_fetcher.get(), NULL);
- decider.Start(config, base::TimeDelta(), true, callback.callback());
+ PacFileDecider decider(&fetcher, dhcp_fetcher.get(), NULL);
+ decider.Start(
+ ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS),
+ base::TimeDelta(), true, callback.callback());
}
// Run the message loop to let the DHCP fetch complete and post the results
// back. Before the fix linked to above, this would try to invoke on
- // the callback object provided by ProxyScriptDecider after it was
+ // the callback object provided by PacFileDecider after it was
// no longer valid.
base::RunLoop().RunUntilIdle();
}
diff --git a/chromium/net/proxy_resolution/pac_file_fetcher.h b/chromium/net/proxy_resolution/pac_file_fetcher.h
index d19ed597031..8555563d34f 100644
--- a/chromium/net/proxy_resolution/pac_file_fetcher.h
+++ b/chromium/net/proxy_resolution/pac_file_fetcher.h
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// ProxyScriptFetcher is an async interface for fetching a proxy auto config
+// PacFileFetcher is an async interface for fetching a proxy auto config
// script. It is specific to fetching a PAC script; enforces timeout, max-size,
// status code.
@@ -12,6 +12,7 @@
#include "base/strings/string16.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
class GURL;
@@ -21,10 +22,10 @@ class URLRequestContext;
// Interface for downloading a PAC script. Implementations can enforce
// timeouts, maximum size constraints, content encoding, etc..
-class NET_EXPORT_PRIVATE ProxyScriptFetcher {
+class NET_EXPORT_PRIVATE PacFileFetcher {
public:
// Destruction should cancel any outstanding requests.
- virtual ~ProxyScriptFetcher() {}
+ virtual ~PacFileFetcher() {}
// Downloads the given PAC URL, and invokes |callback| on completion.
// Returns OK on success, otherwise the error code. If the return code is
@@ -46,7 +47,8 @@ class NET_EXPORT_PRIVATE ProxyScriptFetcher {
// Only one fetch is allowed to be outstanding at a time.
virtual int Fetch(const GURL& url,
base::string16* utf16_text,
- const CompletionCallback& callback) = 0;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag traffic_annotation) = 0;
// Aborts the in-progress fetch (if any).
virtual void Cancel() = 0;
diff --git a/chromium/net/proxy_resolution/pac_file_fetcher_impl.cc b/chromium/net/proxy_resolution/pac_file_fetcher_impl.cc
index d0d107e6aa2..6a02e007e38 100644
--- a/chromium/net/proxy_resolution/pac_file_fetcher_impl.cc
+++ b/chromium/net/proxy_resolution/pac_file_fetcher_impl.cc
@@ -19,7 +19,6 @@
#include "net/base/request_priority.h"
#include "net/cert/cert_status_flags.h"
#include "net/http/http_response_headers.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request_context.h"
// TODO(eroman):
@@ -82,8 +81,7 @@ void ConvertResponseToUTF16(const std::string& charset,
} // namespace
-ProxyScriptFetcherImpl::ProxyScriptFetcherImpl(
- URLRequestContext* url_request_context)
+PacFileFetcherImpl::PacFileFetcherImpl(URLRequestContext* url_request_context)
: url_request_context_(url_request_context),
buf_(new IOBuffer(kBufSize)),
next_id_(0),
@@ -96,26 +94,26 @@ ProxyScriptFetcherImpl::ProxyScriptFetcherImpl(
DCHECK(url_request_context);
}
-ProxyScriptFetcherImpl::~ProxyScriptFetcherImpl() {
+PacFileFetcherImpl::~PacFileFetcherImpl() {
// The URLRequest's destructor will cancel the outstanding request, and
// ensure that the delegate (this) is not called again.
}
-base::TimeDelta ProxyScriptFetcherImpl::SetTimeoutConstraint(
+base::TimeDelta PacFileFetcherImpl::SetTimeoutConstraint(
base::TimeDelta timeout) {
base::TimeDelta prev = max_duration_;
max_duration_ = timeout;
return prev;
}
-size_t ProxyScriptFetcherImpl::SetSizeConstraint(size_t size_bytes) {
+size_t PacFileFetcherImpl::SetSizeConstraint(size_t size_bytes) {
size_t prev = max_response_bytes_;
max_response_bytes_ = size_bytes;
return prev;
}
-void ProxyScriptFetcherImpl::OnResponseCompleted(URLRequest* request,
- int net_error) {
+void PacFileFetcherImpl::OnResponseCompleted(URLRequest* request,
+ int net_error) {
DCHECK_EQ(request, cur_request_.get());
// Use |result_code_| as the request's error if we have already set it to
@@ -126,9 +124,11 @@ void ProxyScriptFetcherImpl::OnResponseCompleted(URLRequest* request,
FetchCompleted();
}
-int ProxyScriptFetcherImpl::Fetch(const GURL& url,
- base::string16* text,
- const CompletionCallback& callback) {
+int PacFileFetcherImpl::Fetch(
+ const GURL& url,
+ base::string16* text,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag traffic_annotation) {
// It is invalid to call Fetch() while a request is already in progress.
DCHECK(!cur_request_.get());
DCHECK(!callback.is_null());
@@ -152,35 +152,6 @@ int ProxyScriptFetcherImpl::Fetch(const GURL& url,
DCHECK(fetch_start_time_.is_null());
fetch_start_time_ = base::TimeTicks::Now();
- net::NetworkTrafficAnnotationTag traffic_annotation =
- net::DefineNetworkTrafficAnnotation("proxy_script_fetcher", R"(
- semantics {
- sender: "Proxy Service"
- description:
- "Fetches candidate URLs for proxy auto-config (PAC) scripts. This "
- "may be carried out as part of the web proxy auto-discovery "
- "protocol, or because an explicit PAC script is specified by the "
- "proxy settings. The source of these URLs may be user-specified "
- "(when part of proxy settings), or may be provided by the network "
- "(DNS or DHCP based discovery). Note that a user may not be using "
- "a proxy, but determining that (i.e. auto-detect) may cause these "
- "fetches."
- trigger:
- "PAC URLs may be fetched on initial start, every time the network "
- "changes, whenever the proxy settings change, or periodically on a "
- "timer to check for changes."
- data: "None."
- destination: OTHER
- }
- policy {
- cookies_allowed: YES
- cookies_store: "user"
- setting:
- "This feature cannot be disabled by settings. This request is only "
- "made if the effective proxy settings include either auto-detect, "
- "or specify a PAC script."
- policy_exception_justification: "Not implemented."
- })");
// Use highest priority, so if socket pools are being used for other types of
// requests, PAC requests are aren't blocked on them.
cur_request_ = url_request_context_->CreateRequest(url, MAXIMUM_PRIORITY,
@@ -212,7 +183,7 @@ int ProxyScriptFetcherImpl::Fetch(const GURL& url,
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
- base::Bind(&ProxyScriptFetcherImpl::OnTimeout, weak_factory_.GetWeakPtr(),
+ base::Bind(&PacFileFetcherImpl::OnTimeout, weak_factory_.GetWeakPtr(),
cur_request_id_),
max_duration_);
@@ -221,17 +192,17 @@ int ProxyScriptFetcherImpl::Fetch(const GURL& url,
return ERR_IO_PENDING;
}
-void ProxyScriptFetcherImpl::Cancel() {
+void PacFileFetcherImpl::Cancel() {
// ResetCurRequestState will free the URLRequest, which will cause
// cancellation.
ResetCurRequestState();
}
-URLRequestContext* ProxyScriptFetcherImpl::GetRequestContext() const {
+URLRequestContext* PacFileFetcherImpl::GetRequestContext() const {
return url_request_context_;
}
-void ProxyScriptFetcherImpl::OnShutdown() {
+void PacFileFetcherImpl::OnShutdown() {
url_request_context_ = nullptr;
if (cur_request_) {
@@ -240,8 +211,8 @@ void ProxyScriptFetcherImpl::OnShutdown() {
}
}
-void ProxyScriptFetcherImpl::OnAuthRequired(URLRequest* request,
- AuthChallengeInfo* auth_info) {
+void PacFileFetcherImpl::OnAuthRequired(URLRequest* request,
+ AuthChallengeInfo* auth_info) {
DCHECK_EQ(request, cur_request_.get());
// TODO(eroman): http://crbug.com/77366
LOG(WARNING) << "Auth required to fetch PAC script, aborting.";
@@ -249,9 +220,9 @@ void ProxyScriptFetcherImpl::OnAuthRequired(URLRequest* request,
request->CancelAuth();
}
-void ProxyScriptFetcherImpl::OnSSLCertificateError(URLRequest* request,
- const SSLInfo& ssl_info,
- bool fatal) {
+void PacFileFetcherImpl::OnSSLCertificateError(URLRequest* request,
+ const SSLInfo& ssl_info,
+ bool fatal) {
DCHECK_EQ(request, cur_request_.get());
// Revocation check failures are not fatal.
if (IsCertStatusMinorError(ssl_info.cert_status)) {
@@ -264,8 +235,7 @@ void ProxyScriptFetcherImpl::OnSSLCertificateError(URLRequest* request,
request->Cancel();
}
-void ProxyScriptFetcherImpl::OnResponseStarted(URLRequest* request,
- int net_error) {
+void PacFileFetcherImpl::OnResponseStarted(URLRequest* request, int net_error) {
DCHECK_EQ(request, cur_request_.get());
DCHECK_NE(ERR_IO_PENDING, net_error);
@@ -300,8 +270,7 @@ void ProxyScriptFetcherImpl::OnResponseStarted(URLRequest* request,
ReadBody(request);
}
-void ProxyScriptFetcherImpl::OnReadCompleted(URLRequest* request,
- int num_bytes) {
+void PacFileFetcherImpl::OnReadCompleted(URLRequest* request, int num_bytes) {
DCHECK_NE(ERR_IO_PENDING, num_bytes);
DCHECK_EQ(request, cur_request_.get());
@@ -311,7 +280,7 @@ void ProxyScriptFetcherImpl::OnReadCompleted(URLRequest* request,
}
}
-void ProxyScriptFetcherImpl::ReadBody(URLRequest* request) {
+void PacFileFetcherImpl::ReadBody(URLRequest* request) {
// Read as many bytes as are available synchronously.
while (true) {
int num_bytes = request->Read(buf_.get(), kBufSize);
@@ -328,8 +297,7 @@ void ProxyScriptFetcherImpl::ReadBody(URLRequest* request) {
}
}
-bool ProxyScriptFetcherImpl::ConsumeBytesRead(URLRequest* request,
- int num_bytes) {
+bool PacFileFetcherImpl::ConsumeBytesRead(URLRequest* request, int num_bytes) {
if (fetch_time_to_first_byte_.is_null())
fetch_time_to_first_byte_ = base::TimeTicks::Now();
@@ -351,9 +319,9 @@ bool ProxyScriptFetcherImpl::ConsumeBytesRead(URLRequest* request,
return true;
}
-void ProxyScriptFetcherImpl::FetchCompleted() {
+void PacFileFetcherImpl::FetchCompleted() {
if (result_code_ == OK) {
- // Calculate duration of time for proxy script fetch to complete.
+ // Calculate duration of time for PAC file fetch to complete.
DCHECK(!fetch_start_time_.is_null());
DCHECK(!fetch_time_to_first_byte_.is_null());
UMA_HISTOGRAM_MEDIUM_TIMES("Net.ProxyScriptFetcher.SuccessDuration",
@@ -378,7 +346,7 @@ void ProxyScriptFetcherImpl::FetchCompleted() {
callback.Run(result_code);
}
-void ProxyScriptFetcherImpl::ResetCurRequestState() {
+void PacFileFetcherImpl::ResetCurRequestState() {
cur_request_.reset();
cur_request_id_ = 0;
callback_.Reset();
@@ -388,7 +356,7 @@ void ProxyScriptFetcherImpl::ResetCurRequestState() {
fetch_time_to_first_byte_ = base::TimeTicks();
}
-void ProxyScriptFetcherImpl::OnTimeout(int id) {
+void PacFileFetcherImpl::OnTimeout(int id) {
// Timeout tasks may outlive the URLRequest they reference. Make sure it
// is still applicable.
if (cur_request_id_ != id)
diff --git a/chromium/net/proxy_resolution/pac_file_fetcher_impl.h b/chromium/net/proxy_resolution/pac_file_fetcher_impl.h
index 3cea326af60..dac5a82b428 100644
--- a/chromium/net/proxy_resolution/pac_file_fetcher_impl.h
+++ b/chromium/net/proxy_resolution/pac_file_fetcher_impl.h
@@ -18,6 +18,7 @@
#include "base/time/time.h"
#include "net/base/net_export.h"
#include "net/proxy_resolution/pac_file_fetcher.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request.h"
class GURL;
@@ -26,20 +27,20 @@ namespace net {
class URLRequestContext;
-// Implementation of ProxyScriptFetcher that downloads scripts using the
+// Implementation of PacFileFetcher that downloads scripts using the
// specified request context.
-class NET_EXPORT ProxyScriptFetcherImpl : public ProxyScriptFetcher,
- public URLRequest::Delegate {
+class NET_EXPORT PacFileFetcherImpl : public PacFileFetcher,
+ public URLRequest::Delegate {
public:
- // Creates a ProxyScriptFetcher that issues requests through
+ // Creates a PacFileFetcher that issues requests through
// |url_request_context|. |url_request_context| must remain valid for the
- // lifetime of ProxyScriptFetcherImpl.
+ // lifetime of PacFileFetcherImpl.
// Note that while a request is in progress, we will be holding a reference
// to |url_request_context|. Be careful not to create cycles between the
// fetcher and the context; you can break such cycles by calling Cancel().
- explicit ProxyScriptFetcherImpl(URLRequestContext* url_request_context);
+ explicit PacFileFetcherImpl(URLRequestContext* url_request_context);
- ~ProxyScriptFetcherImpl() override;
+ ~PacFileFetcherImpl() override;
// Used by unit-tests to modify the default limits.
base::TimeDelta SetTimeoutConstraint(base::TimeDelta timeout);
@@ -47,10 +48,11 @@ class NET_EXPORT ProxyScriptFetcherImpl : public ProxyScriptFetcher,
void OnResponseCompleted(URLRequest* request, int net_error);
- // ProxyScriptFetcher methods:
+ // PacFileFetcher methods:
int Fetch(const GURL& url,
base::string16* text,
- const CompletionCallback& callback) override;
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag traffic_annotation) override;
void Cancel() override;
URLRequestContext* GetRequestContext() const override;
void OnShutdown() override;
@@ -129,9 +131,9 @@ class NET_EXPORT ProxyScriptFetcherImpl : public ProxyScriptFetcher,
// Factory for creating the time-out task. This takes care of revoking
// outstanding tasks when |this| is deleted.
- base::WeakPtrFactory<ProxyScriptFetcherImpl> weak_factory_;
+ base::WeakPtrFactory<PacFileFetcherImpl> weak_factory_;
- DISALLOW_COPY_AND_ASSIGN(ProxyScriptFetcherImpl);
+ DISALLOW_COPY_AND_ASSIGN(PacFileFetcherImpl);
};
} // namespace net
diff --git a/chromium/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc b/chromium/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
index a2c030e58a5..6acd2b638bb 100644
--- a/chromium/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
+++ b/chromium/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
@@ -32,13 +32,14 @@
#include "net/http/http_server_properties_impl.h"
#include "net/http/http_transaction_factory.h"
#include "net/http/transport_security_state.h"
-#include "net/net_features.h"
+#include "net/net_buildflags.h"
#include "net/socket/client_socket_pool_manager.h"
#include "net/socket/transport_client_socket_pool.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/simple_connection_listener.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_context_storage.h"
#include "net/url_request/url_request_file_job.h"
#include "net/url_request/url_request_job_factory_impl.h"
@@ -58,14 +59,14 @@ using base::ASCIIToUTF16;
// TODO(eroman):
// - Test canceling an outstanding request.
-// - Test deleting ProxyScriptFetcher while a request is in progress.
+// - Test deleting PacFileFetcher while a request is in progress.
namespace net {
namespace {
const base::FilePath::CharType kDocRoot[] =
- FILE_PATH_LITERAL("net/data/proxy_script_fetcher_unittest");
+ FILE_PATH_LITERAL("net/data/pac_file_fetcher_unittest");
struct FetchResult {
int code;
@@ -86,7 +87,8 @@ class RequestContext : public URLRequestContext {
storage_.set_cert_transparency_verifier(
std::make_unique<MultiLogCTVerifier>());
storage_.set_ct_policy_enforcer(std::make_unique<CTPolicyEnforcer>());
- storage_.set_proxy_resolution_service(ProxyResolutionService::CreateFixed(no_proxy));
+ storage_.set_proxy_resolution_service(ProxyResolutionService::CreateFixed(
+ ProxyConfigWithAnnotation(no_proxy, TRAFFIC_ANNOTATION_FOR_TESTS)));
storage_.set_ssl_config_service(new SSLConfigServiceDefaults);
storage_.set_http_server_properties(
std::unique_ptr<HttpServerProperties>(new HttpServerPropertiesImpl()));
@@ -122,13 +124,13 @@ class RequestContext : public URLRequestContext {
};
#if !BUILDFLAG(DISABLE_FILE_SUPPORT)
-// Get a file:// url relative to net/data/proxy/proxy_script_fetcher_unittest.
+// Get a file:// url relative to net/data/proxy/pac_file_fetcher_unittest.
GURL GetTestFileUrl(const std::string& relpath) {
base::FilePath path;
PathService::Get(base::DIR_SOURCE_ROOT, &path);
path = path.AppendASCII("net");
path = path.AppendASCII("data");
- path = path.AppendASCII("proxy_script_fetcher_unittest");
+ path = path.AppendASCII("pac_file_fetcher_unittest");
GURL base_url = FilePathToFileURL(path);
return GURL(base_url.spec() + "/" + relpath);
}
@@ -209,9 +211,9 @@ class BasicNetworkDelegate : public NetworkDelegateImpl {
DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate);
};
-class ProxyScriptFetcherImplTest : public PlatformTest {
+class PacFileFetcherImplTest : public PlatformTest {
public:
- ProxyScriptFetcherImplTest() {
+ PacFileFetcherImplTest() {
test_server_.AddDefaultHandlers(base::FilePath(kDocRoot));
context_.set_network_delegate(&network_delegate_);
}
@@ -223,14 +225,15 @@ class ProxyScriptFetcherImplTest : public PlatformTest {
};
#if !BUILDFLAG(DISABLE_FILE_SUPPORT)
-TEST_F(ProxyScriptFetcherImplTest, FileUrl) {
- ProxyScriptFetcherImpl pac_fetcher(&context_);
+TEST_F(PacFileFetcherImplTest, FileUrl) {
+ PacFileFetcherImpl pac_fetcher(&context_);
{ // Fetch a non-existent file.
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(GetTestFileUrl("does-not-exist"), &text,
- callback.callback());
+ int result =
+ pac_fetcher.Fetch(GetTestFileUrl("does-not-exist"), &text,
+ callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_FILE_NOT_FOUND));
EXPECT_TRUE(text.empty());
@@ -238,8 +241,9 @@ TEST_F(ProxyScriptFetcherImplTest, FileUrl) {
{ // Fetch a file that exists.
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(GetTestFileUrl("pac.txt"), &text,
- callback.callback());
+ int result =
+ pac_fetcher.Fetch(GetTestFileUrl("pac.txt"), &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("-pac.txt-\n"), text);
@@ -249,16 +253,17 @@ TEST_F(ProxyScriptFetcherImplTest, FileUrl) {
// Note that all mime types are allowed for PAC file, to be consistent
// with other browsers.
-TEST_F(ProxyScriptFetcherImplTest, HttpMimeType) {
+TEST_F(PacFileFetcherImplTest, HttpMimeType) {
ASSERT_TRUE(test_server_.Start());
- ProxyScriptFetcherImpl pac_fetcher(&context_);
+ PacFileFetcherImpl pac_fetcher(&context_);
{ // Fetch a PAC with mime type "text/plain"
GURL url(test_server_.GetURL("/pac.txt"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("-pac.txt-\n"), text);
@@ -267,7 +272,8 @@ TEST_F(ProxyScriptFetcherImplTest, HttpMimeType) {
GURL url(test_server_.GetURL("/pac.html"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("-pac.html-\n"), text);
@@ -276,23 +282,25 @@ TEST_F(ProxyScriptFetcherImplTest, HttpMimeType) {
GURL url(test_server_.GetURL("/pac.nsproxy"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("-pac.nsproxy-\n"), text);
}
}
-TEST_F(ProxyScriptFetcherImplTest, HttpStatusCode) {
+TEST_F(PacFileFetcherImplTest, HttpStatusCode) {
ASSERT_TRUE(test_server_.Start());
- ProxyScriptFetcherImpl pac_fetcher(&context_);
+ PacFileFetcherImpl pac_fetcher(&context_);
{ // Fetch a PAC which gives a 500 -- FAIL
GURL url(test_server_.GetURL("/500.pac"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PAC_STATUS_NOT_OK));
EXPECT_TRUE(text.empty());
@@ -301,41 +309,44 @@ TEST_F(ProxyScriptFetcherImplTest, HttpStatusCode) {
GURL url(test_server_.GetURL("/404.pac"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PAC_STATUS_NOT_OK));
EXPECT_TRUE(text.empty());
}
}
-TEST_F(ProxyScriptFetcherImplTest, ContentDisposition) {
+TEST_F(PacFileFetcherImplTest, ContentDisposition) {
ASSERT_TRUE(test_server_.Start());
- ProxyScriptFetcherImpl pac_fetcher(&context_);
+ PacFileFetcherImpl pac_fetcher(&context_);
// Fetch PAC scripts via HTTP with a Content-Disposition header -- should
// have no effect.
GURL url(test_server_.GetURL("/downloadable.pac"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("-downloadable.pac-\n"), text);
}
// Verifies that PAC scripts are not being cached.
-TEST_F(ProxyScriptFetcherImplTest, NoCache) {
+TEST_F(PacFileFetcherImplTest, NoCache) {
ASSERT_TRUE(test_server_.Start());
- ProxyScriptFetcherImpl pac_fetcher(&context_);
+ PacFileFetcherImpl pac_fetcher(&context_);
// Fetch a PAC script whose HTTP headers make it cacheable for 1 hour.
GURL url(test_server_.GetURL("/cacheable_1hr.pac"));
{
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("-cacheable_1hr.pac-\n"), text);
@@ -350,7 +361,8 @@ TEST_F(ProxyScriptFetcherImplTest, NoCache) {
{
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
// Expect any error. The exact error varies by platform.
@@ -358,10 +370,10 @@ TEST_F(ProxyScriptFetcherImplTest, NoCache) {
}
}
-TEST_F(ProxyScriptFetcherImplTest, TooLarge) {
+TEST_F(PacFileFetcherImplTest, TooLarge) {
ASSERT_TRUE(test_server_.Start());
- ProxyScriptFetcherImpl pac_fetcher(&context_);
+ PacFileFetcherImpl pac_fetcher(&context_);
// Set the maximum response size to 50 bytes.
int prev_size = pac_fetcher.SetSizeConstraint(50);
@@ -380,7 +392,8 @@ TEST_F(ProxyScriptFetcherImplTest, TooLarge) {
const GURL& url = urls[i];
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_FILE_TOO_BIG));
EXPECT_TRUE(text.empty());
@@ -393,32 +406,34 @@ TEST_F(ProxyScriptFetcherImplTest, TooLarge) {
GURL url(test_server_.GetURL("/pac.nsproxy"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("-pac.nsproxy-\n"), text);
}
}
-// The ProxyScriptFetcher should be able to handle responses with an empty body.
-TEST_F(ProxyScriptFetcherImplTest, Empty) {
+// The PacFileFetcher should be able to handle responses with an empty body.
+TEST_F(PacFileFetcherImplTest, Empty) {
ASSERT_TRUE(test_server_.Start());
- ProxyScriptFetcherImpl pac_fetcher(&context_);
+ PacFileFetcherImpl pac_fetcher(&context_);
GURL url(test_server_.GetURL("/empty"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(0u, text.size());
}
-TEST_F(ProxyScriptFetcherImplTest, Hang) {
+TEST_F(PacFileFetcherImplTest, Hang) {
ASSERT_TRUE(test_server_.Start());
- ProxyScriptFetcherImpl pac_fetcher(&context_);
+ PacFileFetcherImpl pac_fetcher(&context_);
// Set the timeout period to 0.5 seconds.
base::TimeDelta prev_timeout =
@@ -430,7 +445,8 @@ TEST_F(ProxyScriptFetcherImplTest, Hang) {
GURL url(test_server_.GetURL("/slow/proxy.pac?1.2"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_TIMED_OUT));
EXPECT_TRUE(text.empty());
@@ -443,27 +459,29 @@ TEST_F(ProxyScriptFetcherImplTest, Hang) {
GURL url(test_server_.GetURL("/pac.nsproxy"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("-pac.nsproxy-\n"), text);
}
}
-// The ProxyScriptFetcher should decode any content-codings
+// The PacFileFetcher should decode any content-codings
// (like gzip, bzip, etc.), and apply any charset conversions to yield
// UTF8.
-TEST_F(ProxyScriptFetcherImplTest, Encodings) {
+TEST_F(PacFileFetcherImplTest, Encodings) {
ASSERT_TRUE(test_server_.Start());
- ProxyScriptFetcherImpl pac_fetcher(&context_);
+ PacFileFetcherImpl pac_fetcher(&context_);
// Test a response that is gzip-encoded -- should get inflated.
{
GURL url(test_server_.GetURL("/gzipped_pac"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("This data was gzipped.\n"), text);
@@ -475,15 +493,16 @@ TEST_F(ProxyScriptFetcherImplTest, Encodings) {
GURL url(test_server_.GetURL("/utf16be_pac"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("This was encoded as UTF-16BE.\n"), text);
}
}
-TEST_F(ProxyScriptFetcherImplTest, DataURLs) {
- ProxyScriptFetcherImpl pac_fetcher(&context_);
+TEST_F(PacFileFetcherImplTest, DataURLs) {
+ PacFileFetcherImpl pac_fetcher(&context_);
const char kEncodedUrl[] =
"data:application/x-ns-proxy-autoconfig;base64,ZnVuY3Rpb24gRmluZFByb3h5R"
@@ -501,7 +520,8 @@ TEST_F(ProxyScriptFetcherImplTest, DataURLs) {
GURL url(kEncodedUrl);
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsOk());
EXPECT_EQ(ASCIIToUTF16(kPacScript), text);
}
@@ -514,18 +534,19 @@ TEST_F(ProxyScriptFetcherImplTest, DataURLs) {
GURL url(kEncodedUrlBroken);
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback());
+ int result = pac_fetcher.Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_FAILED));
}
}
-// Makes sure that a request gets through when the socket pool is full, so
-// ProxyScriptFetcherImpl can use the same URLRequestContext as everything else.
-TEST_F(ProxyScriptFetcherImplTest, Priority) {
- // Enough requests to exceed the per-pool limit, which is also enough to
- // exceed the per-group limit.
- int num_requests = 10 + ClientSocketPoolManager::max_sockets_per_pool(
- HttpNetworkSession::NORMAL_SOCKET_POOL);
+// Makes sure that a request gets through when the socket group for the PAC URL
+// is full, so PacFileFetcherImpl can use the same URLRequestContext as
+// everything else.
+TEST_F(PacFileFetcherImplTest, IgnoresLimits) {
+ // Enough requests to exceed the per-group limit.
+ int num_requests = 2 + ClientSocketPoolManager::max_sockets_per_group(
+ HttpNetworkSession::NORMAL_SOCKET_POOL);
net::test_server::SimpleConnectionListener connection_listener(
num_requests, net::test_server::SimpleConnectionListener::
@@ -533,17 +554,18 @@ TEST_F(ProxyScriptFetcherImplTest, Priority) {
test_server_.SetConnectionListener(&connection_listener);
ASSERT_TRUE(test_server_.Start());
- std::vector<std::unique_ptr<ProxyScriptFetcherImpl>> pac_fetchers;
+ std::vector<std::unique_ptr<PacFileFetcherImpl>> pac_fetchers;
TestCompletionCallback callback;
base::string16 text;
for (int i = 0; i < num_requests; i++) {
- std::unique_ptr<ProxyScriptFetcherImpl> pac_fetcher =
- std::make_unique<ProxyScriptFetcherImpl>(&context_);
+ std::unique_ptr<PacFileFetcherImpl> pac_fetcher =
+ std::make_unique<PacFileFetcherImpl>(&context_);
GURL url(test_server_.GetURL("/hung"));
// Fine to use the same string and callback for all of these, as they should
// all hang.
- int result = pac_fetcher->Fetch(url, &text, callback.callback());
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
pac_fetchers.push_back(std::move(pac_fetcher));
}
@@ -557,14 +579,15 @@ TEST_F(ProxyScriptFetcherImplTest, Priority) {
EXPECT_TRUE(test_server_.ShutdownAndWaitUntilComplete());
}
-TEST_F(ProxyScriptFetcherImplTest, OnShutdown) {
+TEST_F(PacFileFetcherImplTest, OnShutdown) {
ASSERT_TRUE(test_server_.Start());
- ProxyScriptFetcherImpl pac_fetcher(&context_);
+ PacFileFetcherImpl pac_fetcher(&context_);
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(test_server_.GetURL("/hung"), &text,
- callback.callback());
+ int result =
+ pac_fetcher.Fetch(test_server_.GetURL("/hung"), &text,
+ callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_EQ(1u, context_.url_requests()->size());
@@ -578,20 +601,21 @@ TEST_F(ProxyScriptFetcherImplTest, OnShutdown) {
EXPECT_FALSE(callback.have_result());
result = pac_fetcher.Fetch(test_server_.GetURL("/hung"), &text,
- callback.callback());
+ callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_CONTEXT_SHUT_DOWN));
}
-TEST_F(ProxyScriptFetcherImplTest, OnShutdownWithNoLiveRequest) {
+TEST_F(PacFileFetcherImplTest, OnShutdownWithNoLiveRequest) {
ASSERT_TRUE(test_server_.Start());
- ProxyScriptFetcherImpl pac_fetcher(&context_);
+ PacFileFetcherImpl pac_fetcher(&context_);
pac_fetcher.OnShutdown();
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(test_server_.GetURL("/hung"), &text,
- callback.callback());
+ int result =
+ pac_fetcher.Fetch(test_server_.GetURL("/hung"), &text,
+ callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_CONTEXT_SHUT_DOWN));
EXPECT_EQ(0u, context_.url_requests()->size());
}
diff --git a/chromium/net/proxy_resolution/pac_js_library.h b/chromium/net/proxy_resolution/pac_js_library.h
index c99c348352f..24f68b2f5af 100644
--- a/chromium/net/proxy_resolution/pac_js_library.h
+++ b/chromium/net/proxy_resolution/pac_js_library.h
@@ -44,231 +44,245 @@
*
* ***** END LICENSE BLOCK ***** */
-// The following code was formatted from:
-// 'mozilla/netwerk/base/src/nsProxyAutoConfig.js' (1.55)
+// The following code was last extracted from netwerk/base/ProxyAutoConfig.cpp
+// on 2018-03-29 using this command:
//
-// Using the command:
-// $ cat nsProxyAutoConfig.js |
-// awk '/var pacUtils/,/EOF/' |
-// sed -e 's/^\s*$/""/g' |
-// sed -e 's/"\s*[+]\s*$/"/g' |
-// sed -e 's/"$/" \\/g' |
-// sed -e 's/\/(ipaddr);/\/.exec(ipaddr);/g' |
-// grep -v '^var pacUtils ='
+// REV="6aa3b57955fed5e137d0306478e1a4b424a6d392"
+// FILE_PATH="netwerk/base/ProxyAutoConfig.cpp"
+// URL="https://hg.mozilla.org/mozilla-central/raw-file/$REV/$FILE_PATH"
//
-// isPlainHost() was removed.
-#define PAC_JS_LIBRARY \
- "function dnsDomainIs(host, domain) {\n" \
- " return (host.length >= domain.length &&\n" \
- " host.substring(host.length - domain.length) == domain);\n" \
- "}\n" \
- "" \
- "function dnsDomainLevels(host) {\n" \
- " return host.split('.').length-1;\n" \
- "}\n" \
- "" \
- "function convert_addr(ipchars) {\n" \
- " var bytes = ipchars.split('.');\n" \
- " var result = ((bytes[0] & 0xff) << 24) |\n" \
- " ((bytes[1] & 0xff) << 16) |\n" \
- " ((bytes[2] & 0xff) << 8) |\n" \
- " (bytes[3] & 0xff);\n" \
- " return result;\n" \
- "}\n" \
- "" \
- "function isInNet(ipaddr, pattern, maskstr) {\n" \
- " var test = " \
- "/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(ipaddr);\n" \
- " if (test == null) {\n" \
- " ipaddr = dnsResolve(ipaddr);\n" \
- " if (ipaddr == null)\n" \
- " return false;\n" \
- " } else if (test[1] > 255 || test[2] > 255 || \n" \
- " test[3] > 255 || test[4] > 255) {\n" \
- " return false; // not an IP address\n" \
- " }\n" \
- " var host = convert_addr(ipaddr);\n" \
- " var pat = convert_addr(pattern);\n" \
- " var mask = convert_addr(maskstr);\n" \
- " return ((host & mask) == (pat & mask));\n" \
- " \n" \
- "}\n" \
- "" \
- "function isResolvable(host) {\n" \
- " var ip = dnsResolve(host);\n" \
- " return (ip != null);\n" \
- "}\n" \
- "" \
- "function localHostOrDomainIs(host, hostdom) {\n" \
- " return (host == hostdom) ||\n" \
- " (hostdom.lastIndexOf(host + '.', 0) == 0);\n" \
- "}\n" \
- "" \
- "function shExpMatch(url, pattern) {\n" \
- " pattern = pattern.replace(/\\./g, '\\\\.');\n" \
- " pattern = pattern.replace(/\\*/g, '.*');\n" \
- " pattern = pattern.replace(/\\?/g, '.');\n" \
- " var newRe = new RegExp('^'+pattern+'$');\n" \
- " return newRe.test(url);\n" \
- "}\n" \
- "" \
- "var wdays = {SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6};\n" \
- "" \
- "var months = {JAN: 0, FEB: 1, MAR: 2, APR: 3, MAY: 4, JUN: 5, JUL: 6, " \
- "AUG: 7, SEP: 8, OCT: 9, NOV: 10, DEC: 11};\n" \
- "" \
- "function weekdayRange() {\n" \
- " function getDay(weekday) {\n" \
- " if (weekday in wdays) {\n" \
- " return wdays[weekday];\n" \
- " }\n" \
- " return -1;\n" \
- " }\n" \
- " var date = new Date();\n" \
- " var argc = arguments.length;\n" \
- " var wday;\n" \
- " if (argc < 1)\n" \
- " return false;\n" \
- " if (arguments[argc - 1] == 'GMT') {\n" \
- " argc--;\n" \
- " wday = date.getUTCDay();\n" \
- " } else {\n" \
- " wday = date.getDay();\n" \
- " }\n" \
- " var wd1 = getDay(arguments[0]);\n" \
- " var wd2 = (argc == 2) ? getDay(arguments[1]) : wd1;\n" \
- " return (wd1 == -1 || wd2 == -1) ? false\n" \
- " : (wd1 <= wday && wday <= wd2);\n" \
- "}\n" \
- "" \
- "function dateRange() {\n" \
- " function getMonth(name) {\n" \
- " if (name in months) {\n" \
- " return months[name];\n" \
- " }\n" \
- " return -1;\n" \
- " }\n" \
- " var date = new Date();\n" \
- " var argc = arguments.length;\n" \
- " if (argc < 1) {\n" \
- " return false;\n" \
- " }\n" \
- " var isGMT = (arguments[argc - 1] == 'GMT');\n" \
- "\n" \
- " if (isGMT) {\n" \
- " argc--;\n" \
- " }\n" \
- " // function will work even without explict handling of this case\n" \
- " if (argc == 1) {\n" \
- " var tmp = parseInt(arguments[0]);\n" \
- " if (isNaN(tmp)) {\n" \
- " return ((isGMT ? date.getUTCMonth() : date.getMonth()) ==\n" \
- "getMonth(arguments[0]));\n" \
- " } else if (tmp < 32) {\n" \
- " return ((isGMT ? date.getUTCDate() : date.getDate()) == " \
- "tmp);\n" \
- " } else { \n" \
- " return ((isGMT ? date.getUTCFullYear() : date.getFullYear()) " \
- "==\n" \
- "tmp);\n" \
- " }\n" \
- " }\n" \
- " var year = date.getFullYear();\n" \
- " var date1, date2;\n" \
- " date1 = new Date(year, 0, 1, 0, 0, 0);\n" \
- " date2 = new Date(year, 11, 31, 23, 59, 59);\n" \
- " var adjustMonth = false;\n" \
- " for (var i = 0; i < (argc >> 1); i++) {\n" \
- " var tmp = parseInt(arguments[i]);\n" \
- " if (isNaN(tmp)) {\n" \
- " var mon = getMonth(arguments[i]);\n" \
- " date1.setMonth(mon);\n" \
- " } else if (tmp < 32) {\n" \
- " adjustMonth = (argc <= 2);\n" \
- " date1.setDate(tmp);\n" \
- " } else {\n" \
- " date1.setFullYear(tmp);\n" \
- " }\n" \
- " }\n" \
- " for (var i = (argc >> 1); i < argc; i++) {\n" \
- " var tmp = parseInt(arguments[i]);\n" \
- " if (isNaN(tmp)) {\n" \
- " var mon = getMonth(arguments[i]);\n" \
- " date2.setMonth(mon);\n" \
- " } else if (tmp < 32) {\n" \
- " date2.setDate(tmp);\n" \
- " } else {\n" \
- " date2.setFullYear(tmp);\n" \
- " }\n" \
- " }\n" \
- " if (adjustMonth) {\n" \
- " date1.setMonth(date.getMonth());\n" \
- " date2.setMonth(date.getMonth());\n" \
- " }\n" \
- " if (isGMT) {\n" \
- " var tmp = date;\n" \
- " tmp.setFullYear(date.getUTCFullYear());\n" \
- " tmp.setMonth(date.getUTCMonth());\n" \
- " tmp.setDate(date.getUTCDate());\n" \
- " tmp.setHours(date.getUTCHours());\n" \
- " tmp.setMinutes(date.getUTCMinutes());\n" \
- " tmp.setSeconds(date.getUTCSeconds());\n" \
- " date = tmp;\n" \
- " }\n" \
- " return ((date1 <= date) && (date <= date2));\n" \
- "}\n" \
- "" \
- "function timeRange() {\n" \
- " var argc = arguments.length;\n" \
- " var date = new Date();\n" \
- " var isGMT= false;\n" \
- "\n" \
- " if (argc < 1) {\n" \
- " return false;\n" \
- " }\n" \
- " if (arguments[argc - 1] == 'GMT') {\n" \
- " isGMT = true;\n" \
- " argc--;\n" \
- " }\n" \
- "\n" \
- " var hour = isGMT ? date.getUTCHours() : date.getHours();\n" \
- " var date1, date2;\n" \
- " date1 = new Date();\n" \
- " date2 = new Date();\n" \
- "\n" \
- " if (argc == 1) {\n" \
- " return (hour == arguments[0]);\n" \
- " } else if (argc == 2) {\n" \
- " return ((arguments[0] <= hour) && (hour <= arguments[1]));\n" \
- " } else {\n" \
- " switch (argc) {\n" \
- " case 6:\n" \
- " date1.setSeconds(arguments[2]);\n" \
- " date2.setSeconds(arguments[5]);\n" \
- " case 4:\n" \
- " var middle = argc >> 1;\n" \
- " date1.setHours(arguments[0]);\n" \
- " date1.setMinutes(arguments[1]);\n" \
- " date2.setHours(arguments[middle]);\n" \
- " date2.setMinutes(arguments[middle + 1]);\n" \
- " if (middle == 2) {\n" \
- " date2.setSeconds(59);\n" \
- " }\n" \
- " break;\n" \
- " default:\n" \
- " throw 'timeRange: bad number of arguments'\n" \
- " }\n" \
- " }\n" \
- "\n" \
- " if (isGMT) {\n" \
- " date.setFullYear(date.getUTCFullYear());\n" \
- " date.setMonth(date.getUTCMonth());\n" \
- " date.setDate(date.getUTCDate());\n" \
- " date.setHours(date.getUTCHours());\n" \
- " date.setMinutes(date.getUTCMinutes());\n" \
- " date.setSeconds(date.getUTCSeconds());\n" \
- " }\n" \
- " return ((date1 <= date) && (date <= date2));\n" \
+// curl "$URL" | awk '/sPacUtils =/,/ "";/' | sed -e 's/"$/" \\/g'
+//
+// Additionally, the definition for isPlainHostName() was removed, as it is
+// implemented by the C++ side already.
+#define PAC_JS_LIBRARY \
+ "function dnsDomainIs(host, domain) {\n" \
+ " return (host.length >= domain.length &&\n" \
+ " host.substring(host.length - domain.length) == domain);\n" \
+ "}\n" \
+ "" \
+ "function dnsDomainLevels(host) {\n" \
+ " return host.split('.').length - 1;\n" \
+ "}\n" \
+ "" \
+ "function isValidIpAddress(ipchars) {\n" \
+ " var matches = " \
+ "/^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(ipchars);\n" \
+ " if (matches == null) {\n" \
+ " return false;\n" \
+ " } else if (matches[1] > 255 || matches[2] > 255 || \n" \
+ " matches[3] > 255 || matches[4] > 255) {\n" \
+ " return false;\n" \
+ " }\n" \
+ " return true;\n" \
+ "}\n" \
+ "" \
+ "function convert_addr(ipchars) {\n" \
+ " var bytes = ipchars.split('.');\n" \
+ " var result = ((bytes[0] & 0xff) << 24) |\n" \
+ " ((bytes[1] & 0xff) << 16) |\n" \
+ " ((bytes[2] & 0xff) << 8) |\n" \
+ " (bytes[3] & 0xff);\n" \
+ " return result;\n" \
+ "}\n" \
+ "" \
+ "function isInNet(ipaddr, pattern, maskstr) {\n" \
+ " if (!isValidIpAddress(pattern) || !isValidIpAddress(maskstr)) {\n" \
+ " return false;\n" \
+ " }\n" \
+ " if (!isValidIpAddress(ipaddr)) {\n" \
+ " ipaddr = dnsResolve(ipaddr);\n" \
+ " if (ipaddr == null) {\n" \
+ " return false;\n" \
+ " }\n" \
+ " }\n" \
+ " var host = convert_addr(ipaddr);\n" \
+ " var pat = convert_addr(pattern);\n" \
+ " var mask = convert_addr(maskstr);\n" \
+ " return ((host & mask) == (pat & mask));\n" \
+ " \n" \
+ "}\n" \
+ "" \
+ "function isResolvable(host) {\n" \
+ " var ip = dnsResolve(host);\n" \
+ " return (ip != null);\n" \
+ "}\n" \
+ "" \
+ "function localHostOrDomainIs(host, hostdom) {\n" \
+ " return (host == hostdom) ||\n" \
+ " (hostdom.lastIndexOf(host + '.', 0) == 0);\n" \
+ "}\n" \
+ "" \
+ "function shExpMatch(url, pattern) {\n" \
+ " pattern = pattern.replace(/\\./g, '\\\\.');\n" \
+ " pattern = pattern.replace(/\\*/g, '.*');\n" \
+ " pattern = pattern.replace(/\\?/g, '.');\n" \
+ " var newRe = new RegExp('^'+pattern+'$');\n" \
+ " return newRe.test(url);\n" \
+ "}\n" \
+ "" \
+ "var wdays = {SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6};\n" \
+ "var months = {JAN: 0, FEB: 1, MAR: 2, APR: 3, MAY: 4, JUN: 5, JUL: 6, " \
+ "AUG: 7, SEP: 8, OCT: 9, NOV: 10, DEC: 11};\n" \
+ "" \
+ "function weekdayRange() {\n" \
+ " function getDay(weekday) {\n" \
+ " if (weekday in wdays) {\n" \
+ " return wdays[weekday];\n" \
+ " }\n" \
+ " return -1;\n" \
+ " }\n" \
+ " var date = new Date();\n" \
+ " var argc = arguments.length;\n" \
+ " var wday;\n" \
+ " if (argc < 1)\n" \
+ " return false;\n" \
+ " if (arguments[argc - 1] == 'GMT') {\n" \
+ " argc--;\n" \
+ " wday = date.getUTCDay();\n" \
+ " } else {\n" \
+ " wday = date.getDay();\n" \
+ " }\n" \
+ " var wd1 = getDay(arguments[0]);\n" \
+ " var wd2 = (argc == 2) ? getDay(arguments[1]) : wd1;\n" \
+ " return (wd1 == -1 || wd2 == -1) ? false\n" \
+ " : (wd1 <= wd2) ? (wd1 <= wday && wday " \
+ "<= wd2)\n" \
+ " : (wd2 >= wday || wday " \
+ ">= wd1);\n" \
+ "}\n" \
+ "" \
+ "function dateRange() {\n" \
+ " function getMonth(name) {\n" \
+ " if (name in months) {\n" \
+ " return months[name];\n" \
+ " }\n" \
+ " return -1;\n" \
+ " }\n" \
+ " var date = new Date();\n" \
+ " var argc = arguments.length;\n" \
+ " if (argc < 1) {\n" \
+ " return false;\n" \
+ " }\n" \
+ " var isGMT = (arguments[argc - 1] == 'GMT');\n" \
+ "\n" \
+ " if (isGMT) {\n" \
+ " argc--;\n" \
+ " }\n" \
+ " // function will work even without explict handling of this case\n" \
+ " if (argc == 1) {\n" \
+ " var tmp = parseInt(arguments[0]);\n" \
+ " if (isNaN(tmp)) {\n" \
+ " return ((isGMT ? date.getUTCMonth() : date.getMonth()) ==\n" \
+ " getMonth(arguments[0]));\n" \
+ " } else if (tmp < 32) {\n" \
+ " return ((isGMT ? date.getUTCDate() : date.getDate()) == " \
+ "tmp);\n" \
+ " } else { \n" \
+ " return ((isGMT ? date.getUTCFullYear() : date.getFullYear()) " \
+ "==\n" \
+ " tmp);\n" \
+ " }\n" \
+ " }\n" \
+ " var year = date.getFullYear();\n" \
+ " var date1, date2;\n" \
+ " date1 = new Date(year, 0, 1, 0, 0, 0);\n" \
+ " date2 = new Date(year, 11, 31, 23, 59, 59);\n" \
+ " var adjustMonth = false;\n" \
+ " for (var i = 0; i < (argc >> 1); i++) {\n" \
+ " var tmp = parseInt(arguments[i]);\n" \
+ " if (isNaN(tmp)) {\n" \
+ " var mon = getMonth(arguments[i]);\n" \
+ " date1.setMonth(mon);\n" \
+ " } else if (tmp < 32) {\n" \
+ " adjustMonth = (argc <= 2);\n" \
+ " date1.setDate(tmp);\n" \
+ " } else {\n" \
+ " date1.setFullYear(tmp);\n" \
+ " }\n" \
+ " }\n" \
+ " for (var i = (argc >> 1); i < argc; i++) {\n" \
+ " var tmp = parseInt(arguments[i]);\n" \
+ " if (isNaN(tmp)) {\n" \
+ " var mon = getMonth(arguments[i]);\n" \
+ " date2.setMonth(mon);\n" \
+ " } else if (tmp < 32) {\n" \
+ " date2.setDate(tmp);\n" \
+ " } else {\n" \
+ " date2.setFullYear(tmp);\n" \
+ " }\n" \
+ " }\n" \
+ " if (adjustMonth) {\n" \
+ " date1.setMonth(date.getMonth());\n" \
+ " date2.setMonth(date.getMonth());\n" \
+ " }\n" \
+ " if (isGMT) {\n" \
+ " var tmp = date;\n" \
+ " tmp.setFullYear(date.getUTCFullYear());\n" \
+ " tmp.setMonth(date.getUTCMonth());\n" \
+ " tmp.setDate(date.getUTCDate());\n" \
+ " tmp.setHours(date.getUTCHours());\n" \
+ " tmp.setMinutes(date.getUTCMinutes());\n" \
+ " tmp.setSeconds(date.getUTCSeconds());\n" \
+ " date = tmp;\n" \
+ " }\n" \
+ " return (date1 <= date2) ? (date1 <= date) && (date <= date2)\n" \
+ " : (date2 >= date) || (date >= date1);\n" \
+ "}\n" \
+ "" \
+ "function timeRange() {\n" \
+ " var argc = arguments.length;\n" \
+ " var date = new Date();\n" \
+ " var isGMT= false;\n" \
+ "" \
+ " if (argc < 1) {\n" \
+ " return false;\n" \
+ " }\n" \
+ " if (arguments[argc - 1] == 'GMT') {\n" \
+ " isGMT = true;\n" \
+ " argc--;\n" \
+ " }\n" \
+ "\n" \
+ " var hour = isGMT ? date.getUTCHours() : date.getHours();\n" \
+ " var date1, date2;\n" \
+ " date1 = new Date();\n" \
+ " date2 = new Date();\n" \
+ "\n" \
+ " if (argc == 1) {\n" \
+ " return (hour == arguments[0]);\n" \
+ " } else if (argc == 2) {\n" \
+ " return ((arguments[0] <= hour) && (hour <= arguments[1]));\n" \
+ " } else {\n" \
+ " switch (argc) {\n" \
+ " case 6:\n" \
+ " date1.setSeconds(arguments[2]);\n" \
+ " date2.setSeconds(arguments[5]);\n" \
+ " case 4:\n" \
+ " var middle = argc >> 1;\n" \
+ " date1.setHours(arguments[0]);\n" \
+ " date1.setMinutes(arguments[1]);\n" \
+ " date2.setHours(arguments[middle]);\n" \
+ " date2.setMinutes(arguments[middle + 1]);\n" \
+ " if (middle == 2) {\n" \
+ " date2.setSeconds(59);\n" \
+ " }\n" \
+ " break;\n" \
+ " default:\n" \
+ " throw 'timeRange: bad number of arguments'\n" \
+ " }\n" \
+ " }\n" \
+ "\n" \
+ " if (isGMT) {\n" \
+ " date.setFullYear(date.getUTCFullYear());\n" \
+ " date.setMonth(date.getUTCMonth());\n" \
+ " date.setDate(date.getUTCDate());\n" \
+ " date.setHours(date.getUTCHours());\n" \
+ " date.setMinutes(date.getUTCMinutes());\n" \
+ " date.setSeconds(date.getUTCSeconds());\n" \
+ " }\n" \
+ " return (date1 <= date2) ? (date1 <= date) && (date <= date2)\n" \
+ " : (date2 >= date) || (date >= date1);\n" \
+ "\n" \
"}\n"
// This is a Microsoft extension to PAC for IPv6, see:
diff --git a/chromium/net/proxy_resolution/polling_proxy_config_service.cc b/chromium/net/proxy_resolution/polling_proxy_config_service.cc
index f54dd4de1d6..54c42bf04d7 100644
--- a/chromium/net/proxy_resolution/polling_proxy_config_service.cc
+++ b/chromium/net/proxy_resolution/polling_proxy_config_service.cc
@@ -13,7 +13,7 @@
#include "base/synchronization/lock.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "net/proxy_resolution/proxy_config.h"
+#include "net/proxy_resolution/proxy_config_with_annotation.h"
namespace net {
@@ -23,9 +23,12 @@ namespace net {
class PollingProxyConfigService::Core
: public base::RefCountedThreadSafe<PollingProxyConfigService::Core> {
public:
- Core(base::TimeDelta poll_interval, GetConfigFunction get_config_func)
+ Core(base::TimeDelta poll_interval,
+ GetConfigFunction get_config_func,
+ const NetworkTrafficAnnotationTag& traffic_annotation)
: get_config_func_(get_config_func),
poll_interval_(poll_interval),
+ traffic_annotation_(traffic_annotation),
have_initialized_origin_runner_(false),
has_config_(false),
poll_task_outstanding_(false),
@@ -38,7 +41,7 @@ class PollingProxyConfigService::Core
origin_task_runner_ = NULL;
}
- bool GetLatestProxyConfig(ProxyConfig* config) {
+ bool GetLatestProxyConfig(ProxyConfigWithAnnotation* config) {
LazyInitializeOriginLoop();
DCHECK(origin_task_runner_->BelongsToCurrentThread());
@@ -101,8 +104,8 @@ class PollingProxyConfigService::Core
~Core() = default;
void PollAsync(GetConfigFunction func) {
- ProxyConfig config;
- func(&config);
+ ProxyConfigWithAnnotation config;
+ func(traffic_annotation_, &config);
base::AutoLock lock(lock_);
if (origin_task_runner_.get()) {
@@ -112,7 +115,7 @@ class PollingProxyConfigService::Core
}
// Called after the worker thread has finished retrieving a configuration.
- void GetConfigCompleted(const ProxyConfig& config) {
+ void GetConfigCompleted(const ProxyConfigWithAnnotation& config) {
DCHECK(poll_task_outstanding_);
poll_task_outstanding_ = false;
@@ -121,7 +124,7 @@ class PollingProxyConfigService::Core
DCHECK(origin_task_runner_->BelongsToCurrentThread());
- if (!has_config_ || !last_config_.Equals(config)) {
+ if (!has_config_ || !last_config_.value().Equals(config.value())) {
// If the configuration has changed, notify the observers.
has_config_ = true;
last_config_ = config;
@@ -147,10 +150,12 @@ class PollingProxyConfigService::Core
GetConfigFunction get_config_func_;
base::ObserverList<Observer> observers_;
- ProxyConfig last_config_;
+ ProxyConfigWithAnnotation last_config_;
base::TimeTicks last_poll_time_;
base::TimeDelta poll_interval_;
+ const NetworkTrafficAnnotationTag traffic_annotation_;
+
base::Lock lock_;
scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_;
@@ -169,7 +174,8 @@ void PollingProxyConfigService::RemoveObserver(Observer* observer) {
}
ProxyConfigService::ConfigAvailability
- PollingProxyConfigService::GetLatestProxyConfig(ProxyConfig* config) {
+PollingProxyConfigService::GetLatestProxyConfig(
+ ProxyConfigWithAnnotation* config) {
return core_->GetLatestProxyConfig(config) ? CONFIG_VALID : CONFIG_PENDING;
}
@@ -179,9 +185,9 @@ void PollingProxyConfigService::OnLazyPoll() {
PollingProxyConfigService::PollingProxyConfigService(
base::TimeDelta poll_interval,
- GetConfigFunction get_config_func)
- : core_(new Core(poll_interval, get_config_func)) {
-}
+ GetConfigFunction get_config_func,
+ const NetworkTrafficAnnotationTag& traffic_annotation)
+ : core_(new Core(poll_interval, get_config_func, traffic_annotation)) {}
PollingProxyConfigService::~PollingProxyConfigService() {
core_->Orphan();
diff --git a/chromium/net/proxy_resolution/polling_proxy_config_service.h b/chromium/net/proxy_resolution/polling_proxy_config_service.h
index dccdab481a0..382e5b38d46 100644
--- a/chromium/net/proxy_resolution/polling_proxy_config_service.h
+++ b/chromium/net/proxy_resolution/polling_proxy_config_service.h
@@ -11,6 +11,7 @@
#include "base/time/time.h"
#include "net/base/net_export.h"
#include "net/proxy_resolution/proxy_config_service.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -24,21 +25,24 @@ class NET_EXPORT_PRIVATE PollingProxyConfigService : public ProxyConfigService {
// ProxyConfigService implementation:
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
- ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) override;
+ ConfigAvailability GetLatestProxyConfig(
+ ProxyConfigWithAnnotation* config) override;
void OnLazyPoll() override;
protected:
// Function for retrieving the current proxy configuration.
// Implementors must be threadsafe as the function will be invoked from
// worker threads.
- typedef void (*GetConfigFunction)(ProxyConfig*);
+ typedef void (*GetConfigFunction)(NetworkTrafficAnnotationTag,
+ ProxyConfigWithAnnotation*);
// Creates a polling-based ProxyConfigService which will test for new
// settings at most every |poll_interval| time by calling |get_config_func|
// on a worker thread.
PollingProxyConfigService(
base::TimeDelta poll_interval,
- GetConfigFunction get_config_func);
+ GetConfigFunction get_config_func,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
~PollingProxyConfigService() override;
diff --git a/chromium/net/proxy_resolution/proxy_config.cc b/chromium/net/proxy_resolution/proxy_config.cc
index f33bab69fdf..7c5c189f6c3 100644
--- a/chromium/net/proxy_resolution/proxy_config.cc
+++ b/chromium/net/proxy_resolution/proxy_config.cc
@@ -190,10 +190,7 @@ const ProxyList* ProxyConfig::ProxyRules::GetProxyListForWebSocketScheme()
return NULL;
}
-ProxyConfig::ProxyConfig()
- : auto_detect_(false),
- pac_mandatory_(false),
- source_(PROXY_CONFIG_SOURCE_UNKNOWN) {}
+ProxyConfig::ProxyConfig() : auto_detect_(false), pac_mandatory_(false) {}
ProxyConfig::ProxyConfig(const ProxyConfig& config) = default;
@@ -272,10 +269,7 @@ std::unique_ptr<base::DictionaryValue> ProxyConfig::ToValue() const {
}
}
- // Output the source.
- dict->SetString("source", ProxyConfigSourceToString(source_));
-
return dict;
}
-} // namespace net
+} // namespace net \ No newline at end of file
diff --git a/chromium/net/proxy_resolution/proxy_config.h b/chromium/net/proxy_resolution/proxy_config.h
index 0ae0317c98a..02d12a3376c 100644
--- a/chromium/net/proxy_resolution/proxy_config.h
+++ b/chromium/net/proxy_resolution/proxy_config.h
@@ -10,7 +10,6 @@
#include "net/base/net_export.h"
#include "net/base/proxy_server.h"
#include "net/proxy_resolution/proxy_bypass_rules.h"
-#include "net/proxy_resolution/proxy_config_source.h"
#include "net/proxy_resolution/proxy_list.h"
#include "url/gurl.h"
@@ -202,14 +201,6 @@ class NET_EXPORT ProxyConfig {
return auto_detect_;
}
- void set_source(ProxyConfigSource source) {
- source_ = source;
- }
-
- ProxyConfigSource source() const {
- return source_;
- }
-
// Helpers to construct some common proxy configurations.
static ProxyConfig CreateDirect() {
@@ -237,15 +228,12 @@ class NET_EXPORT ProxyConfig {
// If non-empty, indicates the URL of the proxy auto-config file to use.
GURL pac_url_;
- // If true, blocks all traffic in case fetching the pac script from |pac_url_|
+ // If true, blocks all traffic in case fetching the PAC script from |pac_url_|
// fails. Only valid if |pac_url_| is non-empty.
bool pac_mandatory_;
// Manual proxy settings.
ProxyRules proxy_rules_;
-
- // Source of proxy settings.
- ProxyConfigSource source_;
};
} // namespace net
diff --git a/chromium/net/proxy_resolution/proxy_config_service.h b/chromium/net/proxy_resolution/proxy_config_service.h
index 63429159d80..b8a3f7997dd 100644
--- a/chromium/net/proxy_resolution/proxy_config_service.h
+++ b/chromium/net/proxy_resolution/proxy_config_service.h
@@ -9,7 +9,7 @@
namespace net {
-class ProxyConfig;
+class ProxyConfigWithAnnotation;
// Service for watching when the proxy settings have changed.
class NET_EXPORT ProxyConfigService {
@@ -33,7 +33,7 @@ class NET_EXPORT ProxyConfigService {
// the new availability status and can be CONFIG_UNSET or CONFIG_VALID (in
// which case |config| contains the configuration). Implementors must not
// pass CONFIG_PENDING.
- virtual void OnProxyConfigChanged(const ProxyConfig& config,
+ virtual void OnProxyConfigChanged(const ProxyConfigWithAnnotation& config,
ConfigAvailability availability) = 0;
};
@@ -51,7 +51,8 @@ class NET_EXPORT ProxyConfigService {
// some point in the future once the configuration is available.
// Note that to avoid re-entrancy problems, implementations should not
// dispatch any change notifications from within this function.
- virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) = 0;
+ virtual ConfigAvailability GetLatestProxyConfig(
+ ProxyConfigWithAnnotation* config) = 0;
// ProxyResolutionService will call this periodically during periods of
// activity. It can be used as a signal for polling-based implementations.
diff --git a/chromium/net/proxy_resolution/proxy_config_service_android.cc b/chromium/net/proxy_resolution/proxy_config_service_android.cc
index ba844d07a07..cbc0a904b4a 100644
--- a/chromium/net/proxy_resolution/proxy_config_service_android.cc
+++ b/chromium/net/proxy_resolution/proxy_config_service_android.cc
@@ -22,7 +22,7 @@
#include "base/strings/stringprintf.h"
#include "jni/ProxyChangeListener_jni.h"
#include "net/base/host_port_pair.h"
-#include "net/proxy_resolution/proxy_config.h"
+#include "net/proxy_resolution/proxy_config_with_annotation.h"
#include "url/third_party/mozilla/url_parse.h"
using base::android::AttachCurrentThread;
@@ -146,9 +146,14 @@ bool GetProxyRules(const GetPropertyCallback& get_property,
};
void GetLatestProxyConfigInternal(const GetPropertyCallback& get_property,
- ProxyConfig* config) {
- if (!GetProxyRules(get_property, &config->proxy_rules()))
- *config = ProxyConfig::CreateDirect();
+ ProxyConfigWithAnnotation* config) {
+ ProxyConfig proxy_config;
+ if (GetProxyRules(get_property, &proxy_config.proxy_rules())) {
+ *config =
+ ProxyConfigWithAnnotation(proxy_config, NO_TRAFFIC_ANNOTATION_YET);
+ } else {
+ *config = ProxyConfigWithAnnotation::CreateDirect();
+ }
}
std::string GetJavaProperty(const std::string& property) {
@@ -166,14 +171,17 @@ void CreateStaticProxyConfig(const std::string& host,
int port,
const std::string& pac_url,
const std::vector<std::string>& exclusion_list,
- ProxyConfig* config) {
+ ProxyConfigWithAnnotation* config) {
+ ProxyConfig proxy_config;
if (!pac_url.empty()) {
- config->set_pac_url(GURL(pac_url));
- config->set_pac_mandatory(false);
+ proxy_config.set_pac_url(GURL(pac_url));
+ proxy_config.set_pac_mandatory(false);
+ *config =
+ ProxyConfigWithAnnotation(proxy_config, NO_TRAFFIC_ANNOTATION_YET);
} else if (port != 0) {
std::string rules = base::StringPrintf("%s:%d", host.c_str(), port);
- config->proxy_rules().ParseFromString(rules);
- config->proxy_rules().bypass_rules.Clear();
+ proxy_config.proxy_rules().ParseFromString(rules);
+ proxy_config.proxy_rules().bypass_rules.Clear();
std::vector<std::string>::const_iterator it;
for (it = exclusion_list.begin(); it != exclusion_list.end(); ++it) {
@@ -181,10 +189,13 @@ void CreateStaticProxyConfig(const std::string& host,
base::TrimWhitespaceASCII(*it, base::TRIM_ALL, &pattern);
if (pattern.empty())
continue;
- config->proxy_rules().bypass_rules.AddRuleForHostname("", pattern, -1);
+ proxy_config.proxy_rules().bypass_rules.AddRuleForHostname("", pattern,
+ -1);
}
+ *config =
+ ProxyConfigWithAnnotation(proxy_config, NO_TRAFFIC_ANNOTATION_YET);
} else {
- *config = ProxyConfig::CreateDirect();
+ *config = ProxyConfigWithAnnotation::CreateDirect();
}
}
@@ -216,7 +227,7 @@ class ProxyConfigServiceAndroid::Delegate
void FetchInitialConfig() {
DCHECK(InJNISequence());
- ProxyConfig proxy_config;
+ ProxyConfigWithAnnotation proxy_config;
GetLatestProxyConfigInternal(get_property_callback_, &proxy_config);
network_task_runner_->PostTask(
FROM_HERE, base::Bind(&Delegate::SetNewConfigInNetworkSequence, this,
@@ -243,7 +254,7 @@ class ProxyConfigServiceAndroid::Delegate
observers_.RemoveObserver(observer);
}
- ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) {
+ ConfigAvailability GetLatestProxyConfig(ProxyConfigWithAnnotation* config) {
DCHECK(InNetworkSequence());
if (!config)
return ProxyConfigService::CONFIG_UNSET;
@@ -254,7 +265,7 @@ class ProxyConfigServiceAndroid::Delegate
// Called in the JNI sequence.
void ProxySettingsChanged() {
DCHECK(InJNISequence());
- ProxyConfig proxy_config;
+ ProxyConfigWithAnnotation proxy_config;
GetLatestProxyConfigInternal(get_property_callback_, &proxy_config);
network_task_runner_->PostTask(
FROM_HERE, base::Bind(&Delegate::SetNewConfigInNetworkSequence, this,
@@ -267,7 +278,7 @@ class ProxyConfigServiceAndroid::Delegate
const std::string& pac_url,
const std::vector<std::string>& exclusion_list) {
DCHECK(InJNISequence());
- ProxyConfig proxy_config;
+ ProxyConfigWithAnnotation proxy_config;
if (exclude_pac_url_) {
CreateStaticProxyConfig(host, port, "", exclusion_list, &proxy_config);
} else {
@@ -327,7 +338,8 @@ class ProxyConfigServiceAndroid::Delegate
}
// Called on the network sequence.
- void SetNewConfigInNetworkSequence(const ProxyConfig& proxy_config) {
+ void SetNewConfigInNetworkSequence(
+ const ProxyConfigWithAnnotation& proxy_config) {
DCHECK(InNetworkSequence());
proxy_config_ = proxy_config;
for (auto& observer : observers_) {
@@ -351,7 +363,7 @@ class ProxyConfigServiceAndroid::Delegate
scoped_refptr<base::SequencedTaskRunner> network_task_runner_;
scoped_refptr<base::SequencedTaskRunner> jni_task_runner_;
GetPropertyCallback get_property_callback_;
- ProxyConfig proxy_config_;
+ ProxyConfigWithAnnotation proxy_config_;
bool exclude_pac_url_;
DISALLOW_COPY_AND_ASSIGN(Delegate);
@@ -383,7 +395,8 @@ void ProxyConfigServiceAndroid::RemoveObserver(Observer* observer) {
}
ProxyConfigService::ConfigAvailability
-ProxyConfigServiceAndroid::GetLatestProxyConfig(ProxyConfig* config) {
+ProxyConfigServiceAndroid::GetLatestProxyConfig(
+ ProxyConfigWithAnnotation* config) {
return delegate_->GetLatestProxyConfig(config);
}
diff --git a/chromium/net/proxy_resolution/proxy_config_service_android.h b/chromium/net/proxy_resolution/proxy_config_service_android.h
index 6f2297730c1..fd2729d39a4 100644
--- a/chromium/net/proxy_resolution/proxy_config_service_android.h
+++ b/chromium/net/proxy_resolution/proxy_config_service_android.h
@@ -21,7 +21,7 @@ class SequencedTaskRunner;
namespace net {
-class ProxyConfig;
+class ProxyConfigWithAnnotation;
class NET_EXPORT ProxyConfigServiceAndroid : public ProxyConfigService {
public:
@@ -73,7 +73,8 @@ class NET_EXPORT ProxyConfigServiceAndroid : public ProxyConfigService {
// Called only on the network thread.
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
- ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) override;
+ ConfigAvailability GetLatestProxyConfig(
+ ProxyConfigWithAnnotation* config) override;
private:
friend class ProxyConfigServiceAndroidTestBase;
diff --git a/chromium/net/proxy_resolution/proxy_config_service_android_unittest.cc b/chromium/net/proxy_resolution/proxy_config_service_android_unittest.cc
index ceae603acfa..14a494412c2 100644
--- a/chromium/net/proxy_resolution/proxy_config_service_android_unittest.cc
+++ b/chromium/net/proxy_resolution/proxy_config_service_android_unittest.cc
@@ -13,8 +13,9 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "jni/AndroidProxyConfigServiceTestUtil_jni.h"
-#include "net/proxy_resolution/proxy_config.h"
+#include "net/proxy_resolution/proxy_config_with_annotation.h"
#include "net/proxy_resolution/proxy_info.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -27,7 +28,7 @@ class TestObserver : public ProxyConfigService::Observer {
// ProxyConfigService::Observer:
void OnProxyConfigChanged(
- const ProxyConfig& config,
+ const ProxyConfigWithAnnotation& config,
ProxyConfigService::ConfigAvailability availability) override {
config_ = config;
availability_ = availability;
@@ -37,12 +38,10 @@ class TestObserver : public ProxyConfigService::Observer {
return availability_;
}
- const ProxyConfig& config() const {
- return config_;
- }
+ const ProxyConfigWithAnnotation& config() const { return config_; }
private:
- ProxyConfig config_;
+ ProxyConfigWithAnnotation config_;
ProxyConfigService::ConfigAvailability availability_;
};
@@ -103,11 +102,11 @@ class ProxyConfigServiceAndroidTestBase : public testing::Test {
void TestMapping(const std::string& url, const std::string& expected) {
ProxyConfigService::ConfigAvailability availability;
- ProxyConfig proxy_config;
+ ProxyConfigWithAnnotation proxy_config;
availability = service_.GetLatestProxyConfig(&proxy_config);
EXPECT_EQ(ProxyConfigService::CONFIG_VALID, availability);
ProxyInfo proxy_info;
- proxy_config.proxy_rules().Apply(GURL(url), &proxy_info);
+ proxy_config.value().proxy_rules().Apply(GURL(url), &proxy_info);
EXPECT_EQ(expected, proxy_info.ToPacString());
}
@@ -147,13 +146,13 @@ TEST_F(ProxyConfigServiceAndroidTest, TestChangePropertiesNotification) {
AddProperty("http.proxyHost", "localhost");
ProxySettingsChanged();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID, observer_.availability());
- EXPECT_FALSE(observer_.config().proxy_rules().empty());
+ EXPECT_FALSE(observer_.config().value().proxy_rules().empty());
// Set up an empty configuration
ClearConfiguration();
ProxySettingsChanged();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID, observer_.availability());
- EXPECT_TRUE(observer_.config().proxy_rules().empty());
+ EXPECT_TRUE(observer_.config().value().proxy_rules().empty());
}
TEST_F(ProxyConfigServiceAndroidWithInitialConfigTest, TestInitialConfig) {
diff --git a/chromium/net/proxy_resolution/proxy_config_service_fixed.cc b/chromium/net/proxy_resolution/proxy_config_service_fixed.cc
index 9f06bf89d6e..92dadcc1892 100644
--- a/chromium/net/proxy_resolution/proxy_config_service_fixed.cc
+++ b/chromium/net/proxy_resolution/proxy_config_service_fixed.cc
@@ -6,14 +6,15 @@
namespace net {
-ProxyConfigServiceFixed::ProxyConfigServiceFixed(const ProxyConfig& pc)
- : pc_(pc) {
-}
+ProxyConfigServiceFixed::ProxyConfigServiceFixed(
+ const ProxyConfigWithAnnotation& pc)
+ : pc_(pc) {}
ProxyConfigServiceFixed::~ProxyConfigServiceFixed() = default;
ProxyConfigService::ConfigAvailability
- ProxyConfigServiceFixed::GetLatestProxyConfig(ProxyConfig* config) {
+ProxyConfigServiceFixed::GetLatestProxyConfig(
+ ProxyConfigWithAnnotation* config) {
*config = pc_;
return CONFIG_VALID;
}
diff --git a/chromium/net/proxy_resolution/proxy_config_service_fixed.h b/chromium/net/proxy_resolution/proxy_config_service_fixed.h
index 578f9f0fa34..86733f38371 100644
--- a/chromium/net/proxy_resolution/proxy_config_service_fixed.h
+++ b/chromium/net/proxy_resolution/proxy_config_service_fixed.h
@@ -8,24 +8,25 @@
#include "base/compiler_specific.h"
#include "net/base/net_errors.h"
#include "net/base/net_export.h"
-#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service.h"
+#include "net/proxy_resolution/proxy_config_with_annotation.h"
namespace net {
// Implementation of ProxyConfigService that returns a fixed result.
class NET_EXPORT ProxyConfigServiceFixed : public ProxyConfigService {
public:
- explicit ProxyConfigServiceFixed(const ProxyConfig& pc);
+ explicit ProxyConfigServiceFixed(const ProxyConfigWithAnnotation& pc);
~ProxyConfigServiceFixed() override;
// ProxyConfigService methods:
void AddObserver(Observer* observer) override {}
void RemoveObserver(Observer* observer) override {}
- ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) override;
+ ConfigAvailability GetLatestProxyConfig(
+ ProxyConfigWithAnnotation* config) override;
private:
- ProxyConfig pc_;
+ ProxyConfigWithAnnotation pc_;
};
} // namespace net
diff --git a/chromium/net/proxy_resolution/proxy_config_service_ios.cc b/chromium/net/proxy_resolution/proxy_config_service_ios.cc
index 468d4891b62..14c1f905520 100644
--- a/chromium/net/proxy_resolution/proxy_config_service_ios.cc
+++ b/chromium/net/proxy_resolution/proxy_config_service_ios.cc
@@ -11,7 +11,7 @@
#include "base/mac/scoped_cftyperef.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/sys_string_conversions.h"
-#include "net/proxy_resolution/proxy_config.h"
+#include "net/proxy_resolution/proxy_config_with_annotation.h"
namespace net {
@@ -36,11 +36,12 @@ bool GetBoolFromDictionary(CFDictionaryRef dict,
return default_value;
}
-void GetCurrentProxyConfig(ProxyConfig* config) {
+void GetCurrentProxyConfig(const NetworkTrafficAnnotationTag traffic_annotation,
+ ProxyConfigWithAnnotation* config) {
base::ScopedCFTypeRef<CFDictionaryRef> config_dict(
CFNetworkCopySystemProxySettings());
DCHECK(config_dict);
-
+ ProxyConfig proxy_config;
// Auto-detect is not supported.
// The kCFNetworkProxiesProxyAutoDiscoveryEnable key is not available on iOS.
@@ -52,7 +53,7 @@ void GetCurrentProxyConfig(ProxyConfig* config) {
CFStringRef pac_url_ref = base::mac::GetValueFromDictionary<CFStringRef>(
config_dict.get(), kCFNetworkProxiesProxyAutoConfigURLString);
if (pac_url_ref)
- config->set_pac_url(GURL(base::SysCFStringRefToUTF8(pac_url_ref)));
+ proxy_config.set_pac_url(GURL(base::SysCFStringRefToUTF8(pac_url_ref)));
}
// Proxies (for now http).
@@ -76,12 +77,13 @@ void GetCurrentProxyConfig(ProxyConfig* config) {
kCFNetworkProxiesHTTPProxy,
kCFNetworkProxiesHTTPPort);
if (proxy_server.is_valid()) {
- config->proxy_rules().type =
+ proxy_config.proxy_rules().type =
ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME;
- config->proxy_rules().proxies_for_http.SetSingleProxyServer(proxy_server);
+ proxy_config.proxy_rules().proxies_for_http.SetSingleProxyServer(
+ proxy_server);
// Desktop Safari applies the HTTP proxy to http:// URLs only, but
// Mobile Safari applies the HTTP proxy to https:// URLs as well.
- config->proxy_rules().proxies_for_https.SetSingleProxyServer(
+ proxy_config.proxy_rules().proxies_for_https.SetSingleProxyServer(
proxy_server);
}
}
@@ -93,15 +95,16 @@ void GetCurrentProxyConfig(ProxyConfig* config) {
// The kCFNetworkProxiesExcludeSimpleHostnames key is not available on iOS.
// Source
- config->set_source(PROXY_CONFIG_SOURCE_SYSTEM);
+ *config = ProxyConfigWithAnnotation(proxy_config, traffic_annotation);
}
} // namespace
-ProxyConfigServiceIOS::ProxyConfigServiceIOS()
+ProxyConfigServiceIOS::ProxyConfigServiceIOS(
+ const NetworkTrafficAnnotationTag& traffic_annotation)
: PollingProxyConfigService(base::TimeDelta::FromSeconds(kPollIntervalSec),
- GetCurrentProxyConfig) {
-}
+ GetCurrentProxyConfig,
+ traffic_annotation) {}
ProxyConfigServiceIOS::~ProxyConfigServiceIOS() {
}
diff --git a/chromium/net/proxy_resolution/proxy_config_service_ios.h b/chromium/net/proxy_resolution/proxy_config_service_ios.h
index f6e342c5de0..a56054b94a0 100644
--- a/chromium/net/proxy_resolution/proxy_config_service_ios.h
+++ b/chromium/net/proxy_resolution/proxy_config_service_ios.h
@@ -13,7 +13,8 @@ namespace net {
class ProxyConfigServiceIOS : public PollingProxyConfigService {
public:
// Constructs a ProxyConfigService that watches the iOS system proxy settings.
- explicit ProxyConfigServiceIOS();
+ explicit ProxyConfigServiceIOS(
+ const NetworkTrafficAnnotationTag& traffic_annotation);
~ProxyConfigServiceIOS() override;
private:
diff --git a/chromium/net/proxy_resolution/proxy_config_service_linux.cc b/chromium/net/proxy_resolution/proxy_config_service_linux.cc
index 9f2db1c6ca8..90ed262b768 100644
--- a/chromium/net/proxy_resolution/proxy_config_service_linux.cc
+++ b/chromium/net/proxy_resolution/proxy_config_service_linux.cc
@@ -30,7 +30,6 @@
#include "base/threading/thread_restrictions.h"
#include "base/timer/timer.h"
#include "net/base/proxy_server.h"
-#include "net/proxy_resolution/proxy_config.h"
#if defined(USE_GIO)
#include <gio/gio.h>
@@ -82,13 +81,12 @@ std::string FixupProxyHostScheme(ProxyServer::Scheme scheme,
return host;
}
-ProxyConfig GetConfigOrDirect(
- const base::Optional<ProxyConfig>& optional_config) {
+ProxyConfigWithAnnotation GetConfigOrDirect(
+ const base::Optional<ProxyConfigWithAnnotation>& optional_config) {
if (optional_config)
return optional_config.value();
- ProxyConfig config = ProxyConfig::CreateDirect();
- config.set_source(PROXY_CONFIG_SOURCE_SYSTEM_FAILED);
+ ProxyConfigWithAnnotation config = ProxyConfigWithAnnotation::CreateDirect();
return config;
}
@@ -125,10 +123,9 @@ bool ProxyConfigServiceLinux::Delegate::GetProxyFromEnvVar(
result_server);
}
-base::Optional<ProxyConfig>
+base::Optional<ProxyConfigWithAnnotation>
ProxyConfigServiceLinux::Delegate::GetConfigFromEnv() {
- base::Optional<ProxyConfig> config;
- config.emplace();
+ ProxyConfig config;
// Check for automatic configuration first, in
// "auto_proxy". Possibly only the "environment_proxy" firefox
@@ -138,22 +135,23 @@ ProxyConfigServiceLinux::Delegate::GetConfigFromEnv() {
if (env_var_getter_->GetVar("auto_proxy", &auto_proxy)) {
if (auto_proxy.empty()) {
// Defined and empty => autodetect
- config->set_auto_detect(true);
+ config.set_auto_detect(true);
} else {
// specified autoconfig URL
- config->set_pac_url(GURL(auto_proxy));
+ config.set_pac_url(GURL(auto_proxy));
}
- return config;
+ return ProxyConfigWithAnnotation(
+ config, NetworkTrafficAnnotationTag(traffic_annotation_));
}
// "all_proxy" is a shortcut to avoid defining {http,https,ftp}_proxy.
ProxyServer proxy_server;
if (GetProxyFromEnvVar("all_proxy", &proxy_server)) {
- config->proxy_rules().type = ProxyConfig::ProxyRules::Type::PROXY_LIST;
- config->proxy_rules().single_proxies.SetSingleProxyServer(proxy_server);
+ config.proxy_rules().type = ProxyConfig::ProxyRules::Type::PROXY_LIST;
+ config.proxy_rules().single_proxies.SetSingleProxyServer(proxy_server);
} else {
bool have_http = GetProxyFromEnvVar("http_proxy", &proxy_server);
if (have_http)
- config->proxy_rules().proxies_for_http.SetSingleProxyServer(proxy_server);
+ config.proxy_rules().proxies_for_http.SetSingleProxyServer(proxy_server);
// It would be tempting to let http_proxy apply for all protocols
// if https_proxy and ftp_proxy are not defined. Googling turns up
// several documents that mention only http_proxy. But then the
@@ -161,18 +159,17 @@ ProxyConfigServiceLinux::Delegate::GetConfigFromEnv() {
// like other apps do this. So we will refrain.
bool have_https = GetProxyFromEnvVar("https_proxy", &proxy_server);
if (have_https)
- config->proxy_rules().proxies_for_https.
- SetSingleProxyServer(proxy_server);
+ config.proxy_rules().proxies_for_https.SetSingleProxyServer(proxy_server);
bool have_ftp = GetProxyFromEnvVar("ftp_proxy", &proxy_server);
if (have_ftp)
- config->proxy_rules().proxies_for_ftp.SetSingleProxyServer(proxy_server);
+ config.proxy_rules().proxies_for_ftp.SetSingleProxyServer(proxy_server);
if (have_http || have_https || have_ftp) {
// mustn't change type unless some rules are actually set.
- config->proxy_rules().type =
+ config.proxy_rules().type =
ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME;
}
}
- if (config->proxy_rules().empty()) {
+ if (config.proxy_rules().empty()) {
// If the above were not defined, try for socks.
// For environment variables, we default to version 5, per the gnome
// documentation: http://library.gnome.org/devel/gnet/stable/gnet-socks.html
@@ -182,25 +179,29 @@ ProxyConfigServiceLinux::Delegate::GetConfigFromEnv() {
&& env_version == "4")
scheme = ProxyServer::SCHEME_SOCKS4;
if (GetProxyFromEnvVarForScheme("SOCKS_SERVER", scheme, &proxy_server)) {
- config->proxy_rules().type = ProxyConfig::ProxyRules::Type::PROXY_LIST;
- config->proxy_rules().single_proxies.SetSingleProxyServer(proxy_server);
+ config.proxy_rules().type = ProxyConfig::ProxyRules::Type::PROXY_LIST;
+ config.proxy_rules().single_proxies.SetSingleProxyServer(proxy_server);
}
}
// Look for the proxy bypass list.
std::string no_proxy;
env_var_getter_->GetVar("no_proxy", &no_proxy);
- if (config->proxy_rules().empty()) {
+ if (config.proxy_rules().empty()) {
// Having only "no_proxy" set, presumably to "*", makes it
// explicit that env vars do specify a configuration: having no
// rules specified only means the user explicitly asks for direct
// connections.
- return !no_proxy.empty() ? config : base::Optional<ProxyConfig>();
+ return !no_proxy.empty()
+ ? ProxyConfigWithAnnotation(
+ config, NetworkTrafficAnnotationTag(traffic_annotation_))
+ : base::Optional<ProxyConfigWithAnnotation>();
}
// Note that this uses "suffix" matching. So a bypass of "google.com"
// is understood to mean a bypass of "*google.com".
- config->proxy_rules().bypass_rules.ParseFromStringUsingSuffixMatching(
+ config.proxy_rules().bypass_rules.ParseFromStringUsingSuffixMatching(
no_proxy);
- return config;
+ return ProxyConfigWithAnnotation(
+ config, NetworkTrafficAnnotationTag(traffic_annotation_));
}
namespace {
@@ -316,10 +317,6 @@ class SettingGetterImplGSettings
return task_runner_;
}
- ProxyConfigSource GetConfigSource() override {
- return PROXY_CONFIG_SOURCE_GSETTINGS;
- }
-
bool GetString(StringSetting key, std::string* result) override {
DCHECK(client_);
switch (key) {
@@ -649,10 +646,6 @@ class SettingGetterImplKDE : public ProxyConfigServiceLinux::SettingGetter {
return file_task_runner_;
}
- ProxyConfigSource GetConfigSource() override {
- return PROXY_CONFIG_SOURCE_KDE;
- }
-
bool GetString(StringSetting key, std::string* result) override {
string_map_type::iterator it = string_table_.find(key);
if (it == string_table_.end())
@@ -1026,20 +1019,20 @@ bool ProxyConfigServiceLinux::Delegate::GetProxyFromSettings(
return false;
}
-base::Optional<ProxyConfig>
+base::Optional<ProxyConfigWithAnnotation>
ProxyConfigServiceLinux::Delegate::GetConfigFromSettings() {
- base::Optional<ProxyConfig> config;
- config.emplace();
+ ProxyConfig config;
std::string mode;
if (!setting_getter_->GetString(SettingGetter::PROXY_MODE, &mode)) {
// We expect this to always be set, so if we don't see it then we probably
// have a gsettings problem, and so we don't have a valid proxy config.
- return base::Optional<ProxyConfig>();
+ return base::Optional<ProxyConfigWithAnnotation>();
}
if (mode == "none") {
// Specifically specifies no proxy.
- return config;
+ return ProxyConfigWithAnnotation(
+ config, NetworkTrafficAnnotationTag(traffic_annotation_));
}
if (mode == "auto") {
@@ -1053,18 +1046,20 @@ ProxyConfigServiceLinux::Delegate::GetConfigFromSettings() {
pac_url_str = "file://" + pac_url_str;
GURL pac_url(pac_url_str);
if (!pac_url.is_valid())
- return base::Optional<ProxyConfig>();
- config->set_pac_url(pac_url);
- return config;
+ return base::Optional<ProxyConfigWithAnnotation>();
+ config.set_pac_url(pac_url);
+ return ProxyConfigWithAnnotation(
+ config, NetworkTrafficAnnotationTag(traffic_annotation_));
}
}
- config->set_auto_detect(true);
- return config;
+ config.set_auto_detect(true);
+ return ProxyConfigWithAnnotation(
+ config, NetworkTrafficAnnotationTag(traffic_annotation_));
}
if (mode != "manual") {
// Mode is unrecognized.
- return base::Optional<ProxyConfig>();
+ return base::Optional<ProxyConfigWithAnnotation>();
}
bool use_http_proxy;
if (setting_getter_->GetBool(SettingGetter::PROXY_USE_HTTP_PROXY,
@@ -1072,7 +1067,8 @@ ProxyConfigServiceLinux::Delegate::GetConfigFromSettings() {
&& !use_http_proxy) {
// Another master switch for some reason. If set to false, then no
// proxy. But we don't panic if the key doesn't exist.
- return config;
+ return ProxyConfigWithAnnotation(
+ config, NetworkTrafficAnnotationTag(traffic_annotation_));
}
bool same_proxy = false;
@@ -1104,30 +1100,30 @@ ProxyConfigServiceLinux::Delegate::GetConfigFromSettings() {
if (same_proxy) {
if (proxy_for_http.is_valid()) {
// Use the http proxy for all schemes.
- config->proxy_rules().type = ProxyConfig::ProxyRules::Type::PROXY_LIST;
- config->proxy_rules().single_proxies.SetSingleProxyServer(proxy_for_http);
+ config.proxy_rules().type = ProxyConfig::ProxyRules::Type::PROXY_LIST;
+ config.proxy_rules().single_proxies.SetSingleProxyServer(proxy_for_http);
}
} else if (num_proxies_specified > 0) {
if (socks_proxy.is_valid() && num_proxies_specified == 1) {
// If the only proxy specified was for SOCKS, use it for all schemes.
- config->proxy_rules().type = ProxyConfig::ProxyRules::Type::PROXY_LIST;
- config->proxy_rules().single_proxies.SetSingleProxyServer(socks_proxy);
+ config.proxy_rules().type = ProxyConfig::ProxyRules::Type::PROXY_LIST;
+ config.proxy_rules().single_proxies.SetSingleProxyServer(socks_proxy);
} else {
// Otherwise use the indicated proxies per-scheme.
- config->proxy_rules().type =
+ config.proxy_rules().type =
ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME;
- config->proxy_rules().proxies_for_http.
- SetSingleProxyServer(proxy_for_http);
- config->proxy_rules().proxies_for_https.
- SetSingleProxyServer(proxy_for_https);
- config->proxy_rules().proxies_for_ftp.SetSingleProxyServer(proxy_for_ftp);
- config->proxy_rules().fallback_proxies.SetSingleProxyServer(socks_proxy);
+ config.proxy_rules().proxies_for_http.SetSingleProxyServer(
+ proxy_for_http);
+ config.proxy_rules().proxies_for_https.SetSingleProxyServer(
+ proxy_for_https);
+ config.proxy_rules().proxies_for_ftp.SetSingleProxyServer(proxy_for_ftp);
+ config.proxy_rules().fallback_proxies.SetSingleProxyServer(socks_proxy);
}
}
- if (config->proxy_rules().empty()) {
+ if (config.proxy_rules().empty()) {
// Manual mode but we couldn't parse any rules.
- return base::Optional<ProxyConfig>();
+ return base::Optional<ProxyConfigWithAnnotation>();
}
// Check for authentication, just so we can warn.
@@ -1143,16 +1139,16 @@ ProxyConfigServiceLinux::Delegate::GetConfigFromSettings() {
// Now the bypass list.
std::vector<std::string> ignore_hosts_list;
- config->proxy_rules().bypass_rules.Clear();
+ config.proxy_rules().bypass_rules.Clear();
if (setting_getter_->GetStringList(SettingGetter::PROXY_IGNORE_HOSTS,
&ignore_hosts_list)) {
std::vector<std::string>::const_iterator it(ignore_hosts_list.begin());
for (; it != ignore_hosts_list.end(); ++it) {
if (setting_getter_->MatchHostsUsingSuffixMatching()) {
- config->proxy_rules().bypass_rules.
- AddRuleFromStringUsingSuffixMatching(*it);
+ config.proxy_rules().bypass_rules.AddRuleFromStringUsingSuffixMatching(
+ *it);
} else {
- config->proxy_rules().bypass_rules.AddRuleFromString(*it);
+ config.proxy_rules().bypass_rules.AddRuleFromString(*it);
}
}
}
@@ -1161,15 +1157,22 @@ ProxyConfigServiceLinux::Delegate::GetConfigFromSettings() {
// as a hostname rule.
// KDE allows one to reverse the bypass rules.
- config->proxy_rules().reverse_bypass =
- setting_getter_->BypassListIsReversed();
+ config.proxy_rules().reverse_bypass = setting_getter_->BypassListIsReversed();
- return config;
+ return ProxyConfigWithAnnotation(
+ config, NetworkTrafficAnnotationTag(traffic_annotation_));
+ ;
}
+ProxyConfigServiceLinux::Delegate::Delegate()
+ : env_var_getter_(base::Environment::Create()) {}
+
ProxyConfigServiceLinux::Delegate::Delegate(
- std::unique_ptr<base::Environment> env_var_getter)
- : env_var_getter_(std::move(env_var_getter)) {
+ std::unique_ptr<base::Environment> env_var_getter,
+ const NetworkTrafficAnnotationTag& traffic_annotation)
+ : env_var_getter_(std::move(env_var_getter)),
+ traffic_annotation_(
+ MutableNetworkTrafficAnnotationTag(traffic_annotation)) {
// Figure out which SettingGetterImpl to use, if any.
switch (base::nix::GetDesktopEnvironment(env_var_getter_.get())) {
case base::nix::DESKTOP_ENVIRONMENT_CINNAMON:
@@ -1200,13 +1203,19 @@ ProxyConfigServiceLinux::Delegate::Delegate(
ProxyConfigServiceLinux::Delegate::Delegate(
std::unique_ptr<base::Environment> env_var_getter,
- SettingGetter* setting_getter)
+ SettingGetter* setting_getter,
+ const NetworkTrafficAnnotationTag& traffic_annotation)
: env_var_getter_(std::move(env_var_getter)),
- setting_getter_(setting_getter) {}
+ setting_getter_(setting_getter),
+ traffic_annotation_(
+ MutableNetworkTrafficAnnotationTag(traffic_annotation)) {}
void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig(
const scoped_refptr<base::SingleThreadTaskRunner>& glib_task_runner,
- const scoped_refptr<base::SequencedTaskRunner>& main_task_runner) {
+ const scoped_refptr<base::SequencedTaskRunner>& main_task_runner,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
+ traffic_annotation_ = MutableNetworkTrafficAnnotationTag(traffic_annotation);
+
// We should be running on the default glib main loop thread right
// now. gsettings can only be accessed from this thread.
DCHECK(glib_task_runner->RunsTasksInCurrentSequence());
@@ -1231,14 +1240,13 @@ void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig(
// does so even if the proxy mode is set to auto, which would
// mislead us.
- cached_config_ = base::Optional<ProxyConfig>();
+ cached_config_ = base::Optional<ProxyConfigWithAnnotation>();
if (setting_getter_ && setting_getter_->Init(glib_task_runner)) {
cached_config_ = GetConfigFromSettings();
}
if (cached_config_) {
- cached_config_->set_source(setting_getter_->GetConfigSource());
- VLOG(1) << "Obtained proxy settings from "
- << ProxyConfigSourceToString(cached_config_->source());
+ VLOG(1) << "Obtained proxy settings from annotation hash code "
+ << cached_config_->traffic_annotation().unique_id_hash_code;
// If gsettings proxy mode is "none", meaning direct, then we take
// that to be a valid config and will not check environment
@@ -1278,7 +1286,6 @@ void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig(
// default glib main loop, but it's a tiny enough amount of work.
cached_config_ = GetConfigFromEnv();
if (cached_config_) {
- cached_config_->set_source(PROXY_CONFIG_SOURCE_ENV);
VLOG(1) << "Obtained proxy settings from environment variables";
}
}
@@ -1303,8 +1310,8 @@ void ProxyConfigServiceLinux::Delegate::RemoveObserver(Observer* observer) {
}
ProxyConfigService::ConfigAvailability
- ProxyConfigServiceLinux::Delegate::GetLatestProxyConfig(
- ProxyConfig* config) {
+ProxyConfigServiceLinux::Delegate::GetLatestProxyConfig(
+ ProxyConfigWithAnnotation* config) {
// This is called from the main TaskRunner.
DCHECK(!main_task_runner_.get() ||
main_task_runner_->RunsTasksInCurrentSequence());
@@ -1327,11 +1334,12 @@ void ProxyConfigServiceLinux::Delegate::OnCheckProxyConfigSettings() {
scoped_refptr<base::SequencedTaskRunner> required_loop =
setting_getter_->GetNotificationTaskRunner();
DCHECK(!required_loop.get() || required_loop->RunsTasksInCurrentSequence());
- base::Optional<ProxyConfig> new_config = GetConfigFromSettings();
+ base::Optional<ProxyConfigWithAnnotation> new_config =
+ GetConfigFromSettings();
// See if it is different from what we had before.
if (new_config.has_value() != reference_config_.has_value() ||
- !new_config->Equals(*reference_config_)) {
+ !new_config->value().Equals(reference_config_->value())) {
// Post a task to the main TaskRunner with the new configuration, so it can
// update |cached_config_|.
main_task_runner_->PostTask(
@@ -1346,7 +1354,7 @@ void ProxyConfigServiceLinux::Delegate::OnCheckProxyConfigSettings() {
}
void ProxyConfigServiceLinux::Delegate::SetNewProxyConfig(
- const base::Optional<ProxyConfig>& new_config) {
+ const base::Optional<ProxyConfigWithAnnotation>& new_config) {
DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
VLOG(1) << "Proxy configuration changed";
cached_config_ = new_config;
@@ -1381,21 +1389,24 @@ void ProxyConfigServiceLinux::Delegate::OnDestroy() {
}
ProxyConfigServiceLinux::ProxyConfigServiceLinux()
- : delegate_(new Delegate(base::Environment::Create())) {
-}
+ : delegate_(new Delegate()) {}
ProxyConfigServiceLinux::~ProxyConfigServiceLinux() {
delegate_->PostDestroyTask();
}
ProxyConfigServiceLinux::ProxyConfigServiceLinux(
- std::unique_ptr<base::Environment> env_var_getter)
- : delegate_(new Delegate(std::move(env_var_getter))) {}
+ std::unique_ptr<base::Environment> env_var_getter,
+ const NetworkTrafficAnnotationTag& traffic_annotation)
+ : delegate_(new Delegate(std::move(env_var_getter), traffic_annotation)) {}
ProxyConfigServiceLinux::ProxyConfigServiceLinux(
std::unique_ptr<base::Environment> env_var_getter,
- SettingGetter* setting_getter)
- : delegate_(new Delegate(std::move(env_var_getter), setting_getter)) {}
+ SettingGetter* setting_getter,
+ const NetworkTrafficAnnotationTag& traffic_annotation)
+ : delegate_(new Delegate(std::move(env_var_getter),
+ setting_getter,
+ traffic_annotation)) {}
void ProxyConfigServiceLinux::AddObserver(Observer* observer) {
delegate_->AddObserver(observer);
@@ -1406,7 +1417,8 @@ void ProxyConfigServiceLinux::RemoveObserver(Observer* observer) {
}
ProxyConfigService::ConfigAvailability
- ProxyConfigServiceLinux::GetLatestProxyConfig(ProxyConfig* config) {
+ProxyConfigServiceLinux::GetLatestProxyConfig(
+ ProxyConfigWithAnnotation* config) {
return delegate_->GetLatestProxyConfig(config);
}
diff --git a/chromium/net/proxy_resolution/proxy_config_service_linux.h b/chromium/net/proxy_resolution/proxy_config_service_linux.h
index 1debdc13f39..c853d1a4f6d 100644
--- a/chromium/net/proxy_resolution/proxy_config_service_linux.h
+++ b/chromium/net/proxy_resolution/proxy_config_service_linux.h
@@ -19,8 +19,8 @@
#include "base/optional.h"
#include "net/base/net_export.h"
#include "net/base/proxy_server.h"
-#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service.h"
+#include "net/proxy_resolution/proxy_config_with_annotation.h"
namespace base {
class SingleThreadTaskRunner;
@@ -71,9 +71,6 @@ class NET_EXPORT_PRIVATE ProxyConfigServiceLinux : public ProxyConfigService {
virtual const scoped_refptr<base::SequencedTaskRunner>&
GetNotificationTaskRunner() = 0;
- // Returns the source of proxy settings.
- virtual ProxyConfigSource GetConfigSource() = 0;
-
// These are all the values that can be fetched. We used to just use the
// corresponding paths in gconf for these, but gconf is now obsolete and
// in the future we'll be using mostly gsettings/kioslaverc so we
@@ -170,12 +167,17 @@ class NET_EXPORT_PRIVATE ProxyConfigServiceLinux : public ProxyConfigService {
class Delegate : public base::RefCountedThreadSafe<Delegate> {
public:
+ // Sets the |env_var_getter| to empty.
+ Delegate();
+
// Normal constructor.
- explicit Delegate(std::unique_ptr<base::Environment> env_var_getter);
+ explicit Delegate(std::unique_ptr<base::Environment> env_var_getter,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
// Constructor for testing.
Delegate(std::unique_ptr<base::Environment> env_var_getter,
- SettingGetter* setting_getter);
+ SettingGetter* setting_getter,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
// Synchronously obtains the proxy configuration. If gconf,
// gsettings, or kioslaverc are used, also enables notifications for
@@ -186,7 +188,8 @@ class NET_EXPORT_PRIVATE ProxyConfigServiceLinux : public ProxyConfigService {
// notifications can post tasks to it (and for assertions).
void SetUpAndFetchInitialConfig(
const scoped_refptr<base::SingleThreadTaskRunner>& glib_task_runner,
- const scoped_refptr<base::SequencedTaskRunner>& main_task_runner);
+ const scoped_refptr<base::SequencedTaskRunner>& main_task_runner,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
// Handler for setting change notifications: fetches a new proxy
// configuration from settings, and if this config is different
@@ -199,7 +202,7 @@ class NET_EXPORT_PRIVATE ProxyConfigServiceLinux : public ProxyConfigService {
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
ProxyConfigService::ConfigAvailability GetLatestProxyConfig(
- ProxyConfig* config);
+ ProxyConfigWithAnnotation* config);
// Posts a call to OnDestroy() to the glib or a file task runner,
// depending on the setting getter in use. Called from
@@ -225,7 +228,7 @@ class NET_EXPORT_PRIVATE ProxyConfigServiceLinux : public ProxyConfigService {
ProxyServer* result_server);
// Returns a proxy config based on the environment variables, or empty value
// on failure.
- base::Optional<ProxyConfig> GetConfigFromEnv();
+ base::Optional<ProxyConfigWithAnnotation> GetConfigFromEnv();
// Obtains host and port config settings and parses a proxy server
// specification from it and puts it in result. Returns true if the
@@ -234,11 +237,12 @@ class NET_EXPORT_PRIVATE ProxyConfigServiceLinux : public ProxyConfigService {
ProxyServer* result_server);
// Returns a proxy config based on the settings, or empty value
// on failure.
- base::Optional<ProxyConfig> GetConfigFromSettings();
+ base::Optional<ProxyConfigWithAnnotation> GetConfigFromSettings();
// This method is posted from the glib thread to the main TaskRunner to
// carry the new config information.
- void SetNewProxyConfig(const base::Optional<ProxyConfig>& new_config);
+ void SetNewProxyConfig(
+ const base::Optional<ProxyConfigWithAnnotation>& new_config);
// This method is run on the getter's notification thread.
void SetUpNotifications();
@@ -249,12 +253,12 @@ class NET_EXPORT_PRIVATE ProxyConfigServiceLinux : public ProxyConfigService {
// Cached proxy configuration, to be returned by
// GetLatestProxyConfig. Initially populated from the glib thread, but
// afterwards only accessed from the main TaskRunner.
- base::Optional<ProxyConfig> cached_config_;
+ base::Optional<ProxyConfigWithAnnotation> cached_config_;
// A copy kept on the glib thread of the last seen proxy config, so as
// to avoid posting a call to SetNewProxyConfig when we get a
// notification but the config has not actually changed.
- base::Optional<ProxyConfig> reference_config_;
+ base::Optional<ProxyConfigWithAnnotation> reference_config_;
// The task runner for the glib thread, aka main browser thread. This thread
// is where we run the glib main loop (see
@@ -272,6 +276,8 @@ class NET_EXPORT_PRIVATE ProxyConfigServiceLinux : public ProxyConfigService {
base::ObserverList<Observer> observers_;
+ MutableNetworkTrafficAnnotationTag traffic_annotation_;
+
DISALLOW_COPY_AND_ASSIGN(Delegate);
};
@@ -282,16 +288,21 @@ class NET_EXPORT_PRIVATE ProxyConfigServiceLinux : public ProxyConfigService {
// For testing: take alternate setting and env var getter implementations.
explicit ProxyConfigServiceLinux(
- std::unique_ptr<base::Environment> env_var_getter);
- ProxyConfigServiceLinux(std::unique_ptr<base::Environment> env_var_getter,
- SettingGetter* setting_getter);
+ std::unique_ptr<base::Environment> env_var_getter,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
+ ProxyConfigServiceLinux(
+ std::unique_ptr<base::Environment> env_var_getter,
+ SettingGetter* setting_getter,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
~ProxyConfigServiceLinux() override;
void SetupAndFetchInitialConfig(
const scoped_refptr<base::SingleThreadTaskRunner>& glib_task_runner,
- const scoped_refptr<base::SequencedTaskRunner>& io_task_runner) {
- delegate_->SetUpAndFetchInitialConfig(glib_task_runner, io_task_runner);
+ const scoped_refptr<base::SequencedTaskRunner>& main_task_runner,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
+ delegate_->SetUpAndFetchInitialConfig(glib_task_runner, main_task_runner,
+ traffic_annotation);
}
void OnCheckProxyConfigSettings() {
delegate_->OnCheckProxyConfigSettings();
@@ -302,7 +313,7 @@ class NET_EXPORT_PRIVATE ProxyConfigServiceLinux : public ProxyConfigService {
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
ProxyConfigService::ConfigAvailability GetLatestProxyConfig(
- ProxyConfig* config) override;
+ ProxyConfigWithAnnotation* config) override;
private:
scoped_refptr<Delegate> delegate_;
diff --git a/chromium/net/proxy_resolution/proxy_config_service_linux_unittest.cc b/chromium/net/proxy_resolution/proxy_config_service_linux_unittest.cc
index 7aec908af44..14d06c8acb0 100644
--- a/chromium/net/proxy_resolution/proxy_config_service_linux_unittest.cc
+++ b/chromium/net/proxy_resolution/proxy_config_service_linux_unittest.cc
@@ -26,6 +26,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service_common_unittest.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -214,10 +215,6 @@ class MockSettingGetter : public ProxyConfigServiceLinux::SettingGetter {
return task_runner_;
}
- ProxyConfigSource GetConfigSource() override {
- return PROXY_CONFIG_SOURCE_TEST;
- }
-
bool GetString(StringSetting key, std::string* result) override {
const char* value = strings_table.Get(key);
if (value) {
@@ -271,7 +268,7 @@ class MockSettingGetter : public ProxyConfigServiceLinux::SettingGetter {
// This helper class runs ProxyConfigServiceLinux::GetLatestProxyConfig() on
// the main TaskRunner and synchronously waits for the result.
-// Some code duplicated from proxy_script_fetcher_unittest.cc.
+// Some code duplicated from pac_file_fetcher_unittest.cc.
class SyncConfigGetter : public ProxyConfigService::Observer {
public:
// Takes ownership of |config_service|.
@@ -307,11 +304,12 @@ class SyncConfigGetter : public ProxyConfigService::Observer {
// default glib main loop, which is the glib thread).
void SetupAndInitialFetch() {
config_service_->SetupAndFetchInitialConfig(
- base::ThreadTaskRunnerHandle::Get(), main_thread_.task_runner());
+ base::ThreadTaskRunnerHandle::Get(), main_thread_.task_runner(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
}
// Synchronously gets the proxy config.
ProxyConfigService::ConfigAvailability SyncGetLatestProxyConfig(
- ProxyConfig* config) {
+ ProxyConfigWithAnnotation* config) {
main_thread_.task_runner()->PostTask(
FROM_HERE, base::Bind(&SyncConfigGetter::GetLatestConfigOnIOThread,
base::Unretained(this)));
@@ -344,11 +342,12 @@ class SyncConfigGetter : public ProxyConfigService::Observer {
private:
void OnProxyConfigChanged(
- const ProxyConfig& config,
+ const ProxyConfigWithAnnotation& config,
ProxyConfigService::ConfigAvailability availability) override {
// If the configuration changed to |expected_pac_url_| signal the event.
base::AutoLock lock(lock_);
- if (config.has_pac_url() && config.pac_url() == expected_pac_url_) {
+ if (config.value().has_pac_url() &&
+ config.value().pac_url() == expected_pac_url_) {
expected_pac_url_ = GURL();
matches_pac_url_event_.Signal();
}
@@ -388,7 +387,7 @@ class SyncConfigGetter : public ProxyConfigService::Observer {
// The config obtained by |main_thread_| and read back by the main
// thread.
- ProxyConfig proxy_config_;
+ ProxyConfigWithAnnotation proxy_config_;
// Return value from GetLatestProxyConfig().
ProxyConfigService::ConfigAvailability get_latest_config_result_;
@@ -753,9 +752,9 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicGSettingsTest) {
tests[i].description.c_str()));
std::unique_ptr<MockEnvironment> env(new MockEnvironment);
MockSettingGetter* setting_getter = new MockSettingGetter;
- SyncConfigGetter sync_config_getter(
- new ProxyConfigServiceLinux(std::move(env), setting_getter));
- ProxyConfig config;
+ SyncConfigGetter sync_config_getter(new ProxyConfigServiceLinux(
+ std::move(env), setting_getter, TRAFFIC_ANNOTATION_FOR_TESTS));
+ ProxyConfigWithAnnotation config;
setting_getter->values = tests[i].values;
sync_config_getter.SetupAndInitialFetch();
ProxyConfigService::ConfigAvailability availability =
@@ -763,9 +762,9 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicGSettingsTest) {
EXPECT_EQ(tests[i].availability, availability);
if (availability == ProxyConfigService::CONFIG_VALID) {
- EXPECT_EQ(tests[i].auto_detect, config.auto_detect());
- EXPECT_EQ(tests[i].pac_url, config.pac_url());
- EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules()));
+ EXPECT_EQ(tests[i].auto_detect, config.value().auto_detect());
+ EXPECT_EQ(tests[i].pac_url, config.value().pac_url());
+ EXPECT_TRUE(tests[i].proxy_rules.Matches(config.value().proxy_rules()));
}
}
}
@@ -1083,18 +1082,18 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
std::unique_ptr<MockEnvironment> env(new MockEnvironment);
env->values = tests[i].values;
MockSettingGetter* setting_getter = new MockSettingGetter;
- SyncConfigGetter sync_config_getter(
- new ProxyConfigServiceLinux(std::move(env), setting_getter));
- ProxyConfig config;
+ SyncConfigGetter sync_config_getter(new ProxyConfigServiceLinux(
+ std::move(env), setting_getter, TRAFFIC_ANNOTATION_FOR_TESTS));
+ ProxyConfigWithAnnotation config;
sync_config_getter.SetupAndInitialFetch();
ProxyConfigService::ConfigAvailability availability =
sync_config_getter.SyncGetLatestProxyConfig(&config);
EXPECT_EQ(tests[i].availability, availability);
if (availability == ProxyConfigService::CONFIG_VALID) {
- EXPECT_EQ(tests[i].auto_detect, config.auto_detect());
- EXPECT_EQ(tests[i].pac_url, config.pac_url());
- EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules()));
+ EXPECT_EQ(tests[i].auto_detect, config.value().auto_detect());
+ EXPECT_EQ(tests[i].pac_url, config.value().pac_url());
+ EXPECT_TRUE(tests[i].proxy_rules.Matches(config.value().proxy_rules()));
}
}
}
@@ -1102,17 +1101,17 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
TEST_F(ProxyConfigServiceLinuxTest, GSettingsNotification) {
std::unique_ptr<MockEnvironment> env(new MockEnvironment);
MockSettingGetter* setting_getter = new MockSettingGetter;
- ProxyConfigServiceLinux* service =
- new ProxyConfigServiceLinux(std::move(env), setting_getter);
+ ProxyConfigServiceLinux* service = new ProxyConfigServiceLinux(
+ std::move(env), setting_getter, TRAFFIC_ANNOTATION_FOR_TESTS);
SyncConfigGetter sync_config_getter(service);
- ProxyConfig config;
+ ProxyConfigWithAnnotation config;
// Start with no proxy.
setting_getter->values.mode = "none";
sync_config_getter.SetupAndInitialFetch();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
sync_config_getter.SyncGetLatestProxyConfig(&config));
- EXPECT_FALSE(config.auto_detect());
+ EXPECT_FALSE(config.value().auto_detect());
// Now set to auto-detect.
setting_getter->values.mode = "auto";
@@ -1120,7 +1119,7 @@ TEST_F(ProxyConfigServiceLinuxTest, GSettingsNotification) {
service->OnCheckProxyConfigSettings();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
sync_config_getter.SyncGetLatestProxyConfig(&config));
- EXPECT_TRUE(config.auto_detect());
+ EXPECT_TRUE(config.value().auto_detect());
}
TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
@@ -1680,9 +1679,9 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
// Force the KDE getter to be used and tell it where the test is.
env->values.DESKTOP_SESSION = "kde4";
env->values.KDEHOME = kde_home_.value().c_str();
- SyncConfigGetter sync_config_getter(
- new ProxyConfigServiceLinux(std::move(env)));
- ProxyConfig config;
+ SyncConfigGetter sync_config_getter(new ProxyConfigServiceLinux(
+ std::move(env), TRAFFIC_ANNOTATION_FOR_TESTS));
+ ProxyConfigWithAnnotation config;
// Overwrite the kioslaverc file.
base::WriteFile(kioslaverc_, tests[i].kioslaverc.c_str(),
tests[i].kioslaverc.length());
@@ -1692,9 +1691,9 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
EXPECT_EQ(tests[i].availability, availability);
if (availability == ProxyConfigService::CONFIG_VALID) {
- EXPECT_EQ(tests[i].auto_detect, config.auto_detect());
- EXPECT_EQ(tests[i].pac_url, config.pac_url());
- EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules()));
+ EXPECT_EQ(tests[i].auto_detect, config.value().auto_detect());
+ EXPECT_EQ(tests[i].pac_url, config.value().pac_url());
+ EXPECT_TRUE(tests[i].proxy_rules.Matches(config.value().proxy_rules()));
}
}
}
@@ -1728,14 +1727,14 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEHomePicker) {
std::unique_ptr<MockEnvironment> env(new MockEnvironment);
env->values.DESKTOP_SESSION = "kde4";
env->values.HOME = user_home_.value().c_str();
- SyncConfigGetter sync_config_getter(
- new ProxyConfigServiceLinux(std::move(env)));
- ProxyConfig config;
+ SyncConfigGetter sync_config_getter(new ProxyConfigServiceLinux(
+ std::move(env), TRAFFIC_ANNOTATION_FOR_TESTS));
+ ProxyConfigWithAnnotation config;
sync_config_getter.SetupAndInitialFetch();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
sync_config_getter.SyncGetLatestProxyConfig(&config));
- EXPECT_TRUE(config.auto_detect());
- EXPECT_EQ(GURL(), config.pac_url());
+ EXPECT_TRUE(config.value().auto_detect());
+ EXPECT_EQ(GURL(), config.value().pac_url());
}
// Now create .kde4 and put a kioslaverc in the config directory.
@@ -1749,14 +1748,14 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEHomePicker) {
std::unique_ptr<MockEnvironment> env(new MockEnvironment);
env->values.DESKTOP_SESSION = "kde4";
env->values.HOME = user_home_.value().c_str();
- SyncConfigGetter sync_config_getter(
- new ProxyConfigServiceLinux(std::move(env)));
- ProxyConfig config;
+ SyncConfigGetter sync_config_getter(new ProxyConfigServiceLinux(
+ std::move(env), TRAFFIC_ANNOTATION_FOR_TESTS));
+ ProxyConfigWithAnnotation config;
sync_config_getter.SetupAndInitialFetch();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
sync_config_getter.SyncGetLatestProxyConfig(&config));
- EXPECT_FALSE(config.auto_detect());
- EXPECT_EQ(slaverc4_pac_url, config.pac_url());
+ EXPECT_FALSE(config.value().auto_detect());
+ EXPECT_EQ(slaverc4_pac_url, config.value().pac_url());
}
{
@@ -1764,14 +1763,14 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEHomePicker) {
std::unique_ptr<MockEnvironment> env(new MockEnvironment);
env->values.DESKTOP_SESSION = "kde";
env->values.HOME = user_home_.value().c_str();
- SyncConfigGetter sync_config_getter(
- new ProxyConfigServiceLinux(std::move(env)));
- ProxyConfig config;
+ SyncConfigGetter sync_config_getter(new ProxyConfigServiceLinux(
+ std::move(env), TRAFFIC_ANNOTATION_FOR_TESTS));
+ ProxyConfigWithAnnotation config;
sync_config_getter.SetupAndInitialFetch();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
sync_config_getter.SyncGetLatestProxyConfig(&config));
- EXPECT_TRUE(config.auto_detect());
- EXPECT_EQ(GURL(), config.pac_url());
+ EXPECT_TRUE(config.value().auto_detect());
+ EXPECT_EQ(GURL(), config.value().pac_url());
}
{
@@ -1780,14 +1779,14 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEHomePicker) {
env->values.DESKTOP_SESSION = "kde4";
env->values.HOME = user_home_.value().c_str();
env->values.KDEHOME = kde_home_.value().c_str();
- SyncConfigGetter sync_config_getter(
- new ProxyConfigServiceLinux(std::move(env)));
- ProxyConfig config;
+ SyncConfigGetter sync_config_getter(new ProxyConfigServiceLinux(
+ std::move(env), TRAFFIC_ANNOTATION_FOR_TESTS));
+ ProxyConfigWithAnnotation config;
sync_config_getter.SetupAndInitialFetch();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
sync_config_getter.SyncGetLatestProxyConfig(&config));
- EXPECT_TRUE(config.auto_detect());
- EXPECT_EQ(GURL(), config.pac_url());
+ EXPECT_TRUE(config.value().auto_detect());
+ EXPECT_EQ(GURL(), config.value().pac_url());
}
// Finally, make the .kde4 config directory older than the .kde directory
@@ -1799,14 +1798,14 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEHomePicker) {
std::unique_ptr<MockEnvironment> env(new MockEnvironment);
env->values.DESKTOP_SESSION = "kde4";
env->values.HOME = user_home_.value().c_str();
- SyncConfigGetter sync_config_getter(
- new ProxyConfigServiceLinux(std::move(env)));
- ProxyConfig config;
+ SyncConfigGetter sync_config_getter(new ProxyConfigServiceLinux(
+ std::move(env), TRAFFIC_ANNOTATION_FOR_TESTS));
+ ProxyConfigWithAnnotation config;
sync_config_getter.SetupAndInitialFetch();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
sync_config_getter.SyncGetLatestProxyConfig(&config));
- EXPECT_TRUE(config.auto_detect());
- EXPECT_EQ(GURL(), config.pac_url());
+ EXPECT_TRUE(config.value().auto_detect());
+ EXPECT_EQ(GURL(), config.value().pac_url());
}
// For KDE 5 create ${HOME}/.config and put a kioslaverc in the directory.
@@ -1820,14 +1819,14 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEHomePicker) {
env->values.XDG_CURRENT_DESKTOP = "KDE";
env->values.KDE_SESSION_VERSION = "5";
env->values.HOME = user_home_.value().c_str();
- SyncConfigGetter sync_config_getter(
- new ProxyConfigServiceLinux(std::move(env)));
- ProxyConfig config;
+ SyncConfigGetter sync_config_getter(new ProxyConfigServiceLinux(
+ std::move(env), TRAFFIC_ANNOTATION_FOR_TESTS));
+ ProxyConfigWithAnnotation config;
sync_config_getter.SetupAndInitialFetch();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
sync_config_getter.SyncGetLatestProxyConfig(&config));
- EXPECT_FALSE(config.auto_detect());
- EXPECT_TRUE(slaverc5_rules.Matches(config.proxy_rules()));
+ EXPECT_FALSE(config.value().auto_detect());
+ EXPECT_TRUE(slaverc5_rules.Matches(config.value().proxy_rules()));
}
}
@@ -1847,14 +1846,14 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEFileChanged) {
std::unique_ptr<MockEnvironment> env(new MockEnvironment);
env->values.DESKTOP_SESSION = "kde4";
env->values.HOME = user_home_.value().c_str();
- SyncConfigGetter sync_config_getter(
- new ProxyConfigServiceLinux(std::move(env)));
- ProxyConfig config;
+ SyncConfigGetter sync_config_getter(new ProxyConfigServiceLinux(
+ std::move(env), TRAFFIC_ANNOTATION_FOR_TESTS));
+ ProxyConfigWithAnnotation config;
sync_config_getter.SetupAndInitialFetch();
EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
sync_config_getter.SyncGetLatestProxyConfig(&config));
- EXPECT_TRUE(config.has_pac_url());
- EXPECT_EQ(GURL("http://version1/wpad.dat"), config.pac_url());
+ EXPECT_TRUE(config.value().has_pac_url());
+ EXPECT_EQ(GURL("http://version1/wpad.dat"), config.value().pac_url());
//-----------------------------------------------------
diff --git a/chromium/net/proxy_resolution/proxy_config_service_mac.cc b/chromium/net/proxy_resolution/proxy_config_service_mac.cc
index f236aa473af..6a4df75f038 100644
--- a/chromium/net/proxy_resolution/proxy_config_service_mac.cc
+++ b/chromium/net/proxy_resolution/proxy_config_service_mac.cc
@@ -15,7 +15,6 @@
#include "base/strings/sys_string_conversions.h"
#include "net/base/net_errors.h"
#include "net/base/proxy_server.h"
-#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_info.h"
namespace net {
@@ -39,20 +38,20 @@ bool GetBoolFromDictionary(CFDictionaryRef dict,
return default_value;
}
-void GetCurrentProxyConfig(ProxyConfig* config) {
+void GetCurrentProxyConfig(const NetworkTrafficAnnotationTag traffic_annotation,
+ ProxyConfigWithAnnotation* config) {
base::ScopedCFTypeRef<CFDictionaryRef> config_dict(
SCDynamicStoreCopyProxies(NULL));
DCHECK(config_dict);
+ ProxyConfig proxy_config;
// auto-detect
// There appears to be no UI for this configuration option, and we're not sure
// if Apple's proxy code even takes it into account. But the constant is in
// the header file so we'll use it.
- config->set_auto_detect(
- GetBoolFromDictionary(config_dict.get(),
- kSCPropNetProxiesProxyAutoDiscoveryEnable,
- false));
+ proxy_config.set_auto_detect(GetBoolFromDictionary(
+ config_dict.get(), kSCPropNetProxiesProxyAutoDiscoveryEnable, false));
// PAC file
@@ -62,7 +61,7 @@ void GetCurrentProxyConfig(ProxyConfig* config) {
CFStringRef pac_url_ref = base::mac::GetValueFromDictionary<CFStringRef>(
config_dict.get(), kSCPropNetProxiesProxyAutoConfigURLString);
if (pac_url_ref)
- config->set_pac_url(GURL(base::SysCFStringRefToUTF8(pac_url_ref)));
+ proxy_config.set_pac_url(GURL(base::SysCFStringRefToUTF8(pac_url_ref)));
}
// proxies (for now ftp, http, https, and SOCKS)
@@ -76,9 +75,10 @@ void GetCurrentProxyConfig(ProxyConfig* config) {
kSCPropNetProxiesFTPProxy,
kSCPropNetProxiesFTPPort);
if (proxy_server.is_valid()) {
- config->proxy_rules().type =
+ proxy_config.proxy_rules().type =
ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME;
- config->proxy_rules().proxies_for_ftp.SetSingleProxyServer(proxy_server);
+ proxy_config.proxy_rules().proxies_for_ftp.SetSingleProxyServer(
+ proxy_server);
}
}
if (GetBoolFromDictionary(config_dict.get(),
@@ -90,9 +90,10 @@ void GetCurrentProxyConfig(ProxyConfig* config) {
kSCPropNetProxiesHTTPProxy,
kSCPropNetProxiesHTTPPort);
if (proxy_server.is_valid()) {
- config->proxy_rules().type =
+ proxy_config.proxy_rules().type =
ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME;
- config->proxy_rules().proxies_for_http.SetSingleProxyServer(proxy_server);
+ proxy_config.proxy_rules().proxies_for_http.SetSingleProxyServer(
+ proxy_server);
}
}
if (GetBoolFromDictionary(config_dict.get(),
@@ -104,10 +105,10 @@ void GetCurrentProxyConfig(ProxyConfig* config) {
kSCPropNetProxiesHTTPSProxy,
kSCPropNetProxiesHTTPSPort);
if (proxy_server.is_valid()) {
- config->proxy_rules().type =
+ proxy_config.proxy_rules().type =
ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME;
- config->proxy_rules().proxies_for_https.
- SetSingleProxyServer(proxy_server);
+ proxy_config.proxy_rules().proxies_for_https.SetSingleProxyServer(
+ proxy_server);
}
}
if (GetBoolFromDictionary(config_dict.get(),
@@ -119,9 +120,10 @@ void GetCurrentProxyConfig(ProxyConfig* config) {
kSCPropNetProxiesSOCKSProxy,
kSCPropNetProxiesSOCKSPort);
if (proxy_server.is_valid()) {
- config->proxy_rules().type =
+ proxy_config.proxy_rules().type =
ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME;
- config->proxy_rules().fallback_proxies.SetSingleProxyServer(proxy_server);
+ proxy_config.proxy_rules().fallback_proxies.SetSingleProxyServer(
+ proxy_server);
}
}
@@ -140,7 +142,7 @@ void GetCurrentProxyConfig(ProxyConfig* config) {
" to be a CFStringRef but it was not";
} else {
- config->proxy_rules().bypass_rules.AddRuleFromString(
+ proxy_config.proxy_rules().bypass_rules.AddRuleFromString(
base::SysCFStringRefToUTF8(bypass_item_ref));
}
}
@@ -151,11 +153,10 @@ void GetCurrentProxyConfig(ProxyConfig* config) {
if (GetBoolFromDictionary(config_dict.get(),
kSCPropNetProxiesExcludeSimpleHostnames,
false)) {
- config->proxy_rules().bypass_rules.AddRuleToBypassLocal();
+ proxy_config.proxy_rules().bypass_rules.AddRuleToBypassLocal();
}
- // Source
- config->set_source(PROXY_CONFIG_SOURCE_SYSTEM);
+ *config = ProxyConfigWithAnnotation(proxy_config, traffic_annotation);
}
} // namespace
@@ -175,7 +176,7 @@ class ProxyConfigServiceMac::Helper
parent_ = NULL;
}
- void OnProxyConfigChanged(const ProxyConfig& new_config) {
+ void OnProxyConfigChanged(const ProxyConfigWithAnnotation& new_config) {
if (parent_)
parent_->OnProxyConfigChanged(new_config);
}
@@ -198,11 +199,13 @@ void ProxyConfigServiceMac::Forwarder::OnNetworkConfigChange(
}
ProxyConfigServiceMac::ProxyConfigServiceMac(
- const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner)
+ const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner,
+ const NetworkTrafficAnnotationTag& traffic_annotation)
: forwarder_(this),
has_fetched_config_(false),
helper_(new Helper(this)),
- sequenced_task_runner_(sequenced_task_runner) {
+ sequenced_task_runner_(sequenced_task_runner),
+ traffic_annotation_(traffic_annotation) {
DCHECK(sequenced_task_runner_.get());
config_watcher_.reset(new NetworkConfigWatcherMac(&forwarder_));
}
@@ -226,12 +229,12 @@ void ProxyConfigServiceMac::RemoveObserver(Observer* observer) {
}
ProxyConfigService::ConfigAvailability
-ProxyConfigServiceMac::GetLatestProxyConfig(ProxyConfig* config) {
+ProxyConfigServiceMac::GetLatestProxyConfig(ProxyConfigWithAnnotation* config) {
DCHECK(sequenced_task_runner_->RunsTasksInCurrentSequence());
// Lazy-initialize by fetching the proxy setting from this thread.
if (!has_fetched_config_) {
- GetCurrentProxyConfig(&last_config_fetched_);
+ GetCurrentProxyConfig(traffic_annotation_, &last_config_fetched_);
has_fetched_config_ = true;
}
@@ -259,8 +262,8 @@ void ProxyConfigServiceMac::OnNetworkConfigChange(CFArrayRef changed_keys) {
// Called on notifier thread.
// Fetch the new system proxy configuration.
- ProxyConfig new_config;
- GetCurrentProxyConfig(&new_config);
+ ProxyConfigWithAnnotation new_config;
+ GetCurrentProxyConfig(traffic_annotation_, &new_config);
// Call OnProxyConfigChanged() on the TakeRunner to notify our observers.
sequenced_task_runner_->PostTask(
@@ -269,7 +272,7 @@ void ProxyConfigServiceMac::OnNetworkConfigChange(CFArrayRef changed_keys) {
}
void ProxyConfigServiceMac::OnProxyConfigChanged(
- const ProxyConfig& new_config) {
+ const ProxyConfigWithAnnotation& new_config) {
DCHECK(sequenced_task_runner_->RunsTasksInCurrentSequence());
// Keep track of the last value we have seen.
diff --git a/chromium/net/proxy_resolution/proxy_config_service_mac.h b/chromium/net/proxy_resolution/proxy_config_service_mac.h
index 6b434f56fd6..1281e3b4a21 100644
--- a/chromium/net/proxy_resolution/proxy_config_service_mac.h
+++ b/chromium/net/proxy_resolution/proxy_config_service_mac.h
@@ -12,8 +12,8 @@
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "net/base/network_config_watcher_mac.h"
-#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service.h"
+#include "net/proxy_resolution/proxy_config_with_annotation.h"
namespace base {
class SequencedTaskRunner;
@@ -27,14 +27,16 @@ class ProxyConfigServiceMac : public ProxyConfigService {
// This instance is expected to be operated and deleted on
// |sequenced_task_runner| (however it may be constructed elsewhere).
explicit ProxyConfigServiceMac(
- const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner);
+ const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
~ProxyConfigServiceMac() override;
public:
// ProxyConfigService implementation:
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
- ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) override;
+ ConfigAvailability GetLatestProxyConfig(
+ ProxyConfigWithAnnotation* config) override;
private:
class Helper;
@@ -61,7 +63,7 @@ class ProxyConfigServiceMac : public ProxyConfigService {
void OnNetworkConfigChange(CFArrayRef changed_keys);
// Called when the proxy configuration has changed, to notify the observers.
- void OnProxyConfigChanged(const ProxyConfig& new_config);
+ void OnProxyConfigChanged(const ProxyConfigWithAnnotation& new_config);
Forwarder forwarder_;
std::unique_ptr<const NetworkConfigWatcherMac> config_watcher_;
@@ -70,13 +72,15 @@ class ProxyConfigServiceMac : public ProxyConfigService {
// Holds the last system proxy settings that we fetched.
bool has_fetched_config_;
- ProxyConfig last_config_fetched_;
+ ProxyConfigWithAnnotation last_config_fetched_;
scoped_refptr<Helper> helper_;
// The task runner that |this| will be operated on.
const scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
+ const NetworkTrafficAnnotationTag traffic_annotation_;
+
DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceMac);
};
diff --git a/chromium/net/proxy_resolution/proxy_config_service_win.cc b/chromium/net/proxy_resolution/proxy_config_service_win.cc
index b298a13be1e..b14abc7a31f 100644
--- a/chromium/net/proxy_resolution/proxy_config_service_win.cc
+++ b/chromium/net/proxy_resolution/proxy_config_service_win.cc
@@ -17,7 +17,6 @@
#include "base/win/registry.h"
#include "base/win/scoped_handle.h"
#include "net/base/net_errors.h"
-#include "net/proxy_resolution/proxy_config.h"
namespace net {
@@ -36,11 +35,11 @@ void FreeIEConfig(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* ie_config) {
} // namespace
-ProxyConfigServiceWin::ProxyConfigServiceWin()
- : PollingProxyConfigService(
- base::TimeDelta::FromSeconds(kPollIntervalSec),
- &ProxyConfigServiceWin::GetCurrentProxyConfig) {
-}
+ProxyConfigServiceWin::ProxyConfigServiceWin(
+ const NetworkTrafficAnnotationTag& traffic_annotation)
+ : PollingProxyConfigService(base::TimeDelta::FromSeconds(kPollIntervalSec),
+ &ProxyConfigServiceWin::GetCurrentProxyConfig,
+ traffic_annotation) {}
ProxyConfigServiceWin::~ProxyConfigServiceWin() {
// The registry functions below will end up going to disk. TODO: Do this on
@@ -128,17 +127,20 @@ void ProxyConfigServiceWin::OnObjectSignaled(base::win::RegKey* key) {
}
// static
-void ProxyConfigServiceWin::GetCurrentProxyConfig(ProxyConfig* config) {
+void ProxyConfigServiceWin::GetCurrentProxyConfig(
+ const NetworkTrafficAnnotationTag traffic_annotation,
+ ProxyConfigWithAnnotation* config) {
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_config = {0};
if (!WinHttpGetIEProxyConfigForCurrentUser(&ie_config)) {
LOG(ERROR) << "WinHttpGetIEProxyConfigForCurrentUser failed: " <<
GetLastError();
- *config = ProxyConfig::CreateDirect();
- config->set_source(PROXY_CONFIG_SOURCE_SYSTEM_FAILED);
+ *config = ProxyConfigWithAnnotation::CreateDirect();
return;
}
- SetFromIEConfig(config, ie_config);
+ ProxyConfig proxy_config;
+ SetFromIEConfig(&proxy_config, ie_config);
FreeIEConfig(&ie_config);
+ *config = ProxyConfigWithAnnotation(proxy_config, traffic_annotation);
}
// static
@@ -164,7 +166,6 @@ void ProxyConfigServiceWin::SetFromIEConfig(
}
if (ie_config.lpszAutoConfigUrl)
config->set_pac_url(GURL(ie_config.lpszAutoConfigUrl));
- config->set_source(PROXY_CONFIG_SOURCE_SYSTEM);
}
} // namespace net
diff --git a/chromium/net/proxy_resolution/proxy_config_service_win.h b/chromium/net/proxy_resolution/proxy_config_service_win.h
index 9ee40c5a1a7..cd050a6f778 100644
--- a/chromium/net/proxy_resolution/proxy_config_service_win.h
+++ b/chromium/net/proxy_resolution/proxy_config_service_win.h
@@ -15,6 +15,7 @@
#include "base/gtest_prod_util.h"
#include "net/base/net_export.h"
#include "net/proxy_resolution/polling_proxy_config_service.h"
+#include "net/proxy_resolution/proxy_config_with_annotation.h"
namespace base {
namespace win {
@@ -49,7 +50,7 @@ namespace net {
class NET_EXPORT_PRIVATE ProxyConfigServiceWin
: public PollingProxyConfigService {
public:
- ProxyConfigServiceWin();
+ ProxyConfigServiceWin(const NetworkTrafficAnnotationTag& traffic_annotation);
~ProxyConfigServiceWin() override;
// Overrides a function from PollingProxyConfigService.
@@ -68,7 +69,9 @@ class NET_EXPORT_PRIVATE ProxyConfigServiceWin
// This is called whenever one of the registry keys we are watching change.
void OnObjectSignaled(base::win::RegKey* key);
- static void GetCurrentProxyConfig(ProxyConfig* config);
+ static void GetCurrentProxyConfig(
+ const NetworkTrafficAnnotationTag traffic_annotation,
+ ProxyConfigWithAnnotation* config);
// Set |config| using the proxy configuration values of |ie_config|.
static void SetFromIEConfig(
diff --git a/chromium/net/proxy_resolution/proxy_config_service_win_unittest.cc b/chromium/net/proxy_resolution/proxy_config_service_win_unittest.cc
index 8ea7eb3abe5..fec338e1dc1 100644
--- a/chromium/net/proxy_resolution/proxy_config_service_win_unittest.cc
+++ b/chromium/net/proxy_resolution/proxy_config_service_win_unittest.cc
@@ -208,7 +208,6 @@ TEST(ProxyConfigServiceWinTest, SetFromIEConfig) {
EXPECT_EQ(tests[i].auto_detect, config.auto_detect());
EXPECT_EQ(tests[i].pac_url, config.pac_url());
EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules()));
- EXPECT_EQ(PROXY_CONFIG_SOURCE_SYSTEM, config.source());
}
}
diff --git a/chromium/net/proxy_resolution/proxy_config_source.cc b/chromium/net/proxy_resolution/proxy_config_source.cc
deleted file mode 100644
index 304719ae0dd..00000000000
--- a/chromium/net/proxy_resolution/proxy_config_source.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/proxy_resolution/proxy_config_source.h"
-
-#include "base/logging.h"
-
-namespace net {
-
-namespace {
-
-const char* const kSourceNames[] = {
- "UNKNOWN",
- "SYSTEM",
- "SYSTEM FAILED",
- "GSETTINGS",
- "KDE",
- "ENV",
- "CUSTOM",
- "TEST"
-};
-static_assert(arraysize(kSourceNames) == NUM_PROXY_CONFIG_SOURCES,
- "kSourceNames has incorrect size");
-
-} // namespace
-
-const char* ProxyConfigSourceToString(ProxyConfigSource source) {
- DCHECK_GT(NUM_PROXY_CONFIG_SOURCES, source);
- return kSourceNames[source];
-}
-
-} // namespace net
diff --git a/chromium/net/proxy_resolution/proxy_config_source.h b/chromium/net/proxy_resolution/proxy_config_source.h
deleted file mode 100644
index ff0fcfbd5f9..00000000000
--- a/chromium/net/proxy_resolution/proxy_config_source.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_PROXY_RESOLUTION_PROXY_CONFIG_SOURCE_H_
-#define NET_PROXY_RESOLUTION_PROXY_CONFIG_SOURCE_H_
-
-namespace net {
-
-// Source of the configuration settings encapsulated in a ProxyConfig object.
-
-// The source information is used for determining how credentials are used and
-// for logging. When adding new values, remember to add a string to
-// kSourceNames[] in proxy_config_source.cc.
-enum ProxyConfigSource {
- PROXY_CONFIG_SOURCE_UNKNOWN, // The source hasn't been set.
- PROXY_CONFIG_SOURCE_SYSTEM, // System settings (Win/Mac).
- PROXY_CONFIG_SOURCE_SYSTEM_FAILED, // Default settings after failure to
- // determine system settings.
- PROXY_CONFIG_SOURCE_GSETTINGS, // GSettings (Linux).
- PROXY_CONFIG_SOURCE_KDE, // KDE (Linux).
- PROXY_CONFIG_SOURCE_ENV, // Environment variables.
- PROXY_CONFIG_SOURCE_CUSTOM, // Custom settings local to the
- // application (command line,
- // extensions, application
- // specific preferences, etc.)
- PROXY_CONFIG_SOURCE_TEST, // Test settings.
- NUM_PROXY_CONFIG_SOURCES
-};
-
-// Returns a textual representation of the source.
-const char* ProxyConfigSourceToString(ProxyConfigSource source);
-
-} // namespace net
-
-#endif // NET_PROXY_RESOLUTION_PROXY_CONFIG_SOURCE_H_
diff --git a/chromium/net/proxy_resolution/proxy_config_with_annotation.cc b/chromium/net/proxy_resolution/proxy_config_with_annotation.cc
new file mode 100644
index 00000000000..b4541ffc508
--- /dev/null
+++ b/chromium/net/proxy_resolution/proxy_config_with_annotation.cc
@@ -0,0 +1,51 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/proxy_resolution/proxy_config_with_annotation.h"
+
+namespace net {
+
+namespace {
+
+constexpr NetworkTrafficAnnotationTag kDirectProxyTrafficAnnotation =
+ DefineNetworkTrafficAnnotation("proxy_config_direct", R"(
+ semantics {
+ sender: "Proxy Config"
+ description:
+ "Direct connections are being used instead of a proxy. This is a place "
+ "holder annotation that would include details about where the "
+ "configuration, which can trigger fetching a PAC file, came from."
+ trigger:
+ "Connecting directly to destination sites instead of using a proxy is "
+ "the default behavior."
+ data:
+ "None."
+ destination: WEBSITE
+ }
+ policy {
+ cookies_allowed: NO
+ setting:
+ "This isn't a real network request. A proxy can be selected in "
+ "settings."
+ policy_exception_justification:
+ "Using either of 'ProxyMode', 'ProxyServer', or 'ProxyPacUrl' policies "
+ "can set Chrome to use a specific proxy settings and avoid directly "
+ "connecting to the websites."
+ })");
+
+} // namespace
+
+ProxyConfigWithAnnotation::ProxyConfigWithAnnotation()
+ : value_(ProxyConfig::CreateDirect()),
+ traffic_annotation_(
+ MutableNetworkTrafficAnnotationTag(kDirectProxyTrafficAnnotation)) {}
+
+ProxyConfigWithAnnotation::ProxyConfigWithAnnotation(
+ const ProxyConfig& proxy_config,
+ const NetworkTrafficAnnotationTag& traffic_annotation)
+ : value_(proxy_config),
+ traffic_annotation_(
+ MutableNetworkTrafficAnnotationTag(traffic_annotation)) {}
+
+} // namespace net \ No newline at end of file
diff --git a/chromium/net/proxy_resolution/proxy_config_with_annotation.h b/chromium/net/proxy_resolution/proxy_config_with_annotation.h
new file mode 100644
index 00000000000..019f2fd1aa7
--- /dev/null
+++ b/chromium/net/proxy_resolution/proxy_config_with_annotation.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_PROXY_RESOLUTION_PROXY_CONFIG_WITH_ANNOTATION_H_
+#define NET_PROXY_RESOLUTION_PROXY_CONFIG_WITH_ANNOTATION_H_
+
+#include "net/base/net_export.h"
+#include "net/proxy_resolution/proxy_config.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+
+namespace net {
+
+// ProxyConfigWithAnnotation encapsulates a ProxyConfig with the network traffic
+// annotation that specifies the source of proxy config.
+class NET_EXPORT ProxyConfigWithAnnotation {
+ public:
+ // Creates a Direct proxy config.
+ ProxyConfigWithAnnotation();
+
+ ProxyConfigWithAnnotation(
+ const ProxyConfig& proxy_config,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
+
+ static ProxyConfigWithAnnotation CreateDirect() {
+ return ProxyConfigWithAnnotation();
+ }
+
+ NetworkTrafficAnnotationTag traffic_annotation() const {
+ return NetworkTrafficAnnotationTag(traffic_annotation_);
+ }
+
+ const ProxyConfig& value() const { return value_; }
+
+ private:
+ ProxyConfig value_;
+ MutableNetworkTrafficAnnotationTag traffic_annotation_;
+};
+
+} // namespace net
+
+#endif // NET_PROXY_RESOLUTION_PROXY_CONFIG_WITH_ANNOTATION_H_
diff --git a/chromium/net/proxy_resolution/proxy_info.cc b/chromium/net/proxy_resolution/proxy_info.cc
index dbcc8c45a85..cb0bf4eb0f6 100644
--- a/chromium/net/proxy_resolution/proxy_info.cc
+++ b/chromium/net/proxy_resolution/proxy_info.cc
@@ -8,10 +8,7 @@
namespace net {
-ProxyInfo::ProxyInfo()
- : config_source_(PROXY_CONFIG_SOURCE_UNKNOWN),
- did_bypass_proxy_(false),
- did_use_pac_script_(false) {}
+ProxyInfo::ProxyInfo() : did_bypass_proxy_(false), did_use_pac_script_(false) {}
ProxyInfo::ProxyInfo(const ProxyInfo& other) = default;
@@ -22,7 +19,7 @@ void ProxyInfo::Use(const ProxyInfo& other) {
proxy_resolve_end_time_ = other.proxy_resolve_end_time_;
proxy_list_ = other.proxy_list_;
proxy_retry_info_ = other.proxy_retry_info_;
- config_source_ = other.config_source_;
+ traffic_annotation_ = other.traffic_annotation_;
did_bypass_proxy_ = other.did_bypass_proxy_;
did_use_pac_script_ = other.did_use_pac_script_;
}
@@ -88,15 +85,9 @@ void ProxyInfo::Reset() {
proxy_list_.Clear();
alternative_proxy_ = net::ProxyServer();
proxy_retry_info_.clear();
- config_source_ = PROXY_CONFIG_SOURCE_UNKNOWN;
+ traffic_annotation_.reset();
did_bypass_proxy_ = false;
did_use_pac_script_ = false;
}
-const NetworkTrafficAnnotationTag ProxyInfo::traffic_annotation() const {
- // TODO(crbug.com/656607): Get appropriate annotation from the origin of
- // config_source_.
- return NO_TRAFFIC_ANNOTATION_BUG_656607;
-}
-
} // namespace net
diff --git a/chromium/net/proxy_resolution/proxy_info.h b/chromium/net/proxy_resolution/proxy_info.h
index bf65e4a3683..e3ea8da6a07 100644
--- a/chromium/net/proxy_resolution/proxy_info.h
+++ b/chromium/net/proxy_resolution/proxy_info.h
@@ -131,12 +131,6 @@ class NET_EXPORT ProxyInfo {
// to call this function.
const ProxyServer& proxy_server() const { return proxy_list_.Get(); }
- // Returns the source for configuration settings used for proxy resolution.
- ProxyConfigSource config_source() const { return config_source_; }
-
- // Returns traffic annotation tag based on current config source.
- const NetworkTrafficAnnotationTag traffic_annotation() const;
-
// See description in ProxyList::ToPacString().
std::string ToPacString() const;
@@ -170,6 +164,15 @@ class NET_EXPORT ProxyInfo {
return proxy_resolve_end_time_;
}
+ void set_traffic_annotation(
+ const MutableNetworkTrafficAnnotationTag& traffic_annotation) {
+ traffic_annotation_ = traffic_annotation;
+ }
+
+ MutableNetworkTrafficAnnotationTag traffic_annotation() const {
+ return traffic_annotation_;
+ }
+
private:
friend class ProxyResolutionService;
FRIEND_TEST_ALL_PREFIXES(ProxyInfoTest, UseVsOverrideProxyList);
@@ -192,8 +195,8 @@ class NET_EXPORT ProxyInfo {
// List of proxies that have been tried already.
ProxyRetryInfoMap proxy_retry_info_;
- // The source of the proxy settings used,
- ProxyConfigSource config_source_;
+ // The traffic annotation of the used proxy config.
+ MutableNetworkTrafficAnnotationTag traffic_annotation_;
// Whether the proxy result represent a proxy bypass.
bool did_bypass_proxy_;
diff --git a/chromium/net/proxy_resolution/proxy_list.cc b/chromium/net/proxy_resolution/proxy_list.cc
index 6a0e1a8f27b..25fdf6dbfaa 100644
--- a/chromium/net/proxy_resolution/proxy_list.cc
+++ b/chromium/net/proxy_resolution/proxy_list.cc
@@ -29,8 +29,8 @@ void ProxyList::Set(const std::string& proxy_uri_list) {
proxies_.clear();
base::StringTokenizer str_tok(proxy_uri_list, ";");
while (str_tok.GetNext()) {
- ProxyServer uri = ProxyServer::FromURI(
- str_tok.token_begin(), str_tok.token_end(), ProxyServer::SCHEME_HTTP);
+ ProxyServer uri =
+ ProxyServer::FromURI(str_tok.token_piece(), ProxyServer::SCHEME_HTTP);
// Silently discard malformed inputs.
if (uri.is_valid())
proxies_.push_back(uri);
@@ -120,8 +120,7 @@ void ProxyList::SetFromPacString(const std::string& pac_string) {
base::StringTokenizer entry_tok(pac_string, ";");
proxies_.clear();
while (entry_tok.GetNext()) {
- ProxyServer uri = ProxyServer::FromPacString(
- entry_tok.token_begin(), entry_tok.token_end());
+ ProxyServer uri = ProxyServer::FromPacString(entry_tok.token_piece());
// Silently discard malformed inputs.
if (uri.is_valid())
proxies_.push_back(uri);
diff --git a/chromium/net/proxy_resolution/proxy_list.h b/chromium/net/proxy_resolution/proxy_list.h
index b01003b8124..e65057d2699 100644
--- a/chromium/net/proxy_resolution/proxy_list.h
+++ b/chromium/net/proxy_resolution/proxy_list.h
@@ -70,7 +70,7 @@ class NET_EXPORT_PRIVATE ProxyList {
// Returns all proxy servers in the list.
const std::vector<ProxyServer>& GetAll() const;
- // Sets the list by parsing the pac result |pac_string|.
+ // Sets the list by parsing the PAC result |pac_string|.
// Some examples for |pac_string|:
// "DIRECT"
// "PROXY foopy1"
diff --git a/chromium/net/proxy_resolution/proxy_service.cc b/chromium/net/proxy_resolution/proxy_resolution_service.cc
index 6b633063ec2..b09e8d1bc9f 100644
--- a/chromium/net/proxy_resolution/proxy_service.cc
+++ b/chromium/net/proxy_resolution/proxy_resolution_service.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include <algorithm>
#include <cmath>
@@ -24,6 +24,7 @@
#include "net/base/net_errors.h"
#include "net/base/proxy_delegate.h"
#include "net/base/url_util.h"
+#include "net/log/net_log.h"
#include "net/log/net_log_capture_mode.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_with_source.h"
@@ -59,6 +60,36 @@ namespace net {
namespace {
+#if defined(OS_WIN) || defined(OS_IOS) || defined(OS_MACOSX) || \
+ (defined(OS_LINUX) && !defined(OS_CHROMEOS))
+constexpr net::NetworkTrafficAnnotationTag kSystemProxyConfigTrafficAnnotation =
+ net::DefineNetworkTrafficAnnotation("proxy_config_system", R"(
+ semantics {
+ sender: "Proxy Config"
+ description:
+ "Establishing a connection through a proxy server using system proxy "
+ "settings."
+ trigger:
+ "Whenever a network request is made when the system proxy settings "
+ "are used, and they indicate to use a proxy server."
+ data:
+ "Proxy configuration."
+ destination: OTHER
+ destination_other:
+ "The proxy server specified in the configuration."
+ }
+ policy {
+ cookies_allowed: NO
+ setting:
+ "User cannot override system proxy settings, but can change them "
+ "through 'Advanced/System/Open proxy settings'."
+ policy_exception_justification:
+ "Using either of 'ProxyMode', 'ProxyServer', or 'ProxyPacUrl' "
+ "policies can set Chrome to use a specific proxy settings and avoid "
+ "system proxy."
+ })");
+#endif
+
const size_t kDefaultNumPacThreads = 4;
// When the IP address changes we don't immediately re-run proxy auto-config.
@@ -171,9 +202,9 @@ class ProxyConfigServiceDirect : public ProxyConfigService {
// ProxyConfigService implementation:
void AddObserver(Observer* observer) override {}
void RemoveObserver(Observer* observer) override {}
- ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) override {
- *config = ProxyConfig::CreateDirect();
- config->set_source(PROXY_CONFIG_SOURCE_UNKNOWN);
+ ConfigAvailability GetLatestProxyConfig(
+ ProxyConfigWithAnnotation* config) override {
+ *config = ProxyConfigWithAnnotation::CreateDirect();
return CONFIG_VALID;
}
};
@@ -249,11 +280,10 @@ class ProxyResolverFactoryForNullResolver : public ProxyResolverFactory {
ProxyResolverFactoryForNullResolver() : ProxyResolverFactory(false) {}
// ProxyResolverFactory overrides.
- int CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
- std::unique_ptr<ProxyResolver>* resolver,
- const net::CompletionCallback& callback,
- std::unique_ptr<Request>* request) override {
+ int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
+ std::unique_ptr<ProxyResolver>* resolver,
+ const net::CompletionCallback& callback,
+ std::unique_ptr<Request>* request) override {
resolver->reset(new ProxyResolverNull());
return OK;
}
@@ -268,11 +298,10 @@ class ProxyResolverFactoryForPacResult : public ProxyResolverFactory {
: ProxyResolverFactory(false), pac_string_(pac_string) {}
// ProxyResolverFactory override.
- int CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
- std::unique_ptr<ProxyResolver>* resolver,
- const net::CompletionCallback& callback,
- std::unique_ptr<Request>* request) override {
+ int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
+ std::unique_ptr<ProxyResolver>* resolver,
+ const net::CompletionCallback& callback,
+ std::unique_ptr<Request>* request) override {
resolver->reset(new ProxyResolverFromPacString(pac_string_));
return OK;
}
@@ -285,15 +314,15 @@ class ProxyResolverFactoryForPacResult : public ProxyResolverFactory {
// Returns NetLog parameters describing a proxy configuration change.
std::unique_ptr<base::Value> NetLogProxyConfigChangedCallback(
- const base::Optional<ProxyConfig>* old_config,
- const ProxyConfig* new_config,
+ const base::Optional<ProxyConfigWithAnnotation>* old_config,
+ const ProxyConfigWithAnnotation* new_config,
NetLogCaptureMode /* capture_mode */) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
// The "old_config" is optional -- the first notification will not have
// any "previous" configuration.
if (old_config->has_value())
- dict->Set("old_config", (*old_config)->ToValue());
- dict->Set("new_config", new_config->ToValue());
+ dict->Set("old_config", (*old_config)->value().ToValue());
+ dict->Set("new_config", new_config->value().ToValue());
return std::move(dict);
}
@@ -328,7 +357,8 @@ class UnsetProxyConfigService : public ProxyConfigService {
void AddObserver(Observer* observer) override {}
void RemoveObserver(Observer* observer) override {}
- ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) override {
+ ConfigAvailability GetLatestProxyConfig(
+ ProxyConfigWithAnnotation* config) override {
return CONFIG_UNSET;
}
};
@@ -360,7 +390,7 @@ GURL SanitizeUrl(const GURL& url,
// ProxyResolutionService::InitProxyResolver ----------------------------------
// This glues together two asynchronous steps:
-// (1) ProxyScriptDecider -- try to fetch/validate a sequence of PAC scripts
+// (1) PacFileDecider -- try to fetch/validate a sequence of PAC scripts
// to figure out what we should configure against.
// (2) Feed the fetched PAC script into the ProxyResolver.
//
@@ -378,7 +408,7 @@ class ProxyResolutionService::InitProxyResolver {
quick_check_enabled_(true) {}
~InitProxyResolver() {
- // Note that the destruction of ProxyScriptDecider will automatically cancel
+ // Note that the destruction of PacFileDecider will automatically cancel
// any outstanding work.
}
@@ -387,37 +417,37 @@ class ProxyResolutionService::InitProxyResolver {
// returned via |proxy_resolver| if the final result is OK.
int Start(std::unique_ptr<ProxyResolver>* proxy_resolver,
ProxyResolverFactory* proxy_resolver_factory,
- ProxyScriptFetcher* proxy_script_fetcher,
- DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher,
+ PacFileFetcher* pac_file_fetcher,
+ DhcpPacFileFetcher* dhcp_pac_file_fetcher,
NetLog* net_log,
- const ProxyConfig& config,
+ const ProxyConfigWithAnnotation& config,
TimeDelta wait_delay,
const CompletionCallback& callback) {
DCHECK_EQ(STATE_NONE, next_state_);
proxy_resolver_ = proxy_resolver;
proxy_resolver_factory_ = proxy_resolver_factory;
- decider_.reset(new ProxyScriptDecider(
- proxy_script_fetcher, dhcp_proxy_script_fetcher, net_log));
+ decider_.reset(
+ new PacFileDecider(pac_file_fetcher, dhcp_pac_file_fetcher, net_log));
decider_->set_quick_check_enabled(quick_check_enabled_);
config_ = config;
wait_delay_ = wait_delay;
callback_ = callback;
- next_state_ = STATE_DECIDE_PROXY_SCRIPT;
+ next_state_ = STATE_DECIDE_PAC_FILE;
return DoLoop(OK);
}
- // Similar to Start(), however it skips the ProxyScriptDecider stage. Instead
+ // Similar to Start(), however it skips the PacFileDecider stage. Instead
// |effective_config|, |decider_result| and |script_data| will be used as the
// inputs for initializing the ProxyResolver. A ProxyResolver instance will
// be created using |proxy_resolver_factory| and returned via
// |proxy_resolver| if the final result is OK.
int StartSkipDecider(std::unique_ptr<ProxyResolver>* proxy_resolver,
ProxyResolverFactory* proxy_resolver_factory,
- const ProxyConfig& effective_config,
+ const ProxyConfigWithAnnotation& effective_config,
int decider_result,
- ProxyResolverScriptData* script_data,
+ PacFileData* script_data,
const CompletionCallback& callback) {
DCHECK_EQ(STATE_NONE, next_state_);
proxy_resolver_ = proxy_resolver;
@@ -434,25 +464,25 @@ class ProxyResolutionService::InitProxyResolver {
return DoLoop(OK);
}
- // Returns the proxy configuration that was selected by ProxyScriptDecider.
+ // Returns the proxy configuration that was selected by PacFileDecider.
// Should only be called upon completion of the initialization.
- const ProxyConfig& effective_config() const {
+ const ProxyConfigWithAnnotation& effective_config() const {
DCHECK_EQ(STATE_NONE, next_state_);
return effective_config_;
}
- // Returns the PAC script data that was selected by ProxyScriptDecider.
+ // Returns the PAC script data that was selected by PacFileDecider.
// Should only be called upon completion of the initialization.
- const scoped_refptr<ProxyResolverScriptData>& script_data() {
+ const scoped_refptr<PacFileData>& script_data() {
DCHECK_EQ(STATE_NONE, next_state_);
return script_data_;
}
LoadState GetLoadState() const {
- if (next_state_ == STATE_DECIDE_PROXY_SCRIPT_COMPLETE) {
+ if (next_state_ == STATE_DECIDE_PAC_FILE_COMPLETE) {
// In addition to downloading, this state may also include the stall time
// after network change events (kDelayAfterNetworkChangesMs).
- return LOAD_STATE_DOWNLOADING_PROXY_SCRIPT;
+ return LOAD_STATE_DOWNLOADING_PAC_FILE;
}
return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
}
@@ -469,8 +499,8 @@ class ProxyResolutionService::InitProxyResolver {
private:
enum State {
STATE_NONE,
- STATE_DECIDE_PROXY_SCRIPT,
- STATE_DECIDE_PROXY_SCRIPT_COMPLETE,
+ STATE_DECIDE_PAC_FILE,
+ STATE_DECIDE_PAC_FILE_COMPLETE,
STATE_CREATE_RESOLVER,
STATE_CREATE_RESOLVER_COMPLETE,
};
@@ -482,12 +512,12 @@ class ProxyResolutionService::InitProxyResolver {
State state = next_state_;
next_state_ = STATE_NONE;
switch (state) {
- case STATE_DECIDE_PROXY_SCRIPT:
+ case STATE_DECIDE_PAC_FILE:
DCHECK_EQ(OK, rv);
- rv = DoDecideProxyScript();
+ rv = DoDecidePacFile();
break;
- case STATE_DECIDE_PROXY_SCRIPT_COMPLETE:
- rv = DoDecideProxyScriptComplete(rv);
+ case STATE_DECIDE_PAC_FILE_COMPLETE:
+ rv = DoDecidePacFileComplete(rv);
break;
case STATE_CREATE_RESOLVER:
DCHECK_EQ(OK, rv);
@@ -505,15 +535,15 @@ class ProxyResolutionService::InitProxyResolver {
return rv;
}
- int DoDecideProxyScript() {
- next_state_ = STATE_DECIDE_PROXY_SCRIPT_COMPLETE;
+ int DoDecidePacFile() {
+ next_state_ = STATE_DECIDE_PAC_FILE_COMPLETE;
return decider_->Start(
config_, wait_delay_, proxy_resolver_factory_->expects_pac_bytes(),
base::Bind(&InitProxyResolver::OnIOCompletion, base::Unretained(this)));
}
- int DoDecideProxyScriptComplete(int result) {
+ int DoDecidePacFileComplete(int result) {
if (result != OK)
return result;
@@ -552,11 +582,11 @@ class ProxyResolutionService::InitProxyResolver {
callback_.Run(result);
}
- ProxyConfig config_;
- ProxyConfig effective_config_;
- scoped_refptr<ProxyResolverScriptData> script_data_;
+ ProxyConfigWithAnnotation config_;
+ ProxyConfigWithAnnotation effective_config_;
+ scoped_refptr<PacFileData> script_data_;
TimeDelta wait_delay_;
- std::unique_ptr<ProxyScriptDecider> decider_;
+ std::unique_ptr<PacFileDecider> decider_;
ProxyResolverFactory* proxy_resolver_factory_;
std::unique_ptr<ProxyResolverFactory::Request> create_resolver_request_;
std::unique_ptr<ProxyResolver>* proxy_resolver_;
@@ -567,16 +597,17 @@ class ProxyResolutionService::InitProxyResolver {
DISALLOW_COPY_AND_ASSIGN(InitProxyResolver);
};
-// ProxyResolutionService::ProxyScriptDeciderPoller ---------------------------
+// ProxyResolutionService::PacFileDeciderPoller ---------------------------
// This helper class encapsulates the logic to schedule and run periodic
// background checks to see if the PAC script (or effective proxy configuration)
// has changed. If a change is detected, then the caller will be notified via
// the ChangeCallback.
-class ProxyResolutionService::ProxyScriptDeciderPoller {
+class ProxyResolutionService::PacFileDeciderPoller {
public:
- typedef base::Callback<void(int, ProxyResolverScriptData*,
- const ProxyConfig&)> ChangeCallback;
+ typedef base::Callback<
+ void(int, PacFileData*, const ProxyConfigWithAnnotation&)>
+ ChangeCallback;
// Builds a poller helper, and starts polling for updates. Whenever a change
// is observed, |callback| will be invoked with the details.
@@ -585,11 +616,11 @@ class ProxyResolutionService::ProxyScriptDeciderPoller {
// |proxy_resolver_expects_pac_bytes| the type of proxy resolver we expect
// to use the resulting script data with
// (so it can choose the right format).
- // |proxy_script_fetcher| this pointer must remain alive throughout our
- // lifetime. It is the dependency that will be used
- // for downloading proxy scripts.
- // |dhcp_proxy_script_fetcher| similar to |proxy_script_fetcher|, but for
- // the DHCP dependency.
+ // |pac_file_fetcher| this pointer must remain alive throughout our
+ // lifetime. It is the dependency that will be used
+ // for downloading PAC files.
+ // |dhcp_pac_file_fetcher| similar to |pac_file_fetcher|, but for
+ // he DHCP dependency.
// |init_net_error| This is the initial network error (possibly success)
// encountered by the first PAC fetch attempt. We use it
// to schedule updates more aggressively if the initial
@@ -598,20 +629,19 @@ class ProxyResolutionService::ProxyScriptDeciderPoller {
// This is the baseline used to determine when the
// script's contents have changed.
// |net_log| the NetLog to log progress into.
- ProxyScriptDeciderPoller(ChangeCallback callback,
- const ProxyConfig& config,
- bool proxy_resolver_expects_pac_bytes,
- ProxyScriptFetcher* proxy_script_fetcher,
- DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher,
- int init_net_error,
- const scoped_refptr<ProxyResolverScriptData>&
- init_script_data,
- NetLog* net_log)
+ PacFileDeciderPoller(ChangeCallback callback,
+ const ProxyConfigWithAnnotation& config,
+ bool proxy_resolver_expects_pac_bytes,
+ PacFileFetcher* pac_file_fetcher,
+ DhcpPacFileFetcher* dhcp_pac_file_fetcher,
+ int init_net_error,
+ const scoped_refptr<PacFileData>& init_script_data,
+ NetLog* net_log)
: change_callback_(callback),
config_(config),
proxy_resolver_expects_pac_bytes_(proxy_resolver_expects_pac_bytes),
- proxy_script_fetcher_(proxy_script_fetcher),
- dhcp_proxy_script_fetcher_(dhcp_proxy_script_fetcher),
+ pac_file_fetcher_(pac_file_fetcher),
+ dhcp_pac_file_fetcher_(dhcp_pac_file_fetcher),
last_error_(init_net_error),
last_script_data_(init_script_data),
last_poll_time_(TimeTicks::Now()),
@@ -650,8 +680,8 @@ class ProxyResolutionService::ProxyScriptDeciderPoller {
DCHECK(!decider_.get());
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::Bind(&ProxyScriptDeciderPoller::DoPoll,
- weak_factory_.GetWeakPtr()),
+ FROM_HERE,
+ base::Bind(&PacFileDeciderPoller::DoPoll, weak_factory_.GetWeakPtr()),
next_poll_delay_);
}
@@ -675,21 +705,21 @@ class ProxyResolutionService::ProxyScriptDeciderPoller {
void DoPoll() {
last_poll_time_ = TimeTicks::Now();
- // Start the proxy script decider to see if anything has changed.
+ // Start the PAC file decider to see if anything has changed.
// TODO(eroman): Pass a proper NetLog rather than NULL.
- decider_.reset(new ProxyScriptDecider(
- proxy_script_fetcher_, dhcp_proxy_script_fetcher_, NULL));
+ decider_.reset(
+ new PacFileDecider(pac_file_fetcher_, dhcp_pac_file_fetcher_, NULL));
decider_->set_quick_check_enabled(quick_check_enabled_);
int result = decider_->Start(
config_, TimeDelta(), proxy_resolver_expects_pac_bytes_,
- base::Bind(&ProxyScriptDeciderPoller::OnProxyScriptDeciderCompleted,
+ base::Bind(&PacFileDeciderPoller::OnPacFileDeciderCompleted,
base::Unretained(this)));
if (result != ERR_IO_PENDING)
- OnProxyScriptDeciderCompleted(result);
+ OnPacFileDeciderCompleted(result);
}
- void OnProxyScriptDeciderCompleted(int result) {
+ void OnPacFileDeciderCompleted(int result) {
if (HasScriptDataChanged(result, decider_->script_data())) {
// Something has changed, we must notify the ProxyResolutionService so it
// can re-initialize its ProxyResolver. Note that we post a notification
@@ -698,10 +728,10 @@ class ProxyResolutionService::ProxyScriptDeciderPoller {
// the notification.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::Bind(&ProxyScriptDeciderPoller::NotifyProxyServiceOfChange,
- weak_factory_.GetWeakPtr(), result,
- decider_->script_data(),
- decider_->effective_config()));
+ base::Bind(
+ &PacFileDeciderPoller::NotifyProxyResolutionServiceOfChange,
+ weak_factory_.GetWeakPtr(), result, decider_->script_data(),
+ decider_->effective_config()));
return;
}
@@ -715,7 +745,7 @@ class ProxyResolutionService::ProxyScriptDeciderPoller {
}
bool HasScriptDataChanged(int result,
- const scoped_refptr<ProxyResolverScriptData>& script_data) {
+ const scoped_refptr<PacFileData>& script_data) {
if (result != last_error_) {
// Something changed -- it was failing before and now it succeeded, or
// conversely it succeeded before and now it failed. Or it failed in
@@ -735,25 +765,25 @@ class ProxyResolutionService::ProxyScriptDeciderPoller {
return !script_data->Equals(last_script_data_.get());
}
- void NotifyProxyServiceOfChange(
+ void NotifyProxyResolutionServiceOfChange(
int result,
- const scoped_refptr<ProxyResolverScriptData>& script_data,
- const ProxyConfig& effective_config) {
+ const scoped_refptr<PacFileData>& script_data,
+ const ProxyConfigWithAnnotation& effective_config) {
// Note that |this| may be deleted after calling into the
// ProxyResolutionService.
change_callback_.Run(result, script_data.get(), effective_config);
}
ChangeCallback change_callback_;
- ProxyConfig config_;
+ ProxyConfigWithAnnotation config_;
bool proxy_resolver_expects_pac_bytes_;
- ProxyScriptFetcher* proxy_script_fetcher_;
- DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher_;
+ PacFileFetcher* pac_file_fetcher_;
+ DhcpPacFileFetcher* dhcp_pac_file_fetcher_;
int last_error_;
- scoped_refptr<ProxyResolverScriptData> last_script_data_;
+ scoped_refptr<PacFileData> last_script_data_;
- std::unique_ptr<ProxyScriptDecider> decider_;
+ std::unique_ptr<PacFileDecider> decider_;
TimeDelta next_poll_delay_;
PacPollPolicy::Mode next_poll_mode_;
@@ -767,14 +797,14 @@ class ProxyResolutionService::ProxyScriptDeciderPoller {
bool quick_check_enabled_;
- base::WeakPtrFactory<ProxyScriptDeciderPoller> weak_factory_;
+ base::WeakPtrFactory<PacFileDeciderPoller> weak_factory_;
- DISALLOW_COPY_AND_ASSIGN(ProxyScriptDeciderPoller);
+ DISALLOW_COPY_AND_ASSIGN(PacFileDeciderPoller);
};
// static
const ProxyResolutionService::PacPollPolicy*
- ProxyResolutionService::ProxyScriptDeciderPoller::poll_policy_ = NULL;
+ ProxyResolutionService::PacFileDeciderPoller::poll_policy_ = NULL;
// ProxyResolutionService::Request --------------------------------------------
@@ -795,7 +825,6 @@ class ProxyResolutionService::Request
method_(method),
proxy_delegate_(proxy_delegate),
resolve_job_(nullptr),
- config_source_(PROXY_CONFIG_SOURCE_UNKNOWN),
net_log_(net_log),
creation_time_(TimeTicks::Now()) {
DCHECK(!user_callback.is_null());
@@ -807,7 +836,8 @@ class ProxyResolutionService::Request
DCHECK(!is_started());
DCHECK(service_->config_);
- config_source_ = service_->config_->source();
+ traffic_annotation_ = MutableNetworkTrafficAnnotationTag(
+ service_->config_->traffic_annotation());
return resolver()->GetProxyForURL(
url_, results_,
@@ -847,7 +877,7 @@ class ProxyResolutionService::Request
user_callback_.Reset();
results_ = NULL;
- net_log_.EndEvent(NetLogEventType::PROXY_SERVICE);
+ net_log_.EndEvent(NetLogEventType::PROXY_RESOLUTION_SERVICE);
}
// Returns true if Cancel() has been called.
@@ -870,13 +900,21 @@ class ProxyResolutionService::Request
// Make a note in the results which configuration was in use at the
// time of the resolve.
- results_->config_source_ = config_source_;
results_->did_use_pac_script_ = true;
results_->proxy_resolve_start_time_ = creation_time_;
results_->proxy_resolve_end_time_ = TimeTicks::Now();
+ // If annotation is not already set, e.g. through TryToCompleteSynchronously
+ // function, use in-progress-resolve annotation.
+ if (!results_->traffic_annotation_.is_valid())
+ results_->set_traffic_annotation(traffic_annotation_);
+
+ // If proxy is set without error, ensure that an annotation is provided.
+ if (!rv)
+ DCHECK(results_->traffic_annotation_.is_valid());
+
// Reset the state associated with in-progress-resolve.
- config_source_ = PROXY_CONFIG_SOURCE_UNKNOWN;
+ traffic_annotation_.reset();
return rv;
}
@@ -919,7 +957,7 @@ class ProxyResolutionService::Request
std::string method_;
ProxyDelegate* proxy_delegate_;
std::unique_ptr<ProxyResolver::Request> resolve_job_;
- ProxyConfigSource config_source_; // The source of proxy settings.
+ MutableNetworkTrafficAnnotationTag traffic_annotation_;
NetLogWithSource net_log_;
// Time when the request was created. Stored here rather than in |results_|
// because the time in |results_| will be cleared.
@@ -974,7 +1012,7 @@ ProxyResolutionService::CreateWithoutProxyResolver(
// static
std::unique_ptr<ProxyResolutionService> ProxyResolutionService::CreateFixed(
- const ProxyConfig& pc) {
+ const ProxyConfigWithAnnotation& pc) {
// TODO(eroman): This isn't quite right, won't work if |pc| specifies
// a PAC script.
return CreateUsingSystemProxyResolver(
@@ -983,10 +1021,12 @@ std::unique_ptr<ProxyResolutionService> ProxyResolutionService::CreateFixed(
// static
std::unique_ptr<ProxyResolutionService> ProxyResolutionService::CreateFixed(
- const std::string& proxy) {
+ const std::string& proxy,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
ProxyConfig proxy_config;
proxy_config.proxy_rules().ParseFromString(proxy);
- return ProxyResolutionService::CreateFixed(proxy_config);
+ ProxyConfigWithAnnotation annotated_config(proxy_config, traffic_annotation);
+ return ProxyResolutionService::CreateFixed(annotated_config);
}
// static
@@ -1005,11 +1045,13 @@ ProxyResolutionService::CreateDirectWithNetLog(NetLog* net_log) {
// static
std::unique_ptr<ProxyResolutionService>
ProxyResolutionService::CreateFixedFromPacResult(
- const std::string& pac_string) {
+ const std::string& pac_string,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
// We need the settings to contain an "automatic" setting, otherwise the
// ProxyResolver dependency we give it will never be used.
std::unique_ptr<ProxyConfigService> proxy_config_service(
- new ProxyConfigServiceFixed(ProxyConfig::CreateAutoDetect()));
+ new ProxyConfigServiceFixed(ProxyConfigWithAnnotation(
+ ProxyConfig::CreateAutoDetect(), traffic_annotation)));
return std::make_unique<ProxyResolutionService>(
std::move(proxy_config_service),
@@ -1038,7 +1080,7 @@ int ProxyResolutionService::ResolveProxyHelper(
const NetLogWithSource& net_log) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- net_log.BeginEvent(NetLogEventType::PROXY_SERVICE);
+ net_log.BeginEvent(NetLogEventType::PROXY_RESOLUTION_SERVICE);
// Notify our polling-based dependencies that a resolve is taking place.
// This way they can schedule their polls in response to network activity.
@@ -1077,7 +1119,7 @@ int ProxyResolutionService::ResolveProxyHelper(
return req->QueryDidComplete(rv);
} else {
req->net_log()->BeginEvent(
- NetLogEventType::PROXY_SERVICE_WAITING_FOR_INIT_PAC);
+ NetLogEventType::PROXY_RESOLUTION_SERVICE_WAITING_FOR_INIT_PAC);
}
DCHECK_EQ(ERR_IO_PENDING, rv);
@@ -1118,12 +1160,13 @@ int ProxyResolutionService::TryToCompleteSynchronously(
if (permanent_error_ != OK)
return permanent_error_;
- if (config_->HasAutomaticSettings())
+ if (config_->value().HasAutomaticSettings())
return ERR_IO_PENDING; // Must submit the request to the proxy resolver.
// Use the manual proxy settings.
- config_->proxy_rules().Apply(url, result);
- result->config_source_ = config_->source();
+ config_->value().proxy_rules().Apply(url, result);
+ result->set_traffic_annotation(
+ MutableNetworkTrafficAnnotationTag(config_->traffic_annotation()));
return OK;
}
@@ -1151,7 +1194,7 @@ void ProxyResolutionService::SuspendAllPendingRequests() {
req->CancelResolveJob();
req->net_log()->BeginEvent(
- NetLogEventType::PROXY_SERVICE_WAITING_FOR_INIT_PAC);
+ NetLogEventType::PROXY_RESOLUTION_SERVICE_WAITING_FOR_INIT_PAC);
}
}
}
@@ -1171,7 +1214,7 @@ void ProxyResolutionService::SetReady() {
Request* req = it->get();
if (!req->is_started() && !req->was_cancelled()) {
req->net_log()->EndEvent(
- NetLogEventType::PROXY_SERVICE_WAITING_FOR_INIT_PAC);
+ NetLogEventType::PROXY_RESOLUTION_SERVICE_WAITING_FOR_INIT_PAC);
// Note that we re-check for synchronous completion, in case we are
// no longer using a ProxyResolver (can happen if we fell-back to manual).
@@ -1197,7 +1240,7 @@ void ProxyResolutionService::ApplyProxyConfigIfAvailable() {
// Retrieve the current proxy configuration from the ProxyConfigService.
// If a configuration is not available yet, we will get called back later
// by our ProxyConfigService::Observer once it changes.
- ProxyConfig config;
+ ProxyConfigWithAnnotation config;
ProxyConfigService::ConfigAvailability availability =
config_service_->GetLatestProxyConfig(&config);
if (availability != ProxyConfigService::CONFIG_PENDING)
@@ -1208,7 +1251,7 @@ void ProxyResolutionService::OnInitProxyResolverComplete(int result) {
DCHECK_EQ(STATE_WAITING_FOR_INIT_PROXY_RESOLVER, current_state_);
DCHECK(init_proxy_resolver_.get());
DCHECK(fetched_config_);
- DCHECK(fetched_config_->HasAutomaticSettings());
+ DCHECK(fetched_config_->value().HasAutomaticSettings());
config_ = init_proxy_resolver_->effective_config();
// At this point we have decided which proxy settings to use (i.e. which PAC
@@ -1216,18 +1259,18 @@ void ProxyResolutionService::OnInitProxyResolverComplete(int result) {
// this decision. If the contents of the PAC script change, or if the
// result of proxy auto-discovery changes, this poller will notice it and
// will trigger a re-initialization using the newly discovered PAC.
- script_poller_.reset(new ProxyScriptDeciderPoller(
+ script_poller_.reset(new PacFileDeciderPoller(
base::Bind(&ProxyResolutionService::InitializeUsingDecidedConfig,
base::Unretained(this)),
fetched_config_.value(), resolver_factory_->expects_pac_bytes(),
- proxy_script_fetcher_.get(), dhcp_proxy_script_fetcher_.get(), result,
+ pac_file_fetcher_.get(), dhcp_pac_file_fetcher_.get(), result,
init_proxy_resolver_->script_data(), NULL));
script_poller_->set_quick_check_enabled(quick_check_enabled_);
init_proxy_resolver_.reset();
if (result != OK) {
- if (fetched_config_->pac_mandatory()) {
+ if (fetched_config_->value().pac_mandatory()) {
VLOG(1) << "Failed configuring with mandatory PAC script, blocking all "
"traffic.";
config_ = fetched_config_;
@@ -1235,15 +1278,15 @@ void ProxyResolutionService::OnInitProxyResolverComplete(int result) {
} else {
VLOG(1) << "Failed configuring with PAC script, falling-back to manual "
"proxy servers.";
- config_ = fetched_config_;
- config_->ClearAutomaticSettings();
+ ProxyConfig proxy_config = fetched_config_->value();
+ proxy_config.ClearAutomaticSettings();
+ config_ = ProxyConfigWithAnnotation(
+ proxy_config, fetched_config_->traffic_annotation());
result = OK;
}
}
permanent_error_ = result;
- config_->set_source(fetched_config_->source());
-
// Resume any requests which we had to defer until the PAC script was
// downloaded.
SetReady();
@@ -1327,23 +1370,25 @@ int ProxyResolutionService::DidFinishResolvingProxy(
if (proxy_delegate)
proxy_delegate->OnResolveProxy(url, method, proxy_retry_info_, result);
- net_log.AddEvent(NetLogEventType::PROXY_SERVICE_RESOLVED_PROXY_LIST,
- base::Bind(&NetLogFinishedResolvingProxyCallback, result));
+ net_log.AddEvent(
+ NetLogEventType::PROXY_RESOLUTION_SERVICE_RESOLVED_PROXY_LIST,
+ base::Bind(&NetLogFinishedResolvingProxyCallback, result));
// This check is done to only log the NetLog event when necessary, it's
// not a performance optimization.
if (!proxy_retry_info_.empty()) {
result->DeprioritizeBadProxies(proxy_retry_info_);
net_log.AddEvent(
- NetLogEventType::PROXY_SERVICE_DEPRIORITIZED_BAD_PROXIES,
+ NetLogEventType::PROXY_RESOLUTION_SERVICE_DEPRIORITIZED_BAD_PROXIES,
base::Bind(&NetLogFinishedResolvingProxyCallback, result));
}
} else {
net_log.AddEventWithNetErrorCode(
- NetLogEventType::PROXY_SERVICE_RESOLVED_PROXY_LIST, result_code);
+ NetLogEventType::PROXY_RESOLUTION_SERVICE_RESOLVED_PROXY_LIST,
+ result_code);
bool reset_config = result_code == ERR_PAC_SCRIPT_TERMINATED;
- if (!config_->pac_mandatory()) {
+ if (!config_->value().pac_mandatory()) {
// Fall-back to direct when the proxy resolver fails. This corresponds
// with a javascript runtime error in the PAC script.
//
@@ -1371,17 +1416,17 @@ int ProxyResolutionService::DidFinishResolvingProxy(
}
}
- net_log.EndEvent(NetLogEventType::PROXY_SERVICE);
+ net_log.EndEvent(NetLogEventType::PROXY_RESOLUTION_SERVICE);
return result_code;
}
-void ProxyResolutionService::SetProxyScriptFetchers(
- std::unique_ptr<ProxyScriptFetcher> proxy_script_fetcher,
- std::unique_ptr<DhcpProxyScriptFetcher> dhcp_proxy_script_fetcher) {
+void ProxyResolutionService::SetPacFileFetchers(
+ std::unique_ptr<PacFileFetcher> pac_file_fetcher,
+ std::unique_ptr<DhcpPacFileFetcher> dhcp_pac_file_fetcher) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
State previous_state = ResetProxyConfig(false);
- proxy_script_fetcher_ = std::move(proxy_script_fetcher);
- dhcp_proxy_script_fetcher_ = std::move(dhcp_proxy_script_fetcher);
+ pac_file_fetcher_ = std::move(pac_file_fetcher);
+ dhcp_pac_file_fetcher_ = std::move(dhcp_pac_file_fetcher);
if (previous_state != STATE_NONE)
ApplyProxyConfigIfAvailable();
}
@@ -1391,15 +1436,15 @@ void ProxyResolutionService::OnShutdown() {
// because shutting it down also cancels its requests using the fetcher.
if (init_proxy_resolver_)
init_proxy_resolver_->OnShutdown();
- if (proxy_script_fetcher_)
- proxy_script_fetcher_->OnShutdown();
- if (dhcp_proxy_script_fetcher_)
- dhcp_proxy_script_fetcher_->OnShutdown();
+ if (pac_file_fetcher_)
+ pac_file_fetcher_->OnShutdown();
+ if (dhcp_pac_file_fetcher_)
+ dhcp_pac_file_fetcher_->OnShutdown();
}
-ProxyScriptFetcher* ProxyResolutionService::GetProxyScriptFetcher() const {
+PacFileFetcher* ProxyResolutionService::GetPacFileFetcher() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- return proxy_script_fetcher_.get();
+ return pac_file_fetcher_.get();
}
ProxyResolutionService::State ProxyResolutionService::ResetProxyConfig(
@@ -1413,9 +1458,9 @@ ProxyResolutionService::State ProxyResolutionService::ResetProxyConfig(
init_proxy_resolver_.reset();
SuspendAllPendingRequests();
resolver_.reset();
- config_ = base::Optional<ProxyConfig>();
+ config_ = base::Optional<ProxyConfigWithAnnotation>();
if (reset_fetched_config)
- fetched_config_ = base::Optional<ProxyConfig>();
+ fetched_config_ = base::Optional<ProxyConfigWithAnnotation>();
current_state_ = STATE_NONE;
return previous_state;
@@ -1447,13 +1492,16 @@ void ProxyResolutionService::ForceReloadProxyConfig() {
// static
std::unique_ptr<ProxyConfigService>
ProxyResolutionService::CreateSystemProxyConfigService(
- const scoped_refptr<base::SequencedTaskRunner>& io_task_runner) {
+ const scoped_refptr<base::SequencedTaskRunner>& main_task_runner) {
#if defined(OS_WIN)
- return std::make_unique<ProxyConfigServiceWin>();
+ return std::make_unique<ProxyConfigServiceWin>(
+ kSystemProxyConfigTrafficAnnotation);
#elif defined(OS_IOS)
- return std::make_unique<ProxyConfigServiceIOS>();
+ return std::make_unique<ProxyConfigServiceIOS>(
+ kSystemProxyConfigTrafficAnnotation);
#elif defined(OS_MACOSX)
- return std::make_unique<ProxyConfigServiceMac>(io_task_runner);
+ return std::make_unique<ProxyConfigServiceMac>(
+ main_task_runner, kSystemProxyConfigTrafficAnnotation);
#elif defined(OS_CHROMEOS)
LOG(ERROR) << "ProxyConfigService for ChromeOS should be created in "
<< "profile_io_data.cc::CreateProxyConfigService and this should "
@@ -1473,13 +1521,14 @@ ProxyResolutionService::CreateSystemProxyConfigService(
// glib_default_loop). Additionally register for notifications (delivered in
// either |glib_default_loop| or an internal sequenced task runner) to
// keep us updated when the proxy config changes.
- linux_config_service->SetupAndFetchInitialConfig(glib_thread_task_runner,
- io_task_runner);
+ linux_config_service->SetupAndFetchInitialConfig(
+ glib_thread_task_runner, main_task_runner,
+ kSystemProxyConfigTrafficAnnotation);
return std::move(linux_config_service);
#elif defined(OS_ANDROID)
return std::make_unique<ProxyConfigServiceAndroid>(
- io_task_runner, base::ThreadTaskRunnerHandle::Get());
+ main_task_runner, base::ThreadTaskRunnerHandle::Get());
#else
LOG(WARNING) << "Failed to choose a system proxy settings fetcher "
"for this platform.";
@@ -1491,7 +1540,7 @@ ProxyResolutionService::CreateSystemProxyConfigService(
const ProxyResolutionService::PacPollPolicy*
ProxyResolutionService::set_pac_script_poll_policy(
const PacPollPolicy* policy) {
- return ProxyScriptDeciderPoller::set_policy(policy);
+ return PacFileDeciderPoller::set_policy(policy);
}
// static
@@ -1501,12 +1550,12 @@ ProxyResolutionService::CreateDefaultPacPollPolicy() {
}
void ProxyResolutionService::OnProxyConfigChanged(
- const ProxyConfig& config,
+ const ProxyConfigWithAnnotation& config,
ProxyConfigService::ConfigAvailability availability) {
// Retrieve the current proxy configuration from the ProxyConfigService.
// If a configuration is not available yet, we will get called back later
// by our ProxyConfigService::Observer once it changes.
- ProxyConfig effective_config;
+ ProxyConfigWithAnnotation effective_config;
switch (availability) {
case ProxyConfigService::CONFIG_PENDING:
// ProxyConfigService implementors should never pass CONFIG_PENDING.
@@ -1516,7 +1565,7 @@ void ProxyResolutionService::OnProxyConfigChanged(
effective_config = config;
break;
case ProxyConfigService::CONFIG_UNSET:
- effective_config = ProxyConfig::CreateDirect();
+ effective_config = ProxyConfigWithAnnotation::CreateDirect();
break;
}
@@ -1537,7 +1586,7 @@ void ProxyResolutionService::InitializeUsingLastFetchedConfig() {
ResetProxyConfig(false);
DCHECK(fetched_config_);
- if (!fetched_config_->HasAutomaticSettings()) {
+ if (!fetched_config_->value().HasAutomaticSettings()) {
config_ = fetched_config_;
SetReady();
return;
@@ -1553,8 +1602,8 @@ void ProxyResolutionService::InitializeUsingLastFetchedConfig() {
init_proxy_resolver_.reset(new InitProxyResolver());
init_proxy_resolver_->set_quick_check_enabled(quick_check_enabled_);
int rv = init_proxy_resolver_->Start(
- &resolver_, resolver_factory_.get(), proxy_script_fetcher_.get(),
- dhcp_proxy_script_fetcher_.get(), net_log_, fetched_config_.value(),
+ &resolver_, resolver_factory_.get(), pac_file_fetcher_.get(),
+ dhcp_pac_file_fetcher_.get(), net_log_, fetched_config_.value(),
wait_delay,
base::Bind(&ProxyResolutionService::OnInitProxyResolverComplete,
base::Unretained(this)));
@@ -1565,10 +1614,10 @@ void ProxyResolutionService::InitializeUsingLastFetchedConfig() {
void ProxyResolutionService::InitializeUsingDecidedConfig(
int decider_result,
- ProxyResolverScriptData* script_data,
- const ProxyConfig& effective_config) {
+ PacFileData* script_data,
+ const ProxyConfigWithAnnotation& effective_config) {
DCHECK(fetched_config_);
- DCHECK(fetched_config_->HasAutomaticSettings());
+ DCHECK(fetched_config_->value().HasAutomaticSettings());
ResetProxyConfig(false);
diff --git a/chromium/net/proxy_resolution/proxy_service.h b/chromium/net/proxy_resolution/proxy_resolution_service.h
index e7c867a91e0..de6bd2a94d0 100644
--- a/chromium/net/proxy_resolution/proxy_service.h
+++ b/chromium/net/proxy_resolution/proxy_resolution_service.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef NET_PROXY_RESOLUTION_PROXY_SERVICE_H_
-#define NET_PROXY_RESOLUTION_PROXY_SERVICE_H_
+#ifndef NET_PROXY_RESOLUTION_PROXY_RESOLUTION_SERVICE_H_
+#define NET_PROXY_RESOLUTION_PROXY_RESOLUTION_SERVICE_H_
#include <stddef.h>
@@ -24,6 +24,7 @@
#include "net/base/network_change_notifier.h"
#include "net/base/proxy_server.h"
#include "net/proxy_resolution/proxy_config_service.h"
+#include "net/proxy_resolution/proxy_config_with_annotation.h"
#include "net/proxy_resolution/proxy_info.h"
#include "url/gurl.h"
@@ -36,14 +37,14 @@ class TimeDelta;
namespace net {
-class DhcpProxyScriptFetcher;
+class DhcpPacFileFetcher;
class NetLog;
class NetLogWithSource;
class ProxyDelegate;
class ProxyResolver;
class ProxyResolverFactory;
-class ProxyResolverScriptData;
-class ProxyScriptFetcher;
+class PacFileData;
+class PacFileFetcher;
// This class can be used to resolve the proxy server to use when loading a
// HTTP(S) URL. It uses the given ProxyResolver to handle the actual proxy
@@ -190,12 +191,12 @@ class NET_EXPORT ProxyResolutionService
// Returns the LoadState for this |request| which must be non-NULL.
LoadState GetLoadState(const Request* request) const;
- // Sets the ProxyScriptFetcher and DhcpProxyScriptFetcher dependencies. This
+ // Sets the PacFileFetcher and DhcpPacFileFetcher dependencies. This
// is needed if the ProxyResolver is of type ProxyResolverWithoutFetch.
- void SetProxyScriptFetchers(
- std::unique_ptr<ProxyScriptFetcher> proxy_script_fetcher,
- std::unique_ptr<DhcpProxyScriptFetcher> dhcp_proxy_script_fetcher);
- ProxyScriptFetcher* GetProxyScriptFetcher() const;
+ void SetPacFileFetchers(
+ std::unique_ptr<PacFileFetcher> pac_file_fetcher,
+ std::unique_ptr<DhcpPacFileFetcher> dhcp_pac_file_fetcher);
+ PacFileFetcher* GetPacFileFetcher() const;
// Cancels all network requests, and prevents the service from creating new
// ones. Must be called before the URLRequestContext the
@@ -211,12 +212,14 @@ class NET_EXPORT ProxyResolutionService
std::unique_ptr<ProxyConfigService> new_proxy_config_service);
// Returns the last configuration fetched from ProxyConfigService.
- const base::Optional<ProxyConfig>& fetched_config() const {
+ const base::Optional<ProxyConfigWithAnnotation>& fetched_config() const {
return fetched_config_;
}
// Returns the current configuration being used by ProxyConfigService.
- const base::Optional<ProxyConfig>& config() const { return config_; }
+ const base::Optional<ProxyConfigWithAnnotation>& config() const {
+ return config_;
+ }
// Returns the map of proxies which have been marked as "bad".
const ProxyRetryInfoMap& proxy_retry_info() const {
@@ -233,9 +236,9 @@ class NET_EXPORT ProxyResolutionService
// to downloading and testing the PAC files.
void ForceReloadProxyConfig();
- // Same as CreateProxyServiceUsingV8ProxyResolver, except it uses system
- // libraries for evaluating the PAC script if available, otherwise skips
- // proxy autoconfig.
+ // Same as CreateProxyResolutionServiceUsingV8ProxyResolver, except it uses
+ // system libraries for evaluating the PAC script if available, otherwise
+ // skips proxy autoconfig.
static std::unique_ptr<ProxyResolutionService> CreateUsingSystemProxyResolver(
std::unique_ptr<ProxyConfigService> proxy_config_service,
NetLog* net_log);
@@ -248,9 +251,10 @@ class NET_EXPORT ProxyResolutionService
// Convenience methods that creates a proxy service using the
// specified fixed settings.
static std::unique_ptr<ProxyResolutionService> CreateFixed(
- const ProxyConfig& pc);
+ const ProxyConfigWithAnnotation& pc);
static std::unique_ptr<ProxyResolutionService> CreateFixed(
- const std::string& proxy);
+ const std::string& proxy,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
// Creates a proxy service that uses a DIRECT connection for all requests.
static std::unique_ptr<ProxyResolutionService> CreateDirect();
@@ -264,12 +268,18 @@ class NET_EXPORT ProxyResolutionService
// |pac_string| is a list of proxy servers, in the format that a PAC script
// would return it. For example, "PROXY foobar:99; SOCKS fml:2; DIRECT"
static std::unique_ptr<ProxyResolutionService> CreateFixedFromPacResult(
- const std::string& pac_string);
+ const std::string& pac_string,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
// Creates a config service appropriate for this platform that fetches the
- // system proxy settings.
+ // system proxy settings. |main_task_runner| is the thread where the consumer
+ // of the ProxyConfigService will live.
+ //
+ // TODO(mmenke): Should this be a member of ProxyConfigService?
+ // The ProxyResolutionService may not even be in the same process as the
+ // system ProxyConfigService.
static std::unique_ptr<ProxyConfigService> CreateSystemProxyConfigService(
- const scoped_refptr<base::SequencedTaskRunner>& io_task_runner);
+ const scoped_refptr<base::SequencedTaskRunner>& main_task_runner);
// This method should only be used by unit tests.
void set_stall_proxy_auto_config_delay(base::TimeDelta delay) {
@@ -294,11 +304,13 @@ class NET_EXPORT ProxyResolutionService
}
private:
- FRIEND_TEST_ALL_PREFIXES(ProxyServiceTest, UpdateConfigAfterFailedAutodetect);
- FRIEND_TEST_ALL_PREFIXES(ProxyServiceTest, UpdateConfigFromPACToDirect);
+ FRIEND_TEST_ALL_PREFIXES(ProxyResolutionServiceTest,
+ UpdateConfigAfterFailedAutodetect);
+ FRIEND_TEST_ALL_PREFIXES(ProxyResolutionServiceTest,
+ UpdateConfigFromPACToDirect);
friend class Request;
class InitProxyResolver;
- class ProxyScriptDeciderPoller;
+ class PacFileDeciderPoller;
typedef std::set<scoped_refptr<Request>> PendingRequests;
@@ -373,8 +385,8 @@ class NET_EXPORT ProxyResolutionService
// Start the initialization skipping past the "decision" phase.
void InitializeUsingDecidedConfig(
int decider_result,
- ProxyResolverScriptData* script_data,
- const ProxyConfig& effective_config);
+ PacFileData* script_data,
+ const ProxyConfigWithAnnotation& effective_config);
// NetworkChangeNotifier::IPAddressObserver
// When this is called, we re-fetch PAC scripts and re-run WPAD.
@@ -386,7 +398,7 @@ class NET_EXPORT ProxyResolutionService
// ProxyConfigService::Observer
void OnProxyConfigChanged(
- const ProxyConfig& config,
+ const ProxyConfigWithAnnotation& config,
ProxyConfigService::ConfigAvailability availability) override;
std::unique_ptr<ProxyConfigService> config_service_;
@@ -400,8 +412,8 @@ class NET_EXPORT ProxyResolutionService
// and custom PAC url).
//
// These are "optional" as their value remains unset while being calculated.
- base::Optional<ProxyConfig> fetched_config_;
- base::Optional<ProxyConfig> config_;
+ base::Optional<ProxyConfigWithAnnotation> fetched_config_;
+ base::Optional<ProxyConfigWithAnnotation> config_;
// The time when the proxy configuration was last read from the system.
base::TimeTicks config_last_update_time_;
@@ -415,21 +427,21 @@ class NET_EXPORT ProxyResolutionService
// The fetcher to use when downloading PAC scripts for the ProxyResolver.
// This dependency can be NULL if our ProxyResolver has no need for
// external PAC script fetching.
- std::unique_ptr<ProxyScriptFetcher> proxy_script_fetcher_;
+ std::unique_ptr<PacFileFetcher> pac_file_fetcher_;
// The fetcher to use when attempting to download the most appropriate PAC
// script configured in DHCP, if any. Can be NULL if the ProxyResolver has
// no need for DHCP PAC script fetching.
- std::unique_ptr<DhcpProxyScriptFetcher> dhcp_proxy_script_fetcher_;
+ std::unique_ptr<DhcpPacFileFetcher> dhcp_pac_file_fetcher_;
// Helper to download the PAC script (wpad + custom) and apply fallback rules.
//
- // Note that the declaration is important here: |proxy_script_fetcher_| and
+ // Note that the declaration is important here: |pac_file_fetcher_| and
// |proxy_resolver_| must outlive |init_proxy_resolver_|.
std::unique_ptr<InitProxyResolver> init_proxy_resolver_;
// Helper to poll the PAC script for changes.
- std::unique_ptr<ProxyScriptDeciderPoller> script_poller_;
+ std::unique_ptr<PacFileDeciderPoller> script_poller_;
State current_state_;
@@ -448,7 +460,7 @@ class NET_EXPORT ProxyResolutionService
// The amount of time to stall requests following IP address changes.
base::TimeDelta stall_proxy_auto_config_delay_;
- // Whether child ProxyScriptDeciders should use QuickCheck
+ // Whether child PacFileDeciders should use QuickCheck
bool quick_check_enabled_;
// The method to use for sanitizing URLs seen by the proxy resolver.
@@ -461,4 +473,4 @@ class NET_EXPORT ProxyResolutionService
} // namespace net
-#endif // NET_PROXY_RESOLUTION_PROXY_SERVICE_H_
+#endif // NET_PROXY_RESOLUTION_PROXY_RESOLUTION_SERVICE_H_
diff --git a/chromium/net/proxy_resolution/proxy_service_unittest.cc b/chromium/net/proxy_resolution/proxy_resolution_service_unittest.cc
index 5efa61aaa54..7a417a8be1a 100644
--- a/chromium/net/proxy_resolution/proxy_service_unittest.cc
+++ b/chromium/net/proxy_resolution/proxy_resolution_service_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include <cstdarg>
#include <string>
@@ -31,6 +31,7 @@
#include "net/proxy_resolution/proxy_config_service.h"
#include "net/proxy_resolution/proxy_resolver.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -113,7 +114,7 @@ class ImmediateAfterActivityPollPolicy
//
// The tests which verify the polling code re-enable the polling behavior but
// are careful to avoid timing problems.
-class ProxyServiceTest : public testing::Test {
+class ProxyResolutionServiceTest : public testing::Test {
protected:
void SetUp() override {
testing::Test::SetUp();
@@ -139,13 +140,13 @@ class MockProxyConfigService: public ProxyConfigService {
public:
explicit MockProxyConfigService(const ProxyConfig& config)
: availability_(CONFIG_VALID),
- config_(config) {
- }
+ config_(
+ ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS)) {}
explicit MockProxyConfigService(const std::string& pac_url)
: availability_(CONFIG_VALID),
- config_(ProxyConfig::CreateFromCustomPacURL(GURL(pac_url))) {
- }
+ config_(ProxyConfig::CreateFromCustomPacURL(GURL(pac_url)),
+ TRAFFIC_ANNOTATION_FOR_TESTS) {}
void AddObserver(Observer* observer) override {
observers_.AddObserver(observer);
@@ -155,13 +156,14 @@ class MockProxyConfigService: public ProxyConfigService {
observers_.RemoveObserver(observer);
}
- ConfigAvailability GetLatestProxyConfig(ProxyConfig* results) override {
+ ConfigAvailability GetLatestProxyConfig(
+ ProxyConfigWithAnnotation* results) override {
if (availability_ == CONFIG_VALID)
*results = config_;
return availability_;
}
- void SetConfig(const ProxyConfig& config) {
+ void SetConfig(const ProxyConfigWithAnnotation& config) {
availability_ = CONFIG_VALID;
config_ = config;
for (auto& observer : observers_)
@@ -170,7 +172,7 @@ class MockProxyConfigService: public ProxyConfigService {
private:
ConfigAvailability availability_;
- ProxyConfig config_;
+ ProxyConfigWithAnnotation config_;
base::ObserverList<Observer, true> observers_;
};
@@ -332,7 +334,7 @@ JobMap GetCancelledJobsForURLs(const MockAsyncProxyResolver& resolver,
} // namespace
-TEST_F(ProxyServiceTest, Direct) {
+TEST_F(ProxyResolutionServiceTest, Direct) {
MockAsyncProxyResolverFactory* factory =
new MockAsyncProxyResolverFactory(false);
ProxyResolutionService service(
@@ -358,15 +360,16 @@ TEST_F(ProxyServiceTest, Direct) {
log.GetEntries(&entries);
EXPECT_EQ(3u, entries.size());
- EXPECT_TRUE(
- LogContainsBeginEvent(entries, 0, NetLogEventType::PROXY_SERVICE));
+ EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
+ NetLogEventType::PROXY_RESOLUTION_SERVICE));
EXPECT_TRUE(LogContainsEvent(
- entries, 1, NetLogEventType::PROXY_SERVICE_RESOLVED_PROXY_LIST,
+ entries, 1, NetLogEventType::PROXY_RESOLUTION_SERVICE_RESOLVED_PROXY_LIST,
NetLogEventPhase::NONE));
- EXPECT_TRUE(LogContainsEndEvent(entries, 2, NetLogEventType::PROXY_SERVICE));
+ EXPECT_TRUE(LogContainsEndEvent(entries, 2,
+ NetLogEventType::PROXY_RESOLUTION_SERVICE));
}
-TEST_F(ProxyServiceTest, OnResolveProxyCallbackAddProxy) {
+TEST_F(ProxyResolutionServiceTest, OnResolveProxyCallbackAddProxy) {
ProxyConfig config;
config.proxy_rules().ParseFromString("badproxy:8080,foopy1:8080");
config.set_auto_detect(false);
@@ -426,7 +429,7 @@ TEST_F(ProxyServiceTest, OnResolveProxyCallbackAddProxy) {
EXPECT_TRUE(info.is_direct());
}
-TEST_F(ProxyServiceTest, OnResolveProxyCallbackRemoveProxy) {
+TEST_F(ProxyResolutionServiceTest, OnResolveProxyCallbackRemoveProxy) {
// Same as OnResolveProxyCallbackAddProxy, but verify that the
// ProxyDelegate's behavior is stateless across invocations after it
// *removes* a proxy.
@@ -471,7 +474,7 @@ TEST_F(ProxyServiceTest, OnResolveProxyCallbackRemoveProxy) {
EXPECT_TRUE(info.is_direct());
}
-TEST_F(ProxyServiceTest, PAC) {
+TEST_F(ProxyResolutionServiceTest, PAC) {
MockProxyConfigService* config_service =
new MockProxyConfigService("http://foopy/proxy.pac");
@@ -521,18 +524,21 @@ TEST_F(ProxyServiceTest, PAC) {
log.GetEntries(&entries);
EXPECT_EQ(5u, entries.size());
- EXPECT_TRUE(
- LogContainsBeginEvent(entries, 0, NetLogEventType::PROXY_SERVICE));
+ EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
+ NetLogEventType::PROXY_RESOLUTION_SERVICE));
EXPECT_TRUE(LogContainsBeginEvent(
- entries, 1, NetLogEventType::PROXY_SERVICE_WAITING_FOR_INIT_PAC));
+ entries, 1,
+ NetLogEventType::PROXY_RESOLUTION_SERVICE_WAITING_FOR_INIT_PAC));
EXPECT_TRUE(LogContainsEndEvent(
- entries, 2, NetLogEventType::PROXY_SERVICE_WAITING_FOR_INIT_PAC));
- EXPECT_TRUE(LogContainsEndEvent(entries, 4, NetLogEventType::PROXY_SERVICE));
+ entries, 2,
+ NetLogEventType::PROXY_RESOLUTION_SERVICE_WAITING_FOR_INIT_PAC));
+ EXPECT_TRUE(LogContainsEndEvent(entries, 4,
+ NetLogEventType::PROXY_RESOLUTION_SERVICE));
}
// Test that the proxy resolver does not see the URL's username/password
// or its reference section.
-TEST_F(ProxyServiceTest, PAC_NoIdentityOrHash) {
+TEST_F(ProxyResolutionServiceTest, PAC_NoIdentityOrHash) {
MockProxyConfigService* config_service =
new MockProxyConfigService("http://foopy/proxy.pac");
@@ -564,7 +570,7 @@ TEST_F(ProxyServiceTest, PAC_NoIdentityOrHash) {
// ProxyResolutionService will cancel the outstanding request.
}
-TEST_F(ProxyServiceTest, PAC_FailoverWithoutDirect) {
+TEST_F(ProxyResolutionServiceTest, PAC_FailoverWithoutDirect) {
MockProxyConfigService* config_service =
new MockProxyConfigService("http://foopy/proxy.pac");
MockAsyncProxyResolver resolver;
@@ -611,7 +617,7 @@ TEST_F(ProxyServiceTest, PAC_FailoverWithoutDirect) {
// Test that if the execution of the PAC script fails (i.e. javascript runtime
// error), and the PAC settings are non-mandatory, that we fall-back to direct.
-TEST_F(ProxyServiceTest, PAC_RuntimeError) {
+TEST_F(ProxyResolutionServiceTest, PAC_RuntimeError) {
MockProxyConfigService* config_service =
new MockProxyConfigService("http://foopy/proxy.pac");
MockAsyncProxyResolver resolver;
@@ -668,7 +674,7 @@ TEST_F(ProxyServiceTest, PAC_RuntimeError) {
//
// The important check of this test is to make sure that DIRECT is not somehow
// cached as being a bad proxy.
-TEST_F(ProxyServiceTest, PAC_FailoverAfterDirect) {
+TEST_F(ProxyResolutionServiceTest, PAC_FailoverAfterDirect) {
MockProxyConfigService* config_service =
new MockProxyConfigService("http://foopy/proxy.pac");
MockAsyncProxyResolver resolver;
@@ -720,12 +726,11 @@ TEST_F(ProxyServiceTest, PAC_FailoverAfterDirect) {
EXPECT_TRUE(info.is_empty());
}
-TEST_F(ProxyServiceTest, PAC_ConfigSourcePropagates) {
+TEST_F(ProxyResolutionServiceTest, PAC_ConfigSourcePropagates) {
// Test whether the ProxyConfigSource set by the ProxyConfigService is applied
// to ProxyInfo after the proxy is resolved via a PAC script.
ProxyConfig config =
ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
- config.set_source(PROXY_CONFIG_SOURCE_TEST);
MockProxyConfigService* config_service = new MockProxyConfigService(config);
MockAsyncProxyResolver resolver;
@@ -749,7 +754,8 @@ TEST_F(ProxyServiceTest, PAC_ConfigSourcePropagates) {
resolver.pending_jobs()[0]->CompleteNow(OK);
EXPECT_THAT(callback.WaitForResult(), IsOk());
- EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
+ EXPECT_EQ(MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
+ info.traffic_annotation());
EXPECT_TRUE(info.did_use_pac_script());
EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
@@ -757,7 +763,7 @@ TEST_F(ProxyServiceTest, PAC_ConfigSourcePropagates) {
EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
}
-TEST_F(ProxyServiceTest, ProxyResolverFails) {
+TEST_F(ProxyResolutionServiceTest, ProxyResolverFails) {
// Test what happens when the ProxyResolver fails. The download and setting
// of the PAC script have already succeeded, so this corresponds with a
// javascript runtime error while calling FindProxyForURL().
@@ -820,7 +826,7 @@ TEST_F(ProxyServiceTest, ProxyResolverFails) {
EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
}
-TEST_F(ProxyServiceTest, ProxyResolverTerminatedDuringRequest) {
+TEST_F(ProxyResolutionServiceTest, ProxyResolverTerminatedDuringRequest) {
// Test what happens when the ProxyResolver fails with a fatal error while
// a GetProxyForURL() call is in progress.
@@ -889,7 +895,7 @@ TEST_F(ProxyServiceTest, ProxyResolverTerminatedDuringRequest) {
EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
}
-TEST_F(ProxyServiceTest,
+TEST_F(ProxyResolutionServiceTest,
ProxyResolverTerminatedDuringRequestWithConcurrentRequest) {
// Test what happens when the ProxyResolver fails with a fatal error while
// a GetProxyForURL() call is in progress.
@@ -959,9 +965,9 @@ TEST_F(ProxyServiceTest,
EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
}
-TEST_F(ProxyServiceTest, ProxyScriptFetcherFailsDownloadingMandatoryPac) {
- // Test what happens when the ProxyScriptResolver fails to download a
- // mandatory PAC script.
+TEST_F(ProxyResolutionServiceTest, PacFileFetcherFailsDownloadingMandatoryPac) {
+ // Test what happens when the ProxyResolver fails to download a mandatory PAC
+ // script.
ProxyConfig config(
ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
@@ -1005,7 +1011,8 @@ TEST_F(ProxyServiceTest, ProxyScriptFetcherFailsDownloadingMandatoryPac) {
EXPECT_FALSE(info.is_direct());
}
-TEST_F(ProxyServiceTest, ProxyResolverFailsParsingJavaScriptMandatoryPac) {
+TEST_F(ProxyResolutionServiceTest,
+ ProxyResolverFailsParsingJavaScriptMandatoryPac) {
// Test what happens when the ProxyResolver fails that is configured to use a
// mandatory PAC script. The download of the PAC script has already
// succeeded but the PAC script contains no valid javascript.
@@ -1022,10 +1029,9 @@ TEST_F(ProxyServiceTest, ProxyResolverFailsParsingJavaScriptMandatoryPac) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), nullptr);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
// Start resolve request.
GURL url("http://www.google.com/");
@@ -1046,7 +1052,7 @@ TEST_F(ProxyServiceTest, ProxyResolverFailsParsingJavaScriptMandatoryPac) {
EXPECT_FALSE(fetcher->has_pending_request());
ASSERT_EQ(0u, factory->pending_requests().size());
- // Since ProxyScriptDecider failed to identify a valid PAC and PAC was
+ // Since PacFileDecider failed to identify a valid PAC and PAC was
// mandatory for this configuration, the ProxyResolutionService must not
// implicitly fall-back to DIRECT.
EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
@@ -1054,7 +1060,7 @@ TEST_F(ProxyServiceTest, ProxyResolverFailsParsingJavaScriptMandatoryPac) {
EXPECT_FALSE(info.is_direct());
}
-TEST_F(ProxyServiceTest, ProxyResolverFailsInJavaScriptMandatoryPac) {
+TEST_F(ProxyResolutionServiceTest, ProxyResolverFailsInJavaScriptMandatoryPac) {
// Test what happens when the ProxyResolver fails that is configured to use a
// mandatory PAC script. The download and setting of the PAC script have
// already succeeded, so this corresponds with a javascript runtime error
@@ -1117,7 +1123,7 @@ TEST_F(ProxyServiceTest, ProxyResolverFailsInJavaScriptMandatoryPac) {
EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
}
-TEST_F(ProxyServiceTest, ProxyFallback) {
+TEST_F(ProxyResolutionServiceTest, ProxyFallback) {
// Test what happens when we specify multiple proxy servers and some of them
// are bad.
@@ -1254,7 +1260,7 @@ TEST_F(ProxyServiceTest, ProxyFallback) {
// This test is similar to ProxyFallback, but this time we have an explicit
// fallback choice to DIRECT.
-TEST_F(ProxyServiceTest, ProxyFallbackToDirect) {
+TEST_F(ProxyResolutionServiceTest, ProxyFallbackToDirect) {
MockProxyConfigService* config_service =
new MockProxyConfigService("http://foopy/proxy.pac");
@@ -1313,7 +1319,7 @@ TEST_F(ProxyServiceTest, ProxyFallbackToDirect) {
EXPECT_FALSE(info.Fallback(ERR_PROXY_CONNECTION_FAILED, NetLogWithSource()));
}
-TEST_F(ProxyServiceTest, ProxyFallback_BadConfig) {
+TEST_F(ProxyResolutionServiceTest, ProxyFallback_BadConfig) {
// Test proxy failover when the configuration is bad.
MockProxyConfigService* config_service =
@@ -1408,7 +1414,7 @@ TEST_F(ProxyServiceTest, ProxyFallback_BadConfig) {
EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
}
-TEST_F(ProxyServiceTest, ProxyFallback_BadConfigMandatory) {
+TEST_F(ProxyResolutionServiceTest, ProxyFallback_BadConfigMandatory) {
// Test proxy failover when the configuration is bad.
ProxyConfig config(
@@ -1503,7 +1509,7 @@ TEST_F(ProxyServiceTest, ProxyFallback_BadConfigMandatory) {
EXPECT_EQ(2u, info3.proxy_list().size());
}
-TEST_F(ProxyServiceTest, ProxyBypassList) {
+TEST_F(ProxyResolutionServiceTest, ProxyBypassList) {
// Test that the proxy bypass rules are consulted.
TestCompletionCallback callback[2];
@@ -1535,7 +1541,7 @@ TEST_F(ProxyServiceTest, ProxyBypassList) {
EXPECT_EQ("foopy1:8080", info[1].proxy_server().ToURI());
}
-TEST_F(ProxyServiceTest, MarkProxiesAsBadTests) {
+TEST_F(ProxyResolutionServiceTest, MarkProxiesAsBadTests) {
ProxyConfig config;
config.proxy_rules().ParseFromString(
"http=foopy1:8080;http=foopy2:8080;http=foopy3.8080;http=foopy4:8080");
@@ -1570,7 +1576,7 @@ TEST_F(ProxyServiceTest, MarkProxiesAsBadTests) {
}
}
-TEST_F(ProxyServiceTest, PerProtocolProxyTests) {
+TEST_F(ProxyResolutionServiceTest, PerProtocolProxyTests) {
ProxyConfig config;
config.proxy_rules().ParseFromString("http=foopy1:8080;https=foopy2:8080");
config.set_auto_detect(false);
@@ -1629,13 +1635,12 @@ TEST_F(ProxyServiceTest, PerProtocolProxyTests) {
}
}
-TEST_F(ProxyServiceTest, ProxyConfigSourcePropagates) {
+TEST_F(ProxyResolutionServiceTest, ProxyConfigTrafficAnnotationPropagates) {
// Test that the proxy config source is set correctly when resolving proxies
// using manual proxy rules. Namely, the config source should only be set if
// any of the rules were applied.
{
ProxyConfig config;
- config.set_source(PROXY_CONFIG_SOURCE_TEST);
config.proxy_rules().ParseFromString("https=foopy2:8080");
ProxyResolutionService service(
std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);
@@ -1646,12 +1651,12 @@ TEST_F(ProxyServiceTest, ProxyConfigSourcePropagates) {
callback.callback(), nullptr, nullptr,
NetLogWithSource());
ASSERT_THAT(rv, IsOk());
- // Should be SOURCE_TEST, even if there are no HTTP proxies configured.
- EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
+ // Should be test, even if there are no HTTP proxies configured.
+ EXPECT_EQ(MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
+ info.traffic_annotation());
}
{
ProxyConfig config;
- config.set_source(PROXY_CONFIG_SOURCE_TEST);
config.proxy_rules().ParseFromString("https=foopy2:8080");
ProxyResolutionService service(
std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);
@@ -1662,12 +1667,12 @@ TEST_F(ProxyServiceTest, ProxyConfigSourcePropagates) {
callback.callback(), nullptr, nullptr,
NetLogWithSource());
ASSERT_THAT(rv, IsOk());
- // Used the HTTPS proxy. So source should be TEST.
- EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
+ // Used the HTTPS proxy. So traffic annotation should test.
+ EXPECT_EQ(MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
+ info.traffic_annotation());
}
{
ProxyConfig config;
- config.set_source(PROXY_CONFIG_SOURCE_TEST);
ProxyResolutionService service(
std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);
GURL test_url("http://www.google.com");
@@ -1677,14 +1682,15 @@ TEST_F(ProxyServiceTest, ProxyConfigSourcePropagates) {
callback.callback(), nullptr, nullptr,
NetLogWithSource());
ASSERT_THAT(rv, IsOk());
- // ProxyConfig is empty. Source should still be TEST.
- EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
+ // ProxyConfig is empty. Traffic annotation should still be TEST.
+ EXPECT_EQ(MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
+ info.traffic_annotation());
}
}
// If only HTTP and a SOCKS proxy are specified, check if ftp/https queries
// fall back to the SOCKS proxy.
-TEST_F(ProxyServiceTest, DefaultProxyFallbackToSOCKS) {
+TEST_F(ProxyResolutionServiceTest, DefaultProxyFallbackToSOCKS) {
ProxyConfig config;
config.proxy_rules().ParseFromString("http=foopy1:8080;socks=foopy2:1080");
config.set_auto_detect(false);
@@ -1746,7 +1752,7 @@ TEST_F(ProxyServiceTest, DefaultProxyFallbackToSOCKS) {
}
// Test cancellation of an in-progress request.
-TEST_F(ProxyServiceTest, CancelInProgressRequest) {
+TEST_F(ProxyResolutionServiceTest, CancelInProgressRequest) {
const GURL url1("http://request1");
const GURL url2("http://request2");
const GURL url3("http://request3");
@@ -1816,7 +1822,7 @@ TEST_F(ProxyServiceTest, CancelInProgressRequest) {
}
// Test the initial PAC download for resolver that expects bytes.
-TEST_F(ProxyServiceTest, InitialPACScriptDownload) {
+TEST_F(ProxyResolutionServiceTest, InitialPACScriptDownload) {
const GURL url1("http://request1");
const GURL url2("http://request2");
const GURL url3("http://request3");
@@ -1830,10 +1836,9 @@ TEST_F(ProxyServiceTest, InitialPACScriptDownload) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), nullptr);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
// Start 3 requests.
@@ -1866,15 +1871,12 @@ TEST_F(ProxyServiceTest, InitialPACScriptDownload) {
// Nothing has been sent to the factory yet.
EXPECT_TRUE(factory->pending_requests().empty());
- EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
- service.GetLoadState(request1));
- EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
- service.GetLoadState(request2));
- EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
- service.GetLoadState(request3));
+ EXPECT_EQ(LOAD_STATE_DOWNLOADING_PAC_FILE, service.GetLoadState(request1));
+ EXPECT_EQ(LOAD_STATE_DOWNLOADING_PAC_FILE, service.GetLoadState(request2));
+ EXPECT_EQ(LOAD_STATE_DOWNLOADING_PAC_FILE, service.GetLoadState(request3));
// At this point the ProxyResolutionService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
+ // PacFileFetcher to invoke its completion callback, notifying it of
// PAC script download completion.
fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
@@ -1924,8 +1926,9 @@ TEST_F(ProxyServiceTest, InitialPACScriptDownload) {
EXPECT_LE(info3.proxy_resolve_start_time(), info3.proxy_resolve_end_time());
}
-// Test changing the ProxyScriptFetcher while PAC download is in progress.
-TEST_F(ProxyServiceTest, ChangeScriptFetcherWhilePACDownloadInProgress) {
+// Test changing the PacFileFetcher while PAC download is in progress.
+TEST_F(ProxyResolutionServiceTest,
+ ChangeScriptFetcherWhilePACDownloadInProgress) {
const GURL url1("http://request1");
const GURL url2("http://request2");
MockProxyConfigService* config_service =
@@ -1938,10 +1941,9 @@ TEST_F(ProxyServiceTest, ChangeScriptFetcherWhilePACDownloadInProgress) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), nullptr);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
// Start 2 jobs.
@@ -1963,16 +1965,15 @@ TEST_F(ProxyServiceTest, ChangeScriptFetcherWhilePACDownloadInProgress) {
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
// At this point the ProxyResolutionService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
+ // PacFileFetcher to invoke its completion callback, notifying it of
// PAC script download completion.
// We now change out the ProxyResolutionService's script fetcher. We should
// restart the initialization with the new fetcher.
- fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
// Nothing has been sent to the factory yet.
EXPECT_TRUE(factory->pending_requests().empty());
@@ -1989,7 +1990,7 @@ TEST_F(ProxyServiceTest, ChangeScriptFetcherWhilePACDownloadInProgress) {
}
// Test cancellation of a request, while the PAC script is being fetched.
-TEST_F(ProxyServiceTest, CancelWhilePACFetching) {
+TEST_F(ProxyResolutionServiceTest, CancelWhilePACFetching) {
MockProxyConfigService* config_service =
new MockProxyConfigService("http://foopy/proxy.pac");
@@ -2000,10 +2001,9 @@ TEST_F(ProxyServiceTest, CancelWhilePACFetching) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), nullptr);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
// Start 3 requests.
ProxyInfo info1;
@@ -2042,7 +2042,7 @@ TEST_F(ProxyServiceTest, CancelWhilePACFetching) {
service.CancelRequest(request2);
// At this point the ProxyResolutionService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
+ // PacFileFetcher to invoke its completion callback, notifying it of
// PAC script download completion.
fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
@@ -2072,19 +2072,21 @@ TEST_F(ProxyServiceTest, CancelWhilePACFetching) {
// Check the NetLog for request 1 (which was cancelled) got filled properly.
EXPECT_EQ(4u, entries1.size());
- EXPECT_TRUE(
- LogContainsBeginEvent(entries1, 0, NetLogEventType::PROXY_SERVICE));
+ EXPECT_TRUE(LogContainsBeginEvent(entries1, 0,
+ NetLogEventType::PROXY_RESOLUTION_SERVICE));
EXPECT_TRUE(LogContainsBeginEvent(
- entries1, 1, NetLogEventType::PROXY_SERVICE_WAITING_FOR_INIT_PAC));
- // Note that PROXY_SERVICE_WAITING_FOR_INIT_PAC is never completed before
- // the cancellation occured.
+ entries1, 1,
+ NetLogEventType::PROXY_RESOLUTION_SERVICE_WAITING_FOR_INIT_PAC));
+ // Note that PROXY_RESOLUTION_SERVICE_WAITING_FOR_INIT_PAC is never completed
+ // before the cancellation occured.
EXPECT_TRUE(LogContainsEvent(entries1, 2, NetLogEventType::CANCELLED,
NetLogEventPhase::NONE));
- EXPECT_TRUE(LogContainsEndEvent(entries1, 3, NetLogEventType::PROXY_SERVICE));
+ EXPECT_TRUE(LogContainsEndEvent(entries1, 3,
+ NetLogEventType::PROXY_RESOLUTION_SERVICE));
}
// Test that if auto-detect fails, we fall-back to the custom pac.
-TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac) {
+TEST_F(ProxyResolutionServiceTest, FallbackFromAutodetectToCustomPac) {
const GURL url1("http://request1");
const GURL url2("http://request2");
ProxyConfig config;
@@ -2099,10 +2101,9 @@ TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), nullptr);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
// Start 2 requests.
@@ -2168,7 +2169,7 @@ TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac) {
// This is the same test as FallbackFromAutodetectToCustomPac, except
// the auto-detect script fails parsing rather than downloading.
-TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac2) {
+TEST_F(ProxyResolutionServiceTest, FallbackFromAutodetectToCustomPac2) {
const GURL url1("http://request1");
const GURL url2("http://request2");
ProxyConfig config;
@@ -2183,10 +2184,9 @@ TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac2) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), nullptr);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
// Start 2 requests.
@@ -2248,7 +2248,7 @@ TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac2) {
// Test that if all of auto-detect, a custom PAC script, and manual settings
// are given, then we will try them in that order.
-TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomToManual) {
+TEST_F(ProxyResolutionServiceTest, FallbackFromAutodetectToCustomToManual) {
ProxyConfig config;
config.set_auto_detect(true);
config.set_pac_url(GURL("http://foopy/proxy.pac"));
@@ -2260,10 +2260,9 @@ TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomToManual) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), nullptr);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
// Start 2 jobs.
@@ -2309,7 +2308,7 @@ TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomToManual) {
}
// Test that the bypass rules are NOT applied when using autodetect.
-TEST_F(ProxyServiceTest, BypassDoesntApplyToPac) {
+TEST_F(ProxyResolutionServiceTest, BypassDoesntApplyToPac) {
ProxyConfig config;
config.set_auto_detect(true);
config.set_pac_url(GURL("http://foopy/proxy.pac"));
@@ -2323,10 +2322,9 @@ TEST_F(ProxyServiceTest, BypassDoesntApplyToPac) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), nullptr);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
// Start 1 requests.
@@ -2381,9 +2379,10 @@ TEST_F(ProxyServiceTest, BypassDoesntApplyToPac) {
// Delete the ProxyResolutionService while InitProxyResolver has an outstanding
// request to the script fetcher. When run under valgrind, should not
-// have any memory errors (used to be that the ProxyScriptFetcher was
+// have any memory errors (used to be that the PacFileFetcher was
// being deleted prior to the InitProxyResolver).
-TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingFetch) {
+TEST_F(ProxyResolutionServiceTest,
+ DeleteWhileInitProxyResolverHasOutstandingFetch) {
ProxyConfig config =
ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
@@ -2393,10 +2392,9 @@ TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingFetch) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), nullptr);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
// Start 1 request.
@@ -2410,7 +2408,7 @@ TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingFetch) {
// Check that nothing has been sent to the proxy resolver factory yet.
ASSERT_EQ(0u, factory->pending_requests().size());
- // InitProxyResolver should have issued a request to the ProxyScriptFetcher
+ // InitProxyResolver should have issued a request to the PacFileFetcher
// and be waiting on that to complete.
EXPECT_TRUE(fetcher->has_pending_request());
EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
@@ -2420,7 +2418,8 @@ TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingFetch) {
// request to the proxy resolver. When run under valgrind, should not
// have any memory errors (used to be that the ProxyResolver was
// being deleted prior to the InitProxyResolver).
-TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingSet) {
+TEST_F(ProxyResolutionServiceTest,
+ DeleteWhileInitProxyResolverHasOutstandingSet) {
MockProxyConfigService* config_service =
new MockProxyConfigService("http://foopy/proxy.pac");
@@ -2442,7 +2441,7 @@ TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingSet) {
factory->pending_requests()[0]->script_data()->url());
}
-TEST_F(ProxyServiceTest, ResetProxyConfigService) {
+TEST_F(ProxyResolutionServiceTest, ResetProxyConfigService) {
ProxyConfig config1;
config1.proxy_rules().ParseFromString("foopy1:8080");
config1.set_auto_detect(false);
@@ -2471,7 +2470,7 @@ TEST_F(ProxyServiceTest, ResetProxyConfigService) {
// Test that when going from a configuration that required PAC to one
// that does NOT, we unset the variable |should_use_proxy_resolver_|.
-TEST_F(ProxyServiceTest, UpdateConfigFromPACToDirect) {
+TEST_F(ProxyResolutionServiceTest, UpdateConfigFromPACToDirect) {
ProxyConfig config = ProxyConfig::CreateAutoDetect();
MockProxyConfigService* config_service = new MockProxyConfigService(config);
@@ -2491,7 +2490,7 @@ TEST_F(ProxyServiceTest, UpdateConfigFromPACToDirect) {
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
// Successfully set the autodetect script.
- EXPECT_EQ(ProxyResolverScriptData::TYPE_AUTO_DETECT,
+ EXPECT_EQ(PacFileData::TYPE_AUTO_DETECT,
factory->pending_requests()[0]->script_data()->type());
factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);
@@ -2509,7 +2508,7 @@ TEST_F(ProxyServiceTest, UpdateConfigFromPACToDirect) {
//
// This new configuration no longer has auto_detect set, so
// jobs should complete synchronously now as direct-connect.
- config_service->SetConfig(ProxyConfig::CreateDirect());
+ config_service->SetConfig(ProxyConfigWithAnnotation::CreateDirect());
// Start another request -- the effective configuration has changed.
ProxyInfo info2;
@@ -2522,7 +2521,7 @@ TEST_F(ProxyServiceTest, UpdateConfigFromPACToDirect) {
EXPECT_TRUE(info2.is_direct());
}
-TEST_F(ProxyServiceTest, NetworkChangeTriggersPacRefetch) {
+TEST_F(ProxyResolutionServiceTest, NetworkChangeTriggersPacRefetch) {
MockProxyConfigService* config_service =
new MockProxyConfigService("http://foopy/proxy.pac");
@@ -2535,10 +2534,9 @@ TEST_F(ProxyServiceTest, NetworkChangeTriggersPacRefetch) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), &log);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
// Disable the "wait after IP address changes" hack, so this unit-test can
// complete quickly.
@@ -2561,7 +2559,7 @@ TEST_F(ProxyServiceTest, NetworkChangeTriggersPacRefetch) {
EXPECT_TRUE(factory->pending_requests().empty());
// At this point the ProxyResolutionService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
+ // PacFileFetcher to invoke its completion callback, notifying it of
// PAC script download completion.
fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
@@ -2642,7 +2640,7 @@ TEST_F(ProxyServiceTest, NetworkChangeTriggersPacRefetch) {
// periodically polled for changes. Specifically, if the initial fetch fails due
// to a network error, we will eventually re-configure the service to use the
// script once it becomes available.
-TEST_F(ProxyServiceTest, PACScriptRefetchAfterFailure) {
+TEST_F(ProxyResolutionServiceTest, PACScriptRefetchAfterFailure) {
// Change the retry policy to wait a mere 1 ms before retrying, so the test
// runs quickly.
ImmediatePollPolicy poll_policy;
@@ -2658,10 +2656,9 @@ TEST_F(ProxyServiceTest, PACScriptRefetchAfterFailure) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), nullptr);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
// Start 1 request.
@@ -2680,7 +2677,7 @@ TEST_F(ProxyServiceTest, PACScriptRefetchAfterFailure) {
EXPECT_TRUE(factory->pending_requests().empty());
// At this point the ProxyResolutionService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
+ // PacFileFetcher to invoke its completion callback, notifying it of
// PAC script download completion.
//
// We simulate a failed download attempt, the proxy service should now
@@ -2750,7 +2747,7 @@ TEST_F(ProxyServiceTest, PACScriptRefetchAfterFailure) {
// periodically polled for changes. Specifically, if the initial fetch succeeds,
// however at a later time its *contents* change, we will eventually
// re-configure the service to use the new script.
-TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentChange) {
+TEST_F(ProxyResolutionServiceTest, PACScriptRefetchAfterContentChange) {
// Change the retry policy to wait a mere 1 ms before retrying, so the test
// runs quickly.
ImmediatePollPolicy poll_policy;
@@ -2766,10 +2763,9 @@ TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentChange) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), nullptr);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
// Start 1 request.
@@ -2788,7 +2784,7 @@ TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentChange) {
EXPECT_TRUE(factory->pending_requests().empty());
// At this point the ProxyResolutionService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
+ // PacFileFetcher to invoke its completion callback, notifying it of
// PAC script download completion.
fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
@@ -2864,7 +2860,7 @@ TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentChange) {
// periodically polled for changes. Specifically, if the initial fetch succeeds
// and so does the next poll, however the contents of the downloaded script
// have NOT changed, then we do not bother to re-initialize the proxy resolver.
-TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentUnchanged) {
+TEST_F(ProxyResolutionServiceTest, PACScriptRefetchAfterContentUnchanged) {
// Change the retry policy to wait a mere 1 ms before retrying, so the test
// runs quickly.
ImmediatePollPolicy poll_policy;
@@ -2880,10 +2876,9 @@ TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentUnchanged) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), nullptr);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
// Start 1 request.
@@ -2902,7 +2897,7 @@ TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentUnchanged) {
EXPECT_TRUE(factory->pending_requests().empty());
// At this point the ProxyResolutionService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
+ // PacFileFetcher to invoke its completion callback, notifying it of
// PAC script download completion.
fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
@@ -2975,7 +2970,7 @@ TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentUnchanged) {
// periodically polled for changes. Specifically, if the initial fetch succeeds,
// however at a later time it starts to fail, we should re-configure the
// ProxyResolutionService to stop using that PAC script.
-TEST_F(ProxyServiceTest, PACScriptRefetchAfterSuccess) {
+TEST_F(ProxyResolutionServiceTest, PACScriptRefetchAfterSuccess) {
// Change the retry policy to wait a mere 1 ms before retrying, so the test
// runs quickly.
ImmediatePollPolicy poll_policy;
@@ -2991,10 +2986,9 @@ TEST_F(ProxyServiceTest, PACScriptRefetchAfterSuccess) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), nullptr);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
// Start 1 request.
@@ -3013,7 +3007,7 @@ TEST_F(ProxyServiceTest, PACScriptRefetchAfterSuccess) {
EXPECT_TRUE(factory->pending_requests().empty());
// At this point the ProxyResolutionService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
+ // PacFileFetcher to invoke its completion callback, notifying it of
// PAC script download completion.
fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
@@ -3070,7 +3064,7 @@ TEST_F(ProxyServiceTest, PACScriptRefetchAfterSuccess) {
// Tests that the code which decides at what times to poll the PAC
// script follows the expected policy.
-TEST_F(ProxyServiceTest, PACScriptPollingPolicy) {
+TEST_F(ProxyResolutionServiceTest, PACScriptPollingPolicy) {
// Retrieve the internal polling policy implementation used by
// ProxyResolutionService.
std::unique_ptr<ProxyResolutionService::PacPollPolicy> policy =
@@ -3141,7 +3135,7 @@ TEST_F(ProxyServiceTest, PACScriptPollingPolicy) {
// This tests the polling of the PAC script. Specifically, it tests that
// polling occurs in response to user activity.
-TEST_F(ProxyServiceTest, PACScriptRefetchAfterActivity) {
+TEST_F(ProxyResolutionServiceTest, PACScriptRefetchAfterActivity) {
ImmediateAfterActivityPollPolicy poll_policy;
ProxyResolutionService::set_pac_script_poll_policy(&poll_policy);
@@ -3155,10 +3149,9 @@ TEST_F(ProxyServiceTest, PACScriptRefetchAfterActivity) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), nullptr);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
// Start 1 request.
@@ -3177,7 +3170,7 @@ TEST_F(ProxyServiceTest, PACScriptRefetchAfterActivity) {
EXPECT_TRUE(factory->pending_requests().empty());
// At this point the ProxyResolutionService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
+ // PacFileFetcher to invoke its completion callback, notifying it of
// PAC script download completion.
fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
@@ -3248,7 +3241,7 @@ TEST_F(ProxyServiceTest, PACScriptRefetchAfterActivity) {
}
// Test that the synchronous resolution fails when a PAC script is active.
-TEST_F(ProxyServiceTest, SynchronousWithPAC) {
+TEST_F(ProxyResolutionServiceTest, SynchronousWithPAC) {
MockProxyConfigService* config_service =
new MockProxyConfigService("http://foopy/proxy.pac");
@@ -3274,7 +3267,7 @@ TEST_F(ProxyServiceTest, SynchronousWithPAC) {
// Test that synchronous results are returned correctly if a fixed proxy
// configuration is active.
-TEST_F(ProxyServiceTest, SynchronousWithFixedConfiguration) {
+TEST_F(ProxyResolutionServiceTest, SynchronousWithFixedConfiguration) {
ProxyConfig config;
config.proxy_rules().ParseFromString("foopy1:8080");
config.set_auto_detect(false);
@@ -3386,7 +3379,7 @@ class SanitizeUrlHelper {
std::unique_ptr<ProxyResolutionService> service_;
};
-TEST_F(ProxyServiceTest, SanitizeUrlDefaultsToSafe) {
+TEST_F(ProxyResolutionServiceTest, SanitizeUrlDefaultsToSafe) {
SanitizeUrlHelper helper;
// Without changing the URL sanitization policy, the default should be to
@@ -3399,7 +3392,7 @@ TEST_F(ProxyServiceTest, SanitizeUrlDefaultsToSafe) {
// Tests URL sanitization with input URLs that have a // non-cryptographic
// scheme (i.e. http://). The sanitized result is consistent regardless of the
// stripping mode selected.
-TEST_F(ProxyServiceTest, SanitizeUrlForPacScriptNonCryptographic) {
+TEST_F(ProxyResolutionServiceTest, SanitizeUrlForPacScriptNonCryptographic) {
const struct {
const char* raw_url;
const char* sanitized_url;
@@ -3458,7 +3451,7 @@ TEST_F(ProxyServiceTest, SanitizeUrlForPacScriptNonCryptographic) {
// Tests URL sanitization using input URLs that have a cryptographic schemes
// (i.e. https://). The sanitized result differs depending on the sanitization
// mode chosen.
-TEST_F(ProxyServiceTest, SanitizeUrlForPacScriptCryptographic) {
+TEST_F(ProxyResolutionServiceTest, SanitizeUrlForPacScriptCryptographic) {
const struct {
// Input URL.
const char* raw_url;
@@ -3521,7 +3514,7 @@ TEST_F(ProxyServiceTest, SanitizeUrlForPacScriptCryptographic) {
}
}
-TEST_F(ProxyServiceTest, OnShutdownWithLiveRequest) {
+TEST_F(ProxyResolutionServiceTest, OnShutdownWithLiveRequest) {
MockProxyConfigService* config_service =
new MockProxyConfigService("http://foopy/proxy.pac");
@@ -3532,10 +3525,9 @@ TEST_F(ProxyServiceTest, OnShutdownWithLiveRequest) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), nullptr);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
ProxyInfo info;
TestCompletionCallback callback;
@@ -3555,7 +3547,7 @@ TEST_F(ProxyServiceTest, OnShutdownWithLiveRequest) {
EXPECT_TRUE(info.is_direct());
}
-TEST_F(ProxyServiceTest, OnShutdownFollowedByRequest) {
+TEST_F(ProxyResolutionServiceTest, OnShutdownFollowedByRequest) {
MockProxyConfigService* config_service =
new MockProxyConfigService("http://foopy/proxy.pac");
@@ -3566,10 +3558,9 @@ TEST_F(ProxyServiceTest, OnShutdownFollowedByRequest) {
ProxyResolutionService service(base::WrapUnique(config_service),
base::WrapUnique(factory), nullptr);
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(
- base::WrapUnique(fetcher),
- std::make_unique<DoNothingDhcpProxyScriptFetcher>());
+ MockPacFileFetcher* fetcher = new MockPacFileFetcher;
+ service.SetPacFileFetchers(base::WrapUnique(fetcher),
+ std::make_unique<DoNothingDhcpPacFileFetcher>());
service.OnShutdown();
diff --git a/chromium/net/proxy_resolution/proxy_resolver_factory.h b/chromium/net/proxy_resolution/proxy_resolver_factory.h
index 7a9b66c5d10..ea229aea838 100644
--- a/chromium/net/proxy_resolution/proxy_resolver_factory.h
+++ b/chromium/net/proxy_resolution/proxy_resolver_factory.h
@@ -38,15 +38,14 @@ class NET_EXPORT ProxyResolverFactory {
// case of asynchronous completion |*request| is written to, and can be
// deleted to cancel the request. All requests in progress are cancelled if
// the ProxyResolverFactory is deleted.
- virtual int CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
- std::unique_ptr<ProxyResolver>* resolver,
- const net::CompletionCallback& callback,
- std::unique_ptr<Request>* request) = 0;
+ virtual int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
+ std::unique_ptr<ProxyResolver>* resolver,
+ const net::CompletionCallback& callback,
+ std::unique_ptr<Request>* request) = 0;
// The PAC script backend can be specified to the ProxyResolverFactory either
// via URL, or via the javascript text itself. If |expects_pac_bytes| is true,
- // then the ProxyResolverScriptData passed to CreateProxyResolver() should
+ // then the PacFileData passed to CreateProxyResolver() should
// contain the actual script bytes rather than just the URL.
bool expects_pac_bytes() const { return expects_pac_bytes_; }
diff --git a/chromium/net/proxy_resolution/proxy_resolver_mac.cc b/chromium/net/proxy_resolution/proxy_resolver_mac.cc
index 6d13cbd72af..8570f984668 100644
--- a/chromium/net/proxy_resolution/proxy_resolver_mac.cc
+++ b/chromium/net/proxy_resolution/proxy_resolver_mac.cc
@@ -183,8 +183,7 @@ void RunLoopObserverCallBackFunc(CFRunLoopObserverRef observer,
#pragma mark - ProxyResolverMac
class ProxyResolverMac : public ProxyResolver {
public:
- explicit ProxyResolverMac(
- const scoped_refptr<ProxyResolverScriptData>& script_data);
+ explicit ProxyResolverMac(const scoped_refptr<PacFileData>& script_data);
~ProxyResolverMac() override;
// ProxyResolver methods:
@@ -195,13 +194,12 @@ class ProxyResolverMac : public ProxyResolver {
const NetLogWithSource& net_log) override;
private:
- const scoped_refptr<ProxyResolverScriptData> script_data_;
+ const scoped_refptr<PacFileData> script_data_;
};
ProxyResolverMac::ProxyResolverMac(
- const scoped_refptr<ProxyResolverScriptData>& script_data)
- : script_data_(script_data) {
-}
+ const scoped_refptr<PacFileData>& script_data)
+ : script_data_(script_data) {}
ProxyResolverMac::~ProxyResolverMac() {}
@@ -219,7 +217,7 @@ int ProxyResolverMac::GetProxyForURL(const GURL& query_url,
if (!query_url_ref.get())
return ERR_FAILED;
base::ScopedCFTypeRef<CFStringRef> pac_ref(base::SysUTF8ToCFStringRef(
- script_data_->type() == ProxyResolverScriptData::TYPE_AUTO_DETECT
+ script_data_->type() == PacFileData::TYPE_AUTO_DETECT
? std::string()
: script_data_->url().spec()));
base::ScopedCFTypeRef<CFURLRef> pac_url_ref(
@@ -345,7 +343,7 @@ ProxyResolverFactoryMac::ProxyResolverFactoryMac()
}
int ProxyResolverFactoryMac::CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
+ const scoped_refptr<PacFileData>& pac_script,
std::unique_ptr<ProxyResolver>* resolver,
const CompletionCallback& callback,
std::unique_ptr<Request>* request) {
diff --git a/chromium/net/proxy_resolution/proxy_resolver_mac.h b/chromium/net/proxy_resolution/proxy_resolver_mac.h
index 866bb1a4e6c..3577dc2cb68 100644
--- a/chromium/net/proxy_resolution/proxy_resolver_mac.h
+++ b/chromium/net/proxy_resolution/proxy_resolver_mac.h
@@ -21,11 +21,10 @@ class NET_EXPORT ProxyResolverFactoryMac : public ProxyResolverFactory {
public:
ProxyResolverFactoryMac();
- int CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
- std::unique_ptr<ProxyResolver>* resolver,
- const CompletionCallback& callback,
- std::unique_ptr<Request>* request) override;
+ int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
+ std::unique_ptr<ProxyResolver>* resolver,
+ const CompletionCallback& callback,
+ std::unique_ptr<Request>* request) override;
private:
DISALLOW_COPY_AND_ASSIGN(ProxyResolverFactoryMac);
diff --git a/chromium/net/proxy_resolution/proxy_resolver_v8.cc b/chromium/net/proxy_resolution/proxy_resolver_v8.cc
index 71072ea8e81..7eee9c429c0 100644
--- a/chromium/net/proxy_resolution/proxy_resolver_v8.cc
+++ b/chromium/net/proxy_resolution/proxy_resolver_v8.cc
@@ -89,12 +89,12 @@ const char kPacResourceName[] = "proxy-pac-script.js";
const char kPacUtilityResourceName[] = "proxy-pac-utility-script.js";
// External string wrapper so V8 can access the UTF16 string wrapped by
-// ProxyResolverScriptData.
+// PacFileData.
class V8ExternalStringFromScriptData
: public v8::String::ExternalStringResource {
public:
explicit V8ExternalStringFromScriptData(
- const scoped_refptr<ProxyResolverScriptData>& script_data)
+ const scoped_refptr<PacFileData>& script_data)
: script_data_(script_data) {}
const uint16_t* data() const override {
@@ -104,7 +104,7 @@ class V8ExternalStringFromScriptData
size_t length() const override { return script_data_->utf16().size(); }
private:
- const scoped_refptr<ProxyResolverScriptData> script_data_;
+ const scoped_refptr<PacFileData> script_data_;
DISALLOW_COPY_AND_ASSIGN(V8ExternalStringFromScriptData);
};
@@ -166,10 +166,11 @@ v8::Local<v8::String> ASCIIStringToV8String(v8::Isolate* isolate,
s.size()).ToLocalChecked();
}
-// Converts a UTF16 base::string16 (warpped by a ProxyResolverScriptData) to a
+// Converts a UTF16 base::string16 (wrapped by a PacFileData) to a
// V8 string.
v8::Local<v8::String> ScriptDataToV8String(
- v8::Isolate* isolate, const scoped_refptr<ProxyResolverScriptData>& s) {
+ v8::Isolate* isolate,
+ const scoped_refptr<PacFileData>& s) {
if (s->utf16().size() * 2 <= kMaxStringBytesForCopy) {
return v8::String::NewFromTwoByte(
isolate, reinterpret_cast<const uint16_t*>(s->utf16().data()),
@@ -492,7 +493,7 @@ class ProxyResolverV8::Context {
return OK;
}
- int InitV8(const scoped_refptr<ProxyResolverScriptData>& pac_script,
+ int InitV8(const scoped_refptr<PacFileData>& pac_script,
JSBindings* bindings) {
base::AutoReset<JSBindings*> bindings_reset(&js_bindings_, bindings);
v8::Locker locked(isolate_);
@@ -860,10 +861,9 @@ int ProxyResolverV8::GetProxyForURL(const GURL& query_url,
}
// static
-int ProxyResolverV8::Create(
- const scoped_refptr<ProxyResolverScriptData>& script_data,
- ProxyResolverV8::JSBindings* js_bindings,
- std::unique_ptr<ProxyResolverV8>* resolver) {
+int ProxyResolverV8::Create(const scoped_refptr<PacFileData>& script_data,
+ ProxyResolverV8::JSBindings* js_bindings,
+ std::unique_ptr<ProxyResolverV8>* resolver) {
DCHECK(script_data.get());
DCHECK(js_bindings);
diff --git a/chromium/net/proxy_resolution/proxy_resolver_v8.h b/chromium/net/proxy_resolution/proxy_resolver_v8.h
index 2b391c4df69..58490f82c34 100644
--- a/chromium/net/proxy_resolution/proxy_resolver_v8.h
+++ b/chromium/net/proxy_resolution/proxy_resolver_v8.h
@@ -19,7 +19,7 @@ class GURL;
namespace net {
class ProxyInfo;
-class ProxyResolverScriptData;
+class PacFileData;
// A synchronous ProxyResolver-like that uses V8 to evaluate PAC scripts.
class NET_EXPORT_PRIVATE ProxyResolverV8 {
@@ -57,7 +57,7 @@ class NET_EXPORT_PRIVATE ProxyResolverV8 {
};
// Constructs a ProxyResolverV8.
- static int Create(const scoped_refptr<ProxyResolverScriptData>& script_data,
+ static int Create(const scoped_refptr<PacFileData>& script_data,
JSBindings* bindings,
std::unique_ptr<ProxyResolverV8>* resolver);
diff --git a/chromium/net/proxy_resolution/proxy_resolver_v8_tracing.cc b/chromium/net/proxy_resolution/proxy_resolver_v8_tracing.cc
index fbd268e9cb5..8b96c07fbb9 100644
--- a/chromium/net/proxy_resolution/proxy_resolver_v8_tracing.cc
+++ b/chromium/net/proxy_resolution/proxy_resolver_v8_tracing.cc
@@ -99,10 +99,9 @@ class Job : public base::RefCountedThreadSafe<Job>,
std::unique_ptr<ProxyResolverV8Tracing::Bindings> bindings);
// Called from origin thread.
- void StartCreateV8Resolver(
- const scoped_refptr<ProxyResolverScriptData>& script_data,
- std::unique_ptr<ProxyResolverV8>* resolver,
- const CompletionCallback& callback);
+ void StartCreateV8Resolver(const scoped_refptr<PacFileData>& script_data,
+ std::unique_ptr<ProxyResolverV8>* resolver,
+ const CompletionCallback& callback);
// Called from origin thread.
void StartGetProxyForURL(const GURL& url,
@@ -246,7 +245,7 @@ class Job : public base::RefCountedThreadSafe<Job>,
// State specific to CREATE_V8_RESOLVER.
// -------------------------------------------------------
- scoped_refptr<ProxyResolverScriptData> script_data_;
+ scoped_refptr<PacFileData> script_data_;
std::unique_ptr<ProxyResolverV8>* resolver_out_;
// -------------------------------------------------------
@@ -353,10 +352,9 @@ Job::Job(const Job::Params* params,
CheckIsOnOriginThread();
}
-void Job::StartCreateV8Resolver(
- const scoped_refptr<ProxyResolverScriptData>& script_data,
- std::unique_ptr<ProxyResolverV8>* resolver,
- const CompletionCallback& callback) {
+void Job::StartCreateV8Resolver(const scoped_refptr<PacFileData>& script_data,
+ std::unique_ptr<ProxyResolverV8>* resolver,
+ const CompletionCallback& callback) {
CheckIsOnOriginThread();
resolver_out_ = resolver;
@@ -423,7 +421,7 @@ LoadState Job::GetLoadState() const {
CheckIsOnOriginThread();
if (pending_dns_)
- return LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT;
+ return LOAD_STATE_RESOLVING_HOST_IN_PAC_FILE;
return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
}
@@ -986,7 +984,7 @@ class ProxyResolverV8TracingFactoryImpl : public ProxyResolverV8TracingFactory {
~ProxyResolverV8TracingFactoryImpl() override;
void CreateProxyResolverV8Tracing(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
+ const scoped_refptr<PacFileData>& pac_script,
std::unique_ptr<ProxyResolverV8Tracing::Bindings> bindings,
std::unique_ptr<ProxyResolverV8Tracing>* resolver,
const CompletionCallback& callback,
@@ -1007,7 +1005,7 @@ class ProxyResolverV8TracingFactoryImpl::CreateJob
public:
CreateJob(ProxyResolverV8TracingFactoryImpl* factory,
std::unique_ptr<ProxyResolverV8Tracing::Bindings> bindings,
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
+ const scoped_refptr<PacFileData>& pac_script,
std::unique_ptr<ProxyResolverV8Tracing>* resolver_out,
const CompletionCallback& callback)
: factory_(factory),
@@ -1091,7 +1089,7 @@ ProxyResolverV8TracingFactoryImpl::~ProxyResolverV8TracingFactoryImpl() {
}
void ProxyResolverV8TracingFactoryImpl::CreateProxyResolverV8Tracing(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
+ const scoped_refptr<PacFileData>& pac_script,
std::unique_ptr<ProxyResolverV8Tracing::Bindings> bindings,
std::unique_ptr<ProxyResolverV8Tracing>* resolver,
const CompletionCallback& callback,
diff --git a/chromium/net/proxy_resolution/proxy_resolver_v8_tracing.h b/chromium/net/proxy_resolution/proxy_resolver_v8_tracing.h
index e95812ec88c..7decd2c2bbd 100644
--- a/chromium/net/proxy_resolution/proxy_resolver_v8_tracing.h
+++ b/chromium/net/proxy_resolution/proxy_resolver_v8_tracing.h
@@ -72,7 +72,7 @@ class NET_EXPORT ProxyResolverV8TracingFactory {
virtual ~ProxyResolverV8TracingFactory() = default;
virtual void CreateProxyResolverV8Tracing(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
+ const scoped_refptr<PacFileData>& pac_script,
std::unique_ptr<ProxyResolverV8Tracing::Bindings> bindings,
std::unique_ptr<ProxyResolverV8Tracing>* resolver,
const CompletionCallback& callback,
diff --git a/chromium/net/proxy_resolution/proxy_resolver_v8_tracing_unittest.cc b/chromium/net/proxy_resolution/proxy_resolver_v8_tracing_unittest.cc
index 22e05463abe..090f4acd939 100644
--- a/chromium/net/proxy_resolution/proxy_resolver_v8_tracing_unittest.cc
+++ b/chromium/net/proxy_resolution/proxy_resolver_v8_tracing_unittest.cc
@@ -44,7 +44,7 @@ class ProxyResolverV8TracingTest : public testing::Test {
}
};
-scoped_refptr<ProxyResolverScriptData> LoadScriptData(const char* filename) {
+scoped_refptr<PacFileData> LoadScriptData(const char* filename) {
base::FilePath path;
PathService::Get(base::DIR_SOURCE_ROOT, &path);
path = path.AppendASCII("net");
@@ -60,7 +60,7 @@ scoped_refptr<ProxyResolverScriptData> LoadScriptData(const char* filename) {
EXPECT_TRUE(ok) << "Failed to read file: " << path.value();
// Load the PAC script into the ProxyResolver.
- return ProxyResolverScriptData::FromUTF8(file_contents);
+ return PacFileData::FromUTF8(file_contents);
}
class MockBindings {
diff --git a/chromium/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper.cc b/chromium/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper.cc
index abe633816c1..cef1b8adf39 100644
--- a/chromium/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper.cc
+++ b/chromium/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper.cc
@@ -147,7 +147,7 @@ ProxyResolverFactoryV8TracingWrapper::~ProxyResolverFactoryV8TracingWrapper() =
default;
int ProxyResolverFactoryV8TracingWrapper::CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
+ const scoped_refptr<PacFileData>& pac_script,
std::unique_ptr<ProxyResolver>* resolver,
const CompletionCallback& callback,
std::unique_ptr<Request>* request) {
diff --git a/chromium/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper.h b/chromium/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper.h
index e5a170b0651..b7423063602 100644
--- a/chromium/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper.h
+++ b/chromium/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper.h
@@ -38,11 +38,10 @@ class NET_EXPORT ProxyResolverFactoryV8TracingWrapper
~ProxyResolverFactoryV8TracingWrapper() override;
// ProxyResolverFactory override.
- int CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
- std::unique_ptr<ProxyResolver>* resolver,
- const CompletionCallback& callback,
- std::unique_ptr<Request>* request) override;
+ int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
+ std::unique_ptr<ProxyResolver>* resolver,
+ const CompletionCallback& callback,
+ std::unique_ptr<Request>* request) override;
private:
void OnProxyResolverCreated(
diff --git a/chromium/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper_unittest.cc b/chromium/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper_unittest.cc
index 44acb35fd12..8fdea68d20b 100644
--- a/chromium/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper_unittest.cc
+++ b/chromium/net/proxy_resolution/proxy_resolver_v8_tracing_wrapper_unittest.cc
@@ -51,7 +51,7 @@ class ProxyResolverV8TracingWrapperTest : public testing::Test {
}
};
-scoped_refptr<ProxyResolverScriptData> LoadScriptData(const char* filename) {
+scoped_refptr<PacFileData> LoadScriptData(const char* filename) {
base::FilePath path;
PathService::Get(base::DIR_SOURCE_ROOT, &path);
path = path.AppendASCII("net");
@@ -67,7 +67,7 @@ scoped_refptr<ProxyResolverScriptData> LoadScriptData(const char* filename) {
EXPECT_TRUE(ok) << "Failed to read file: " << path.value();
// Load the PAC script into the ProxyResolver.
- return ProxyResolverScriptData::FromUTF8(file_contents);
+ return PacFileData::FromUTF8(file_contents);
}
std::unique_ptr<ProxyResolverErrorObserver> ReturnErrorObserver(
diff --git a/chromium/net/proxy_resolution/proxy_resolver_v8_unittest.cc b/chromium/net/proxy_resolution/proxy_resolver_v8_unittest.cc
index 2acc464a2b9..58bf6d05df3 100644
--- a/chromium/net/proxy_resolution/proxy_resolver_v8_unittest.cc
+++ b/chromium/net/proxy_resolution/proxy_resolver_v8_unittest.cc
@@ -20,6 +20,7 @@
using net::test::IsError;
using net::test::IsOk;
+using ::testing::IsEmpty;
namespace net {
namespace {
@@ -123,9 +124,8 @@ class ProxyResolverV8Test : public testing::Test {
}
// Create the ProxyResolver using the PAC script.
- return ProxyResolverV8::Create(
- ProxyResolverScriptData::FromUTF8(file_contents), bindings(),
- &resolver_);
+ return ProxyResolverV8::Create(PacFileData::FromUTF8(file_contents),
+ bindings(), &resolver_);
}
ProxyResolverV8& resolver() {
@@ -348,11 +348,11 @@ TEST_F(ProxyResolverV8Test, JavascriptLibrary) {
// If the javascript side of this unit-test fails, it will throw a javascript
// exception. Otherwise it will return "PROXY success:80".
- EXPECT_THAT(result, IsOk());
- EXPECT_EQ("success:80", proxy_info.proxy_server().ToURI());
+ EXPECT_THAT(bindings()->alerts, IsEmpty());
+ EXPECT_THAT(bindings()->errors, IsEmpty());
- EXPECT_EQ(0U, bindings()->alerts.size());
- EXPECT_EQ(0U, bindings()->errors.size());
+ ASSERT_THAT(result, IsOk());
+ EXPECT_EQ("success:80", proxy_info.proxy_server().ToURI());
}
// Test marshalling/un-marshalling of values between C++/V8.
diff --git a/chromium/net/proxy_resolution/proxy_resolver_winhttp.cc b/chromium/net/proxy_resolution/proxy_resolver_winhttp.cc
index ebe5fb8dca2..40d46f9e872 100644
--- a/chromium/net/proxy_resolution/proxy_resolver_winhttp.cc
+++ b/chromium/net/proxy_resolution/proxy_resolver_winhttp.cc
@@ -52,8 +52,7 @@ static Error WinHttpErrorToNetError(DWORD win_http_error) {
class ProxyResolverWinHttp : public ProxyResolver {
public:
- ProxyResolverWinHttp(
- const scoped_refptr<ProxyResolverScriptData>& script_data);
+ ProxyResolverWinHttp(const scoped_refptr<PacFileData>& script_data);
~ProxyResolverWinHttp() override;
// ProxyResolver implementation:
@@ -76,12 +75,11 @@ class ProxyResolverWinHttp : public ProxyResolver {
};
ProxyResolverWinHttp::ProxyResolverWinHttp(
- const scoped_refptr<ProxyResolverScriptData>& script_data)
+ const scoped_refptr<PacFileData>& script_data)
: session_handle_(NULL),
- pac_url_(script_data->type() == ProxyResolverScriptData::TYPE_AUTO_DETECT
+ pac_url_(script_data->type() == PacFileData::TYPE_AUTO_DETECT
? GURL("http://wpad/wpad.dat")
- : script_data->url()) {
-}
+ : script_data->url()) {}
ProxyResolverWinHttp::~ProxyResolverWinHttp() {
CloseWinHttpSession();
@@ -204,7 +202,7 @@ ProxyResolverFactoryWinHttp::ProxyResolverFactoryWinHttp()
}
int ProxyResolverFactoryWinHttp::CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
+ const scoped_refptr<PacFileData>& pac_script,
std::unique_ptr<ProxyResolver>* resolver,
const CompletionCallback& callback,
std::unique_ptr<Request>* request) {
diff --git a/chromium/net/proxy_resolution/proxy_resolver_winhttp.h b/chromium/net/proxy_resolution/proxy_resolver_winhttp.h
index 663e76ec330..f76576a493a 100644
--- a/chromium/net/proxy_resolution/proxy_resolver_winhttp.h
+++ b/chromium/net/proxy_resolution/proxy_resolver_winhttp.h
@@ -20,11 +20,10 @@ class NET_EXPORT_PRIVATE ProxyResolverFactoryWinHttp
public:
ProxyResolverFactoryWinHttp();
- int CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
- std::unique_ptr<ProxyResolver>* resolver,
- const CompletionCallback& callback,
- std::unique_ptr<Request>* request) override;
+ int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
+ std::unique_ptr<ProxyResolver>* resolver,
+ const CompletionCallback& callback,
+ std::unique_ptr<Request>* request) override;
private:
DISALLOW_COPY_AND_ASSIGN(ProxyResolverFactoryWinHttp);
diff --git a/chromium/net/quic/chromium/bidirectional_stream_quic_impl.cc b/chromium/net/quic/chromium/bidirectional_stream_quic_impl.cc
index e809c3e1634..b2c48aec8a8 100644
--- a/chromium/net/quic/chromium/bidirectional_stream_quic_impl.cc
+++ b/chromium/net/quic/chromium/bidirectional_stream_quic_impl.cc
@@ -12,6 +12,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/timer/timer.h"
#include "net/http/bidirectional_stream_request_info.h"
+#include "net/http/http_util.h"
#include "net/quic/core/quic_connection.h"
#include "net/quic/platform/api/quic_string_piece.h"
#include "net/socket/next_proto.h"
@@ -68,7 +69,8 @@ void BidirectionalStreamQuicImpl::Start(
const NetLogWithSource& net_log,
bool send_request_headers_automatically,
BidirectionalStreamImpl::Delegate* delegate,
- std::unique_ptr<base::Timer> /* timer */) {
+ std::unique_ptr<base::Timer> timer,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
ScopedBoolSaver saver(&may_invoke_callbacks_, false);
DCHECK(!stream_);
CHECK(delegate);
@@ -79,12 +81,11 @@ void BidirectionalStreamQuicImpl::Start(
delegate_ = delegate;
request_info_ = request_info;
- // TODO(https://crbug.com/656607): Add proper annotation here.
int rv = session_->RequestStream(
- request_info_->method == "POST",
+ !HttpUtil::IsMethodSafe(request_info_->method),
base::Bind(&BidirectionalStreamQuicImpl::OnStreamReady,
weak_factory_.GetWeakPtr()),
- NO_TRAFFIC_ANNOTATION_BUG_656607);
+ traffic_annotation);
if (rv == ERR_IO_PENDING)
return;
diff --git a/chromium/net/quic/chromium/bidirectional_stream_quic_impl.h b/chromium/net/quic/chromium/bidirectional_stream_quic_impl.h
index 8b63600bd90..00a70d2cccb 100644
--- a/chromium/net/quic/chromium/bidirectional_stream_quic_impl.h
+++ b/chromium/net/quic/chromium/bidirectional_stream_quic_impl.h
@@ -41,7 +41,8 @@ class NET_EXPORT_PRIVATE BidirectionalStreamQuicImpl
const NetLogWithSource& net_log,
bool send_request_headers_automatically,
BidirectionalStreamImpl::Delegate* delegate,
- std::unique_ptr<base::Timer> timer) override;
+ std::unique_ptr<base::Timer> timer,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
void SendRequestHeaders() override;
int ReadData(IOBuffer* buffer, int buffer_len) override;
void SendvData(const std::vector<scoped_refptr<IOBuffer>>& buffers,
diff --git a/chromium/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc b/chromium/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc
index 79794cdfafc..fac7558c616 100644
--- a/chromium/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc
+++ b/chromium/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc
@@ -28,6 +28,7 @@
#include "net/quic/chromium/quic_chromium_packet_writer.h"
#include "net/quic/chromium/quic_http_utils.h"
#include "net/quic/chromium/quic_server_info.h"
+#include "net/quic/chromium/quic_stream_factory.h"
#include "net/quic/chromium/quic_test_packet_maker.h"
#include "net/quic/chromium/test_task_runner.h"
#include "net/quic/core/crypto/crypto_protocol.h"
@@ -46,6 +47,7 @@
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/socket/socket_test_util.h"
#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -167,7 +169,7 @@ class TestDelegateBase : public BidirectionalStreamImpl::Delegate {
not_expect_callback_ = true;
stream_ = std::make_unique<BidirectionalStreamQuicImpl>(std::move(session));
stream_->Start(request_info, net_log, send_request_headers_automatically_,
- this, nullptr);
+ this, nullptr, TRAFFIC_ANNOTATION_FOR_TESTS);
not_expect_callback_ = false;
}
@@ -990,28 +992,16 @@ TEST_P(BidirectionalStreamQuicImplTest, CoalesceDataBuffersNotHeadersFrame) {
AddWrite(ConstructRequestHeadersPacketInner(
2, GetNthClientInitiatedStreamId(0), !kFin, DEFAULT_PRIORITY,
&spdy_request_headers_frame_length, &header_stream_offset));
- if (FLAGS_quic_reloadable_flag_quic_use_mem_slices) {
- AddWrite(ConstructDataPacket(3, kIncludeVersion, !kFin, 0,
- "here are some datadata keep coming",
- &client_maker_));
- } else {
AddWrite(ConstructClientMultipleDataFramesPacket(3, kIncludeVersion, !kFin,
0, {kBody1, kBody2}));
- }
// Ack server's data packet.
AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
const char kBody3[] = "hello there";
const char kBody4[] = "another piece of small data";
const char kBody5[] = "really small";
QuicStreamOffset data_offset = strlen(kBody1) + strlen(kBody2);
- if (FLAGS_quic_reloadable_flag_quic_use_mem_slices) {
- AddWrite(ConstructDataPacket(
- 5, !kIncludeVersion, kFin, data_offset,
- "hello thereanother piece of small datareally small", &client_maker_));
- } else {
AddWrite(ConstructClientMultipleDataFramesPacket(
5, !kIncludeVersion, kFin, data_offset, {kBody3, kBody4, kBody5}));
- }
Initialize();
BidirectionalStreamRequestInfo request;
@@ -1207,27 +1197,18 @@ TEST_P(BidirectionalStreamQuicImplTest,
AddWrite(ConstructInitialSettingsPacket(1, &header_stream_offset));
const char kBody1[] = "here are some data";
const char kBody2[] = "data keep coming";
- const char kBody1And2[] = "here are some datadata keep coming";
std::vector<std::string> two_writes = {kBody1, kBody2};
- std::vector<std::string> one_write = {kBody1And2};
AddWrite(ConstructRequestHeadersAndMultipleDataFramesPacket(
2, !kFin, DEFAULT_PRIORITY, &header_stream_offset,
- &spdy_request_headers_frame_length,
- FLAGS_quic_reloadable_flag_quic_use_mem_slices ? one_write : two_writes));
+ &spdy_request_headers_frame_length, two_writes));
// Ack server's data packet.
AddWrite(ConstructClientAckPacket(3, 3, 1, 1));
const char kBody3[] = "hello there";
const char kBody4[] = "another piece of small data";
const char kBody5[] = "really small";
QuicStreamOffset data_offset = strlen(kBody1) + strlen(kBody2);
- if (FLAGS_quic_reloadable_flag_quic_use_mem_slices) {
- AddWrite(ConstructDataPacket(
- 4, !kIncludeVersion, kFin, data_offset,
- "hello thereanother piece of small datareally small", &client_maker_));
- } else {
AddWrite(ConstructClientMultipleDataFramesPacket(
4, !kIncludeVersion, kFin, data_offset, {kBody3, kBody4, kBody5}));
- }
Initialize();
BidirectionalStreamRequestInfo request;
@@ -1465,84 +1446,6 @@ TEST_P(BidirectionalStreamQuicImplTest, PostRequest) {
delegate->GetTotalReceivedBytes());
}
-TEST_P(BidirectionalStreamQuicImplTest, PutRequest) {
- SetRequest("PUT", "/", DEFAULT_PRIORITY);
- size_t spdy_request_headers_frame_length;
- AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
- &spdy_request_headers_frame_length));
- AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData,
- &client_maker_));
- AddWrite(ConstructClientAckPacket(3, 3, 1, 1));
-
- Initialize();
-
- BidirectionalStreamRequestInfo request;
- request.method = "PUT";
- request.url = GURL("http://www.google.com/");
- request.end_stream_on_headers = false;
- request.priority = DEFAULT_PRIORITY;
-
- scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
- std::unique_ptr<TestDelegateBase> delegate(
- new TestDelegateBase(read_buffer.get(), kReadBufferSize));
- delegate->Start(&request, net_log().bound(),
- session()->CreateHandle(destination_));
- delegate->WaitUntilNextCallback(kOnStreamReady);
-
- // Send a DATA frame.
- scoped_refptr<StringIOBuffer> buf(new StringIOBuffer(kUploadData));
-
- delegate->SendData(buf, buf->size(), true);
- delegate->WaitUntilNextCallback(kOnDataSent);
-
- // Server acks the request.
- ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
-
- // Server sends the response headers.
- SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
- size_t spdy_response_headers_frame_length;
- QuicStreamOffset offset = 0;
- ProcessPacket(ConstructResponseHeadersPacket(
- 2, !kFin, std::move(response_headers),
- &spdy_response_headers_frame_length, &offset));
-
- delegate->WaitUntilNextCallback(kOnHeadersReceived);
- TestCompletionCallback cb;
- int rv = delegate->ReadData(cb.callback());
- EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
- EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
- const char kResponseBody[] = "Hello world!";
- // Server sends data.
- ProcessPacket(
- ConstructServerDataPacket(3, !kIncludeVersion, !kFin, 0, kResponseBody));
-
- EXPECT_EQ(static_cast<int>(strlen(kResponseBody)), cb.WaitForResult());
-
- size_t spdy_trailers_frame_length;
- SpdyHeaderBlock trailers;
- trailers["foo"] = "bar";
- trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(kResponseBody));
- // Server sends trailers.
- ProcessPacket(ConstructResponseTrailersPacket(
- 4, kFin, trailers.Clone(), &spdy_trailers_frame_length, &offset));
-
- delegate->WaitUntilNextCallback(kOnTrailersReceived);
- trailers.erase(kFinalOffsetHeaderKey);
- EXPECT_EQ(trailers, delegate->trailers());
- EXPECT_THAT(delegate->ReadData(cb.callback()), IsOk());
-
- EXPECT_EQ(1, delegate->on_data_read_count());
- EXPECT_EQ(1, delegate->on_data_sent_count());
- EXPECT_EQ(kProtoQUIC, delegate->GetProtocol());
- EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
- strlen(kUploadData)),
- delegate->GetTotalSentBytes());
- EXPECT_EQ(
- static_cast<int64_t>(spdy_response_headers_frame_length +
- strlen(kResponseBody) + spdy_trailers_frame_length),
- delegate->GetTotalReceivedBytes());
-}
-
TEST_P(BidirectionalStreamQuicImplTest, InterleaveReadDataAndSendData) {
SetRequest("POST", "/", DEFAULT_PRIORITY);
size_t spdy_request_headers_frame_length;
diff --git a/chromium/net/quic/chromium/crypto/proof_verifier_chromium_test.cc b/chromium/net/quic/chromium/crypto/proof_verifier_chromium_test.cc
index 696efbbad07..942b88a118c 100644
--- a/chromium/net/quic/chromium/crypto/proof_verifier_chromium_test.cc
+++ b/chromium/net/quic/chromium/crypto/proof_verifier_chromium_test.cc
@@ -62,8 +62,10 @@ class MockCTPolicyEnforcer : public CTPolicyEnforcer {
class MockRequireCTDelegate : public TransportSecurityState::RequireCTDelegate {
public:
- MOCK_METHOD1(IsCTRequiredForHost,
- CTRequirementLevel(const std::string& host));
+ MOCK_METHOD3(IsCTRequiredForHost,
+ CTRequirementLevel(const std::string& host,
+ const X509Certificate* chain,
+ const HashValueVector& hashes));
};
// Proof source callback which saves the signature into |signature|.
@@ -114,9 +116,8 @@ class ProofVerifierChromiumTest : public ::testing::Test {
.WillRepeatedly(
Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
- scoped_refptr<const CTLogVerifier> log(
- CTLogVerifier::Create(ct::GetTestPublicKey(), kLogDescription,
- "https://test.example.com", "dns.example.com"));
+ scoped_refptr<const CTLogVerifier> log(CTLogVerifier::Create(
+ ct::GetTestPublicKey(), kLogDescription, "dns.example.com"));
ASSERT_TRUE(log);
log_verifiers_.push_back(log);
@@ -597,10 +598,10 @@ TEST_F(ProofVerifierChromiumTest, CTIsRequired) {
// Set up CT.
MockRequireCTDelegate require_ct_delegate;
transport_security_state_.SetRequireCTDelegate(&require_ct_delegate);
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_))
+ EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
.WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
CTRequirementLevel::NOT_REQUIRED));
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(kTestHostname))
+ EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(kTestHostname, _, _))
.WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
CTRequirementLevel::REQUIRED));
EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
@@ -649,10 +650,10 @@ TEST_F(ProofVerifierChromiumTest, CTIsRequiredHistogramNonCompliant) {
// Set up CT.
MockRequireCTDelegate require_ct_delegate;
transport_security_state_.SetRequireCTDelegate(&require_ct_delegate);
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_))
+ EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
.WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
CTRequirementLevel::NOT_REQUIRED));
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(kTestHostname))
+ EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(kTestHostname, _, _))
.WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
CTRequirementLevel::REQUIRED));
EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
@@ -696,10 +697,10 @@ TEST_F(ProofVerifierChromiumTest, CTIsRequiredHistogramCompliant) {
// Set up CT.
MockRequireCTDelegate require_ct_delegate;
transport_security_state_.SetRequireCTDelegate(&require_ct_delegate);
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_))
+ EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
.WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
CTRequirementLevel::NOT_REQUIRED));
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(kTestHostname))
+ EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(kTestHostname, _, _))
.WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
CTRequirementLevel::REQUIRED));
EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
@@ -805,10 +806,10 @@ TEST_F(ProofVerifierChromiumTest, PKPAndCTBothTested) {
// Set up CT.
MockRequireCTDelegate require_ct_delegate;
transport_security_state_.SetRequireCTDelegate(&require_ct_delegate);
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_))
+ EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
.WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
CTRequirementLevel::NOT_REQUIRED));
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(kTestHostname))
+ EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(kTestHostname, _, _))
.WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
CTRequirementLevel::REQUIRED));
EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
@@ -917,7 +918,7 @@ TEST_F(ProofVerifierChromiumTest, CTRequirementsFlagNotMet) {
// Set up CT.
MockRequireCTDelegate require_ct_delegate;
transport_security_state_.SetRequireCTDelegate(&require_ct_delegate);
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_))
+ EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
.WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
CTRequirementLevel::REQUIRED));
EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
@@ -959,7 +960,7 @@ TEST_F(ProofVerifierChromiumTest, CTRequirementsFlagMet) {
// Set up CT.
MockRequireCTDelegate require_ct_delegate;
transport_security_state_.SetRequireCTDelegate(&require_ct_delegate);
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_))
+ EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
.WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
CTRequirementLevel::REQUIRED));
EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
diff --git a/chromium/net/quic/chromium/quic_chromium_client_session.cc b/chromium/net/quic/chromium/quic_chromium_client_session.cc
index d366ad8a759..fcbaa1349a8 100644
--- a/chromium/net/quic/chromium/quic_chromium_client_session.cc
+++ b/chromium/net/quic/chromium/quic_chromium_client_session.cc
@@ -76,6 +76,12 @@ const int kDefaultRTTMilliSecs = 300;
// The maximum size of uncompressed QUIC headers that will be allowed.
const size_t kMaxUncompressedHeaderSize = 256 * 1024;
+// The maximum time allowed to have no retransmittable packets on the wire
+// (after sending the first retransmittable packet) if
+// |migrate_session_early_v2_| is true. PING frames will be sent as needed to
+// enforce this.
+const size_t kDefaultRetransmittableOnWireTimeoutMillisecs = 100;
+
// Histograms for tracking down the crashes from http://crbug.com/354669
// Note: these values must be kept in sync with the corresponding values in:
// tools/metrics/histograms/histograms.xml
@@ -130,26 +136,6 @@ std::unique_ptr<base::Value> NetLogQuicConnectionMigrationSuccessCallback(
return std::move(dict);
}
-void HistogramAndLogMigrationFailure(const NetLogWithSource& net_log,
- enum QuicConnectionMigrationStatus status,
- QuicConnectionId connection_id,
- std::string reason) {
- UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ConnectionMigration", status,
- MIGRATION_STATUS_MAX);
- net_log.AddEvent(NetLogEventType::QUIC_CONNECTION_MIGRATION_FAILURE,
- base::Bind(&NetLogQuicConnectionMigrationFailureCallback,
- connection_id, reason));
-}
-
-void HistogramAndLogMigrationSuccess(const NetLogWithSource& net_log,
- QuicConnectionId connection_id) {
- UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ConnectionMigration",
- MIGRATION_STATUS_SUCCESS, MIGRATION_STATUS_MAX);
- net_log.AddEvent(
- NetLogEventType::QUIC_CONNECTION_MIGRATION_SUCCESS,
- base::Bind(&NetLogQuicConnectionMigrationSuccessCallback, connection_id));
-}
-
// Histogram for recording the different reasons that a QUIC session is unable
// to complete the handshake.
enum HandshakeFailureReason {
@@ -180,6 +166,29 @@ void RecordHandshakeState(HandshakeState state) {
NUM_HANDSHAKE_STATES);
}
+std::string ConnectionMigrationCauseToString(ConnectionMigrationCause cause) {
+ switch (cause) {
+ case UNKNOWN:
+ return "Unknown";
+ case ON_NETWORK_CONNECTED:
+ return "OnNetworkConnected";
+ case ON_NETWORK_DISCONNECTED:
+ return "OnNetworkDisconnected";
+ case ON_WRITE_ERROR:
+ return "OnWriteError";
+ case ON_NETWORK_MADE_DEFAULT:
+ return "OnNetworkMadeDefault";
+ case ON_MIGRATE_BACK_TO_DEFAULT_NETWORK:
+ return "OnMigrateBackToDefaultNetwork";
+ case ON_PATH_DEGRADING:
+ return "OnPathDegrading";
+ default:
+ QUIC_NOTREACHED();
+ break;
+ }
+ return "InvalidCause";
+}
+
std::unique_ptr<base::Value> NetLogQuicClientSessionCallback(
const QuicServerId* server_id,
int cert_verify_flags,
@@ -207,6 +216,19 @@ std::unique_ptr<base::Value> NetLogQuicPushPromiseReceivedCallback(
return std::move(dict);
}
+// TODO(fayang): Remove this when necessary data is collected.
+void LogProbeResultToHistogram(ConnectionMigrationCause cause, bool success) {
+ UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ConnectionMigrationProbeSuccess",
+ success);
+ const std::string histogram_name =
+ "Net.QuicSession.ConnectionMigrationProbeSuccess." +
+ ConnectionMigrationCauseToString(cause);
+ STATIC_HISTOGRAM_POINTER_GROUP(
+ histogram_name, cause, MIGRATION_CAUSE_MAX, AddBoolean(success),
+ base::BooleanHistogram::FactoryGet(
+ histogram_name, base::HistogramBase::kUmaTargetedHistogramFlag));
+}
+
class HpackEncoderDebugVisitor : public QuicHpackDebugVisitor {
void OnUseEntry(QuicTime::Delta elapsed) override {
UMA_HISTOGRAM_TIMES(
@@ -721,6 +743,7 @@ QuicChromiumClientSession::QuicChromiumClientSession(
bytes_pushed_and_unclaimed_count_(0),
probing_manager_(this, task_runner_),
retry_migrate_back_count_(0),
+ current_connection_migration_cause_(UNKNOWN),
migration_pending_(false),
headers_include_h2_stream_dependency_(
headers_include_h2_stream_dependency &&
@@ -751,6 +774,11 @@ QuicChromiumClientSession::QuicChromiumClientSession(
}
connect_timing_.dns_start = dns_resolution_start_time;
connect_timing_.dns_end = dns_resolution_end_time;
+ if (migrate_session_early_v2_) {
+ connection->set_retransmittable_on_wire_timeout(
+ QuicTime::Delta::FromMilliseconds(
+ kDefaultRetransmittableOnWireTimeoutMillisecs));
+ }
}
QuicChromiumClientSession::~QuicChromiumClientSession() {
@@ -780,7 +808,7 @@ QuicChromiumClientSession::~QuicChromiumClientSession() {
if (connection()->connected()) {
// Ensure that the connection is closed by the time the session is
// destroyed.
- RecordInternalErrorLocation(QUIC_CHROMIUM_CLIENT_SESSION);
+ RecordInternalErrorLocation(QUIC_CHROMIUM_CLIENT_SESSION_DESTRUCTOR);
connection()->CloseConnection(QUIC_INTERNAL_ERROR, "session torn down",
ConnectionCloseBehavior::SILENT_CLOSE);
}
@@ -900,11 +928,12 @@ void QuicChromiumClientSession::OnHeadersHeadOfLineBlocking(
base::TimeDelta::FromMicroseconds(delta.ToMicroseconds()));
}
-void QuicChromiumClientSession::UnregisterStreamPriority(QuicStreamId id) {
- if (headers_include_h2_stream_dependency_) {
+void QuicChromiumClientSession::UnregisterStreamPriority(QuicStreamId id,
+ bool is_static) {
+ if (headers_include_h2_stream_dependency_ && !is_static) {
priority_dependency_state_.OnStreamDestruction(id);
}
- QuicSpdySession::UnregisterStreamPriority(id);
+ QuicSpdySession::UnregisterStreamPriority(id, is_static);
}
void QuicChromiumClientSession::UpdateStreamPriority(
@@ -1563,7 +1592,7 @@ void QuicChromiumClientSession::OnConnectionClosed(
void QuicChromiumClientSession::OnSuccessfulVersionNegotiation(
const ParsedQuicVersion& version) {
- logger_->OnSuccessfulVersionNegotiation(version.transport_version);
+ logger_->OnSuccessfulVersionNegotiation(version);
QuicSpdySession::OnSuccessfulVersionNegotiation(version);
}
@@ -1619,6 +1648,8 @@ void QuicChromiumClientSession::MigrateSessionOnWriteError(int error_code) {
if (!migration_pending_)
return;
+ current_connection_migration_cause_ = ON_WRITE_ERROR;
+
MigrationResult result = MigrationResult::FAILURE;
if (stream_factory_ != nullptr) {
const NetLogWithSource migration_net_log = NetLogWithSource::Make(
@@ -1672,11 +1703,7 @@ void QuicChromiumClientSession::WriteToNewSocket() {
// Unblock the connection before sending a PING packet, since it
// may have been blocked before the migration started.
connection()->OnCanWrite();
- if (use_control_frame_manager()) {
- SendPing();
- } else {
- connection()->SendPing();
- }
+ SendPing();
return;
}
@@ -1700,9 +1727,8 @@ void QuicChromiumClientSession::OnMigrationTimeout(size_t num_sockets) {
// If number of sockets has changed, this migration task is stale.
if (num_sockets != sockets_.size())
return;
- UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ConnectionMigration",
- MIGRATION_STATUS_NO_ALTERNATE_NETWORK,
- MIGRATION_STATUS_MAX);
+
+ LogConnectionMigrationResultToHistogram(MIGRATION_STATUS_TIMEOUT);
CloseSessionOnError(ERR_NETWORK_CHANGED,
QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK);
}
@@ -1721,6 +1747,8 @@ void QuicChromiumClientSession::OnProbeNetworkSucceeded(
NetLogEventType::QUIC_CONNECTION_CONNECTIVITY_PROBING_SUCCEEDED,
NetLog::Int64Callback("network", network));
+ LogProbeResultToHistogram(current_connection_migration_cause_, true);
+
// Set |this| to listen on socket write events on the packet writer
// that was used for probing.
writer->set_delegate(this);
@@ -1745,6 +1773,7 @@ void QuicChromiumClientSession::OnProbeNetworkSucceeded(
<< "successful probing network: " << network << ".";
current_migrations_to_non_default_network_on_path_degrading_++;
if (!migrate_back_to_default_timer_.IsRunning()) {
+ current_connection_migration_cause_ = ON_MIGRATE_BACK_TO_DEFAULT_NETWORK;
// Session gets off the |default_network|, stay on |network| for now but
// try to migrate back to default network after 1 second.
StartMigrateBackToDefaultNetworkTimer(
@@ -1758,6 +1787,8 @@ void QuicChromiumClientSession::OnProbeNetworkFailed(
net_log_.AddEvent(
NetLogEventType::QUIC_CONNECTION_CONNECTIVITY_PROBING_FAILED,
NetLog::Int64Callback("network", network));
+
+ LogProbeResultToHistogram(current_connection_migration_cause_, false);
// Probing failure for default network can be ignored.
DVLOG(1) << "Connectivity probing failed on NetworkHandle " << network;
DVLOG_IF(1, network == default_network_ &&
@@ -1782,6 +1813,7 @@ void QuicChromiumClientSession::OnNetworkConnected(
if (!migration_pending_)
return;
+ current_connection_migration_cause_ = ON_NETWORK_CONNECTED;
// |migration_pending_| is true, there was no working network previously.
// |network| is now the only possible candidate, migrate immediately.
if (migrate_session_on_network_change_v2_) {
@@ -1806,6 +1838,7 @@ void QuicChromiumClientSession::OnNetworkDisconnected(
if (!migrate_session_on_network_change_)
return;
+ current_connection_migration_cause_ = ON_NETWORK_DISCONNECTED;
MaybeMigrateOrCloseSession(
alternate_network, /*close_if_cannot_migrate*/ true, migration_net_log);
}
@@ -1829,6 +1862,7 @@ void QuicChromiumClientSession::OnNetworkDisconnectedV2(
return;
}
+ current_connection_migration_cause_ = ON_NETWORK_DISCONNECTED;
// Attempt to find alternative network.
NetworkChangeNotifier::NetworkHandle new_network =
stream_factory_->FindAlternateNetwork(disconnected_network);
@@ -1837,6 +1871,7 @@ void QuicChromiumClientSession::OnNetworkDisconnectedV2(
OnNoNewNetwork();
return;
}
+
// Current network is being disconnected, migrate immediately to the
// alternative network.
MigrateImmediately(new_network);
@@ -1855,6 +1890,7 @@ void QuicChromiumClientSession::OnNetworkMadeDefault(
DCHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, new_network);
default_network_ = new_network;
+ current_connection_migration_cause_ = ON_NETWORK_MADE_DEFAULT;
if (!migrate_session_on_network_change_v2_) {
MaybeMigrateOrCloseSession(new_network, /*close_if_cannot_migrate*/ false,
@@ -1943,6 +1979,7 @@ void QuicChromiumClientSession::OnPathDegrading() {
NetworkChangeNotifier::NetworkHandle alternate_network =
stream_factory_->FindAlternateNetwork(
GetDefaultSocket()->GetBoundNetwork());
+ current_connection_migration_cause_ = ON_PATH_DEGRADING;
if (alternate_network != NetworkChangeNotifier::kInvalidNetworkHandle) {
if (GetDefaultSocket()->GetBoundNetwork() == default_network_ &&
current_migrations_to_non_default_network_on_path_degrading_ >=
@@ -1970,8 +2007,8 @@ void QuicChromiumClientSession::OnPathDegrading() {
migration_net_log);
} else {
HistogramAndLogMigrationFailure(
- migration_net_log, MIGRATION_STATUS_NOT_ENABLED, connection_id(),
- "Migration on path degrading not enabled");
+ migration_net_log, MIGRATION_STATUS_PATH_DEGRADING_NOT_ENABLED,
+ connection_id(), "Migration on path degrading not enabled");
}
migration_net_log.EndEvent(
NetLogEventType::QUIC_CONNECTION_MIGRATION_TRIGGERED);
@@ -2027,6 +2064,10 @@ void QuicChromiumClientSession::StartReading() {
void QuicChromiumClientSession::CloseSessionOnError(int net_error,
QuicErrorCode quic_error) {
base::UmaHistogramSparse("Net.QuicSession.CloseSessionOnError", -net_error);
+ if (quic_error == QUIC_INTERNAL_ERROR) {
+ RecordInternalErrorLocation(
+ QUIC_CHROMIUM_CLIENT_SESSION_CLOSE_SESSION_ON_ERROR);
+ }
if (!callback_.is_null()) {
base::ResetAndReturn(&callback_).Run(net_error);
@@ -2189,6 +2230,9 @@ ProbingResult QuicChromiumClientSession::StartProbeNetwork(
void QuicChromiumClientSession::StartMigrateBackToDefaultNetworkTimer(
base::TimeDelta delay) {
+ if (current_connection_migration_cause_ != ON_NETWORK_MADE_DEFAULT)
+ current_connection_migration_cause_ = ON_MIGRATE_BACK_TO_DEFAULT_NETWORK;
+
CancelMigrateBackToDefaultNetworkTimer();
// Post a task to try migrate back to default network after |delay|.
migrate_back_to_default_timer_.Start(
@@ -2360,6 +2404,40 @@ void QuicChromiumClientSession::LogMetricsOnNetworkMadeDefault() {
}
}
+void QuicChromiumClientSession::LogConnectionMigrationResultToHistogram(
+ QuicConnectionMigrationStatus status) {
+ UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.ConnectionMigration", status,
+ MIGRATION_STATUS_MAX);
+
+ // Log the connection migraiton result to different histograms based on the
+ // cause of the connection migration.
+ std::string histogram_name =
+ "Net.QuicSession.ConnectionMigration." +
+ ConnectionMigrationCauseToString(current_connection_migration_cause_);
+ base::UmaHistogramEnumeration(histogram_name, status, MIGRATION_STATUS_MAX);
+ current_connection_migration_cause_ = UNKNOWN;
+}
+
+void QuicChromiumClientSession::HistogramAndLogMigrationFailure(
+ const NetLogWithSource& net_log,
+ QuicConnectionMigrationStatus status,
+ QuicConnectionId connection_id,
+ const std::string& reason) {
+ LogConnectionMigrationResultToHistogram(status);
+ net_log.AddEvent(NetLogEventType::QUIC_CONNECTION_MIGRATION_FAILURE,
+ base::Bind(&NetLogQuicConnectionMigrationFailureCallback,
+ connection_id, reason));
+}
+
+void QuicChromiumClientSession::HistogramAndLogMigrationSuccess(
+ const NetLogWithSource& net_log,
+ QuicConnectionId connection_id) {
+ LogConnectionMigrationResultToHistogram(MIGRATION_STATUS_SUCCESS);
+ net_log.AddEvent(
+ NetLogEventType::QUIC_CONNECTION_MIGRATION_SUCCESS,
+ base::Bind(&NetLogQuicConnectionMigrationSuccessCallback, connection_id));
+}
+
std::unique_ptr<base::Value> QuicChromiumClientSession::GetInfoAsValue(
const std::set<HostPortPair>& aliases) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
@@ -2403,13 +2481,31 @@ void QuicChromiumClientSession::OnReadError(
int result,
const DatagramClientSocket* socket) {
DCHECK(socket != nullptr);
+ base::UmaHistogramSparse("Net.QuicSession.ReadError.AnyNetwork", -result);
if (socket != GetDefaultSocket()) {
- // Ignore read errors from old sockets that are no longer active.
+ base::UmaHistogramSparse("Net.QuicSession.ReadError.OtherNetworks",
+ -result);
+ // Ignore read errors from sockets that are not affecting the current
+ // network, i.e., sockets that are no longer active and probing socket.
// TODO(jri): Maybe clean up old sockets on error.
return;
}
+
+ base::UmaHistogramSparse("Net.QuicSession.ReadError.CurrentNetwork", -result);
+ if (IsCryptoHandshakeConfirmed()) {
+ base::UmaHistogramSparse(
+ "Net.QuicSession.ReadError.CurrentNetwork.HandshakeConfirmed", -result);
+ }
+
+ if (migration_pending_) {
+ // Ignore read errors during pending migration. Connection will be closed if
+ // pending migration failed or timed out.
+ base::UmaHistogramSparse("Net.QuicSession.ReadError.PendingMigration",
+ -result);
+ return;
+ }
+
DVLOG(1) << "Closing session on read error: " << result;
- base::UmaHistogramSparse("Net.QuicSession.ReadError", -result);
connection()->CloseConnection(QUIC_PACKET_READ_ERROR, ErrorToString(result),
ConnectionCloseBehavior::SILENT_CLOSE);
}
@@ -2666,7 +2762,7 @@ bool QuicChromiumClientSession::HandlePromised(QuicStreamId id,
// push promise headers are received, send a PRIORITY frame for the
// promised stream ID. Send |kDefaultPriority| since that will be the
// initial SpdyPriority of the push promise stream when created.
- const SpdyPriority priority = kDefaultPriority;
+ const SpdyPriority priority = QuicStream::kDefaultPriority;
SpdyStreamId parent_stream_id = 0;
int weight = 0;
bool exclusive = false;
diff --git a/chromium/net/quic/chromium/quic_chromium_client_session.h b/chromium/net/quic/chromium/quic_chromium_client_session.h
index 21b4cb4bfc0..68ef0c92f0e 100644
--- a/chromium/net/quic/chromium/quic_chromium_client_session.h
+++ b/chromium/net/quic/chromium/quic_chromium_client_session.h
@@ -81,6 +81,35 @@ enum class ConnectionMigrationMode {
FULL_MIGRATION_V2
};
+// Cause of connection migration.
+enum ConnectionMigrationCause {
+ UNKNOWN,
+ ON_NETWORK_CONNECTED, // No probing.
+ ON_NETWORK_DISCONNECTED, // No probing.
+ ON_WRITE_ERROR, // No probing.
+ ON_NETWORK_MADE_DEFAULT, // With probing.
+ ON_MIGRATE_BACK_TO_DEFAULT_NETWORK, // With probing.
+ ON_PATH_DEGRADING, // With probing.
+ MIGRATION_CAUSE_MAX
+};
+
+// Result of connection migration.
+enum QuicConnectionMigrationStatus {
+ MIGRATION_STATUS_NO_MIGRATABLE_STREAMS,
+ MIGRATION_STATUS_ALREADY_MIGRATED,
+ MIGRATION_STATUS_INTERNAL_ERROR,
+ MIGRATION_STATUS_TOO_MANY_CHANGES,
+ MIGRATION_STATUS_SUCCESS,
+ MIGRATION_STATUS_NON_MIGRATABLE_STREAM,
+ MIGRATION_STATUS_NOT_ENABLED,
+ MIGRATION_STATUS_NO_ALTERNATE_NETWORK,
+ MIGRATION_STATUS_ON_PATH_DEGRADING_DISABLED,
+ MIGRATION_STATUS_DISABLED_BY_CONFIG,
+ MIGRATION_STATUS_PATH_DEGRADING_NOT_ENABLED,
+ MIGRATION_STATUS_TIMEOUT,
+ MIGRATION_STATUS_MAX
+};
+
// Result of a connectivity probing attempt.
enum class ProbingResult {
PENDING, // Probing started, pending result.
@@ -426,7 +455,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
QuicReferenceCountedPointer<QuicAckListenerInterface>
ack_listener) override;
void OnHeadersHeadOfLineBlocking(QuicTime::Delta delta) override;
- void UnregisterStreamPriority(QuicStreamId id) override;
+ void UnregisterStreamPriority(QuicStreamId id, bool is_static) override;
void UpdateStreamPriority(QuicStreamId id,
SpdyPriority new_priority) override;
@@ -687,6 +716,14 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
const NetLogWithSource& migration_net_log);
void LogMetricsOnNetworkDisconnected();
void LogMetricsOnNetworkMadeDefault();
+ void LogConnectionMigrationResultToHistogram(
+ QuicConnectionMigrationStatus status);
+ void HistogramAndLogMigrationFailure(const NetLogWithSource& net_log,
+ QuicConnectionMigrationStatus status,
+ QuicConnectionId connection_id,
+ const std::string& reason);
+ void HistogramAndLogMigrationSuccess(const NetLogWithSource& net_log,
+ QuicConnectionId connection_id);
// Notifies the factory that this session is going away and no more streams
// should be created from it. This needs to be called before closing any
@@ -763,6 +800,7 @@ class NET_EXPORT_PRIVATE QuicChromiumClientSession
QuicConnectivityProbingManager probing_manager_;
int retry_migrate_back_count_;
base::OneShotTimer migrate_back_to_default_timer_;
+ ConnectionMigrationCause current_connection_migration_cause_;
// TODO(jri): Replace use of migration_pending_ sockets_.size().
// When a task is posted for MigrateSessionOnError, pass in
// sockets_.size(). Then in MigrateSessionOnError, check to see if
diff --git a/chromium/net/quic/chromium/quic_chromium_client_session_test.cc b/chromium/net/quic/chromium/quic_chromium_client_session_test.cc
index 88e20fb455a..36509ccb712 100644
--- a/chromium/net/quic/chromium/quic_chromium_client_session_test.cc
+++ b/chromium/net/quic/chromium/quic_chromium_client_session_test.cc
@@ -7,7 +7,6 @@
#include "base/base64.h"
#include "base/files/file_path.h"
#include "base/memory/ptr_util.h"
-#include "base/rand_util.h"
#include "base/run_loop.h"
#include "base/test/histogram_tester.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -36,14 +35,16 @@
#include "net/quic/core/quic_packet_writer.h"
#include "net/quic/core/tls_client_handshaker.h"
#include "net/quic/platform/api/quic_flags.h"
-#include "net/quic/platform/impl/quic_test_impl.h"
+#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/quic_client_promised_info_peer.h"
+#include "net/quic/test_tools/quic_connection_peer.h"
#include "net/quic/test_tools/quic_stream_peer.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/quic/test_tools/simple_quic_framer.h"
#include "net/socket/datagram_client_socket.h"
#include "net/socket/socket_test_util.h"
+#include "net/spdy/chromium/spdy_test_util_common.h"
#include "net/spdy/core/spdy_test_utils.h"
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
@@ -111,7 +112,8 @@ class QuicChromiumClientSessionTest
&clock_,
kServerHostname,
Perspective::IS_SERVER,
- false) {
+ false),
+ migrate_session_early_v2_(false) {
// Advance the time, because timers do not like uninitialized times.
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
}
@@ -129,7 +131,6 @@ class QuicChromiumClientSessionTest
socket_factory_.AddSocketDataProvider(socket_data_.get());
std::unique_ptr<DatagramClientSocket> socket =
socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
- base::Bind(&base::RandInt),
&net_log_, NetLogSource());
socket->Connect(kIpEndPoint);
QuicChromiumPacketWriter* writer = new net::QuicChromiumPacketWriter(
@@ -144,10 +145,9 @@ class QuicChromiumClientSessionTest
/*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
&transport_security_state_,
base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)), session_key_,
- /*require_confirmation=*/false, /*migrate_session_early*/ false,
- /*migrate_session_on_network_change*/ false,
- /*migrate_session_early_v2*/ false,
- /*migrate_session_on_network_change_v2*/ false,
+ /*require_confirmation=*/false, /*migrate_session_early=*/false,
+ /*migrate_session_on_network_change=*/false, migrate_session_early_v2_,
+ /*migrate_session_on_network_change_v2=*/false,
base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
kQuicYieldAfterPacketsRead,
@@ -219,6 +219,7 @@ class QuicChromiumClientSessionTest
QuicTestPacketMaker client_maker_;
QuicTestPacketMaker server_maker_;
ProofVerifyDetailsChromium verify_details_;
+ bool migrate_session_early_v2_;
};
INSTANTIATE_TEST_CASE_P(
@@ -1236,15 +1237,9 @@ TEST_P(QuicChromiumClientSessionTest, MigrateToSocket) {
char data[] = "ABCD";
std::unique_ptr<QuicEncryptedPacket> client_ping;
std::unique_ptr<QuicEncryptedPacket> ack_and_data_out;
- if (session_->use_control_frame_manager()) {
client_ping = client_maker_.MakeAckAndPingPacket(2, false, 1, 1, 1);
ack_and_data_out = client_maker_.MakeDataPacket(3, 5, false, false, 0,
QuicStringPiece(data));
- } else {
- client_ping = client_maker_.MakePingPacket(2, /*include_version=*/false);
- ack_and_data_out = client_maker_.MakeAckAndDataPacket(
- 3, false, 5, 1, 1, 1, false, 0, QuicStringPiece(data));
- }
std::unique_ptr<QuicEncryptedPacket> server_ping(
server_maker_.MakePingPacket(1, /*include_version=*/false));
MockRead reads[] = {
@@ -1260,7 +1255,6 @@ TEST_P(QuicChromiumClientSessionTest, MigrateToSocket) {
// Create connected socket.
std::unique_ptr<DatagramClientSocket> new_socket =
socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
- base::Bind(&base::RandInt),
&net_log_, NetLogSource());
EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
@@ -1319,7 +1313,6 @@ TEST_P(QuicChromiumClientSessionTest, MigrateToSocketMaxReaders) {
// Create connected socket.
std::unique_ptr<DatagramClientSocket> new_socket =
socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
- base::Bind(&base::RandInt),
&net_log_, NetLogSource());
EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
@@ -1355,11 +1348,7 @@ TEST_P(QuicChromiumClientSessionTest, MigrateToSocketReadError) {
std::unique_ptr<QuicEncryptedPacket> settings_packet(
client_maker_.MakeInitialSettingsPacket(1, nullptr));
std::unique_ptr<QuicEncryptedPacket> client_ping;
- if (FLAGS_quic_reloadable_flag_quic_use_control_frame_manager) {
client_ping = client_maker_.MakeAckAndPingPacket(2, false, 1, 1, 1);
- } else {
- client_ping = client_maker_.MakePingPacket(2, /*include_version=*/false);
- }
std::unique_ptr<QuicEncryptedPacket> server_ping(
server_maker_.MakePingPacket(1, /*include_version=*/false));
MockWrite old_writes[] = {
@@ -1386,7 +1375,6 @@ TEST_P(QuicChromiumClientSessionTest, MigrateToSocketReadError) {
// Create connected socket.
std::unique_ptr<DatagramClientSocket> new_socket =
socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
- base::Bind(&base::RandInt),
&net_log_, NetLogSource());
EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
@@ -1425,6 +1413,53 @@ TEST_P(QuicChromiumClientSessionTest, MigrateToSocketReadError) {
EXPECT_TRUE(new_socket_data.AllWriteDataConsumed());
}
+TEST_P(QuicChromiumClientSessionTest, RetransmittableOnWireTimeout) {
+ migrate_session_early_v2_ = true;
+
+ MockQuicData quic_data;
+ quic_data.AddWrite(client_maker_.MakeInitialSettingsPacket(1, nullptr));
+ quic_data.AddWrite(client_maker_.MakePingPacket(2, true));
+ quic_data.AddRead(server_maker_.MakeAckPacket(1, 2, 1, 1, false));
+
+ quic_data.AddWrite(client_maker_.MakePingPacket(3, false));
+ quic_data.AddRead(ASYNC, ERR_IO_PENDING);
+ quic_data.AddRead(ASYNC, OK); // EOF
+ quic_data.AddSocketDataToFactory(&socket_factory_);
+
+ Initialize();
+ CompleteCryptoHandshake();
+
+ EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100),
+ session_->connection()->retransmittable_on_wire_timeout());
+
+ // Open a stream since the connection only sends PINGs to keep a
+ // retransmittable packet on the wire if there's an open stream.
+ EXPECT_TRUE(QuicChromiumClientSessionPeer::CreateOutgoingDynamicStream(
+ session_.get()));
+
+ QuicAlarm* alarm =
+ QuicConnectionPeer::GetRetransmittableOnWireAlarm(session_->connection());
+ EXPECT_FALSE(alarm->IsSet());
+
+ // Send PING, which will be ACKed by the server. After the ACK, there will be
+ // no retransmittable packets on the wire, so the alarm should be set.
+ session_->SendPing();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(alarm->IsSet());
+ EXPECT_EQ(clock_.ApproximateNow() + QuicTime::Delta::FromMilliseconds(100),
+ alarm->deadline());
+
+ // Advance clock and simulate the alarm firing. This should cause a PING to be
+ // sent.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
+ alarm_factory_.FireAlarm(alarm);
+ base::RunLoop().RunUntilIdle();
+
+ quic_data.Resume();
+ EXPECT_TRUE(quic_data.AllReadDataConsumed());
+ EXPECT_TRUE(quic_data.AllWriteDataConsumed());
+}
+
} // namespace
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/chromium/quic_chromium_client_stream.cc b/chromium/net/quic/chromium/quic_chromium_client_stream.cc
index 4db1630d7dc..aa886ddd2e1 100644
--- a/chromium/net/quic/chromium/quic_chromium_client_stream.cc
+++ b/chromium/net/quic/chromium/quic_chromium_client_stream.cc
@@ -18,6 +18,7 @@
#include "net/quic/core/quic_spdy_session.h"
#include "net/quic/core/quic_write_blocked_list.h"
#include "net/quic/core/spdy_utils.h"
+#include "net/spdy/chromium/spdy_log_util.h"
namespace net {
namespace {
@@ -536,17 +537,11 @@ bool QuicChromiumClientStream::WritevStreamData(
// Must not be called when data is buffered.
DCHECK(!HasBufferedData());
// Writes the data, or buffers it.
- if (session_->can_use_slices()) {
- WriteMemSlices(QuicMemSliceSpan(QuicMemSliceSpanImpl(
- buffers.data(), lengths.data(), buffers.size())),
- fin);
- } else {
for (size_t i = 0; i < buffers.size(); ++i) {
bool is_fin = fin && (i == buffers.size() - 1);
QuicStringPiece string_data(buffers[i]->data(), lengths[i]);
WriteOrBufferData(string_data, is_fin, nullptr);
}
- }
return !HasBufferedData(); // Was all data written?
}
diff --git a/chromium/net/quic/chromium/quic_chromium_client_stream_test.cc b/chromium/net/quic/chromium/quic_chromium_client_stream_test.cc
index bd6ba937536..e37e55f6d8d 100644
--- a/chromium/net/quic/chromium/quic_chromium_client_stream_test.cc
+++ b/chromium/net/quic/chromium/quic_chromium_client_stream_test.cc
@@ -606,14 +606,9 @@ TEST_P(QuicChromiumClientStreamTest, WritevStreamData) {
new StringIOBuffer("Just a small payload"));
// All data written.
- if (session_.can_use_slices()) {
- EXPECT_CALL(session_, WritevData(stream_, stream_->id(), _, _, _))
- .WillOnce(Return(QuicConsumedData(buf1->size() + buf2->size(), true)));
- } else {
EXPECT_CALL(session_, WritevData(stream_, stream_->id(), _, _, _))
.WillOnce(Return(QuicConsumedData(buf1->size(), false)))
.WillOnce(Return(QuicConsumedData(buf2->size(), true)));
- }
TestCompletionCallback callback;
EXPECT_EQ(
OK, handle_->WritevStreamData({buf1, buf2}, {buf1->size(), buf2->size()},
@@ -626,16 +621,11 @@ TEST_P(QuicChromiumClientStreamTest, WritevStreamDataAsync) {
new StringIOBuffer("Just a small payload"));
// Only a part of the data is written.
- if (session_.can_use_slices()) {
- EXPECT_CALL(session_, WritevData(stream_, stream_->id(), _, _, _))
- .WillOnce(Return(QuicConsumedData(buf1->size(), false)));
- } else {
EXPECT_CALL(session_, WritevData(stream_, stream_->id(), _, _, _))
// First piece of data is written.
.WillOnce(Return(QuicConsumedData(buf1->size(), false)))
// Second piece of data is queued.
.WillOnce(Return(QuicConsumedData(0, false)));
- }
TestCompletionCallback callback;
EXPECT_EQ(ERR_IO_PENDING,
handle_->WritevStreamData({buf1.get(), buf2.get()},
diff --git a/chromium/net/quic/chromium/quic_chromium_packet_writer.cc b/chromium/net/quic/chromium/quic_chromium_packet_writer.cc
index af3b7c0a20b..5786a7f0192 100644
--- a/chromium/net/quic/chromium/quic_chromium_packet_writer.cc
+++ b/chromium/net/quic/chromium/quic_chromium_packet_writer.cc
@@ -38,6 +38,32 @@ void RecordRetryCount(int count) {
count, kMaxRetries + 1);
}
+const net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+ net::DefineNetworkTrafficAnnotation("quic_chromium_packet_writer", R"(
+ semantics {
+ sender: "QUIC Packet Writer"
+ description:
+ "A QUIC packet is written to the wire based on a request from "
+ "a QUIC stream."
+ trigger:
+ "A request from QUIC stream."
+ data: "Any data sent by the stream."
+ destination: OTHER
+ destination_other: "Any destination choosen by the stream."
+ }
+ policy {
+ cookies_allowed: NO
+ setting: "This feature cannot be disabled in settings."
+ policy_exception_justification:
+ "Essential for network access."
+ }
+ comments:
+ "All requests that are received by QUIC streams have network traffic "
+ "annotation, but the annotation is not passed to the writer function "
+ "due to technial overheads. Please see QuicChromiumClientSession and "
+ "QuicChromiumClientStream classes for references."
+ )");
+
} // namespace
QuicChromiumPacketWriter::ReusableIOBuffer::ReusableIOBuffer(size_t capacity)
@@ -108,34 +134,9 @@ WriteResult QuicChromiumPacketWriter::WritePacketToSocket(
WriteResult QuicChromiumPacketWriter::WritePacketToSocketImpl() {
base::TimeTicks now = base::TimeTicks::Now();
- net::NetworkTrafficAnnotationTag traffic_annotation =
- net::DefineNetworkTrafficAnnotation("quic_chromium_packet_writer", R"(
- semantics {
- sender: "QUIC Packet Writer"
- description:
- "A QUIC packet is written to the wire based on a request from "
- "a QUIC stream."
- trigger:
- "A request from QUIC stream."
- data: "Any data sent by the stream."
- destination: OTHER
- destination_other: "Any destination choosen by the stream."
- }
- policy {
- cookies_allowed: NO
- setting: "This feature cannot be disabled in settings."
- policy_exception_justification:
- "Essential for network access."
- }
- comments:
- "All requests that are received by QUIC streams have network traffic "
- "annotation, but the annotation is not passed to the writer function "
- "due to technial overheads. Please see QuicChromiumClientSession and "
- "QuicChromiumClientStream classes for references."
- )");
int rv = socket_->Write(packet_.get(), packet_->size(), write_callback_,
- traffic_annotation);
+ kTrafficAnnotation);
if (MaybeRetryAfterWriteError(rv))
return WriteResult(WRITE_STATUS_BLOCKED, ERR_IO_PENDING);
diff --git a/chromium/net/quic/chromium/quic_connection_logger.cc b/chromium/net/quic/chromium/quic_connection_logger.cc
index 048c4922a2e..d9e4ceefd38 100644
--- a/chromium/net/quic/chromium/quic_connection_logger.cc
+++ b/chromium/net/quic/chromium/quic_connection_logger.cc
@@ -711,10 +711,10 @@ void QuicConnectionLogger::OnConnectionClosed(QuicErrorCode error,
}
void QuicConnectionLogger::OnSuccessfulVersionNegotiation(
- const QuicTransportVersion& version) {
+ const ParsedQuicVersion& version) {
if (!net_log_is_capturing_)
return;
- string quic_version = QuicVersionToString(version);
+ string quic_version = QuicVersionToString(version.transport_version);
net_log_.AddEvent(NetLogEventType::QUIC_SESSION_VERSION_NEGOTIATED,
NetLog::StringCallback("version", &quic_version));
}
diff --git a/chromium/net/quic/chromium/quic_connection_logger.h b/chromium/net/quic/chromium/quic_connection_logger.h
index 07b6894e456..25638374c46 100644
--- a/chromium/net/quic/chromium/quic_connection_logger.h
+++ b/chromium/net/quic/chromium/quic_connection_logger.h
@@ -77,7 +77,7 @@ class NET_EXPORT_PRIVATE QuicConnectionLogger
const std::string& error_details,
ConnectionCloseSource source) override;
void OnSuccessfulVersionNegotiation(
- const QuicTransportVersion& version) override;
+ const ParsedQuicVersion& version) override;
void OnRttChanged(QuicTime::Delta rtt) const override;
void OnCryptoHandshakeMessageReceived(const CryptoHandshakeMessage& message);
diff --git a/chromium/net/quic/chromium/quic_connectivity_probing_manager_test.cc b/chromium/net/quic/chromium/quic_connectivity_probing_manager_test.cc
index 7b7b0c5c5cc..6d77dead83a 100644
--- a/chromium/net/quic/chromium/quic_connectivity_probing_manager_test.cc
+++ b/chromium/net/quic/chromium/quic_connectivity_probing_manager_test.cc
@@ -4,7 +4,6 @@
#include "net/quic/chromium/quic_connectivity_probing_manager.h"
-#include "base/rand_util.h"
#include "base/test/test_mock_time_task_runner.h"
#include "net/log/test_net_log.h"
#include "net/quic/test_tools/mock_clock.h"
@@ -84,8 +83,7 @@ class QuicConnectivityProbingManagerTest : public ::testing::Test {
socket_factory_.AddSocketDataProvider(socket_data_.get());
// Create a connected socket for probing.
socket_ = socket_factory_.CreateDatagramClientSocket(
- DatagramSocket::DEFAULT_BIND, base::Bind(&base::RandInt), &net_log_,
- NetLogSource());
+ DatagramSocket::DEFAULT_BIND, &net_log_, NetLogSource());
EXPECT_THAT(socket_->Connect(kIpEndPoint), IsOk());
IPEndPoint self_address;
socket_->GetLocalAddress(&self_address);
diff --git a/chromium/net/quic/chromium/quic_end_to_end_unittest.cc b/chromium/net/quic/chromium/quic_end_to_end_unittest.cc
index ae892bec698..ce0b3fbe1ee 100644
--- a/chromium/net/quic/chromium/quic_end_to_end_unittest.cc
+++ b/chromium/net/quic/chromium/quic_end_to_end_unittest.cc
@@ -28,7 +28,7 @@
#include "net/http/http_transaction_test_util.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log_with_source.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/quic/platform/api/quic_string_piece.h"
#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
diff --git a/chromium/net/quic/chromium/quic_http_stream.cc b/chromium/net/quic/chromium/quic_http_stream.cc
index bd1f159af5b..307604da0e5 100644
--- a/chromium/net/quic/chromium/quic_http_stream.cc
+++ b/chromium/net/quic/chromium/quic_http_stream.cc
@@ -15,6 +15,7 @@
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
+#include "net/log/net_log.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_source.h"
#include "net/quic/chromium/quic_http_utils.h"
@@ -467,6 +468,9 @@ void QuicHttpStream::DoCallback(int rv) {
int QuicHttpStream::DoLoop(int rv) {
CHECK(!in_loop_);
base::AutoReset<bool> auto_reset_in_loop(&in_loop_, true);
+ std::unique_ptr<QuicConnection::ScopedPacketFlusher> packet_flusher =
+ quic_session()->CreatePacketBundler(
+ QuicConnection::AckBundling::SEND_ACK_IF_QUEUED);
do {
State state = next_state_;
next_state_ = STATE_NONE;
diff --git a/chromium/net/quic/chromium/quic_http_stream_test.cc b/chromium/net/quic/chromium/quic_http_stream_test.cc
index b0b026be692..4d68b369db3 100644
--- a/chromium/net/quic/chromium/quic_http_stream_test.cc
+++ b/chromium/net/quic/chromium/quic_http_stream_test.cc
@@ -34,6 +34,7 @@
#include "net/quic/chromium/quic_chromium_packet_writer.h"
#include "net/quic/chromium/quic_http_utils.h"
#include "net/quic/chromium/quic_server_info.h"
+#include "net/quic/chromium/quic_stream_factory.h"
#include "net/quic/chromium/quic_test_packet_maker.h"
#include "net/quic/chromium/test_task_runner.h"
#include "net/quic/core/congestion_control/send_algorithm_interface.h"
@@ -420,6 +421,45 @@ class QuicHttpStreamTest
spdy_headers_frame_length, offset);
}
+ std::unique_ptr<QuicReceivedPacket>
+ ConstructRequestHeadersAndDataFramesPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ RequestPriority request_priority,
+ QuicStreamId parent_stream_id,
+ QuicStreamOffset* offset,
+ size_t* spdy_headers_frame_length,
+ const std::vector<std::string>& data_writes) {
+ SpdyPriority priority =
+ ConvertRequestPriorityToQuicPriority(request_priority);
+ return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
+ packet_number, stream_id, should_include_version, fin, priority,
+ std::move(request_headers_), parent_stream_id, offset,
+ spdy_headers_frame_length, data_writes);
+ }
+
+ std::unique_ptr<QuicReceivedPacket> ConstructRequestAndRstPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ RequestPriority request_priority,
+ QuicStreamId parent_stream_id,
+ size_t* spdy_headers_frame_length,
+ QuicStreamOffset* header_stream_offset,
+ QuicRstStreamErrorCode error_code,
+ size_t bytes_written) {
+ SpdyPriority priority =
+ ConvertRequestPriorityToQuicPriority(request_priority);
+ return client_maker_.MakeRequestHeadersAndRstPacket(
+ packet_number, stream_id, should_include_version, fin, priority,
+ std::move(request_headers_), parent_stream_id,
+ spdy_headers_frame_length, header_stream_offset, error_code,
+ bytes_written);
+ }
+
std::unique_ptr<QuicReceivedPacket> ConstructRequestHeadersPacket(
QuicPacketNumber packet_number,
bool fin,
@@ -1141,12 +1181,13 @@ TEST_P(QuicHttpStreamTest, SendPostRequest) {
size_t spdy_request_headers_frame_length;
QuicStreamOffset header_stream_offset = 0;
AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
- AddWrite(InnerConstructRequestHeadersPacket(
- 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
- DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
- &header_stream_offset));
- AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, 0, kUploadData));
- AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
+
+ AddWrite(ConstructRequestHeadersAndDataFramesPacket(
+ 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
+ DEFAULT_PRIORITY, 0, &header_stream_offset,
+ &spdy_request_headers_frame_length, {kUploadData}));
+
+ AddWrite(ConstructClientAckPacket(3, 3, 1, 1));
Initialize();
@@ -1212,12 +1253,11 @@ TEST_P(QuicHttpStreamTest, SendPostRequestAndReceiveSoloFin) {
size_t spdy_request_headers_frame_length;
QuicStreamOffset header_stream_offset = 0;
AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
- AddWrite(InnerConstructRequestHeadersPacket(
- 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
- DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
- &header_stream_offset));
- AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, 0, kUploadData));
- AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
+ AddWrite(ConstructRequestHeadersAndDataFramesPacket(
+ 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
+ DEFAULT_PRIORITY, 0, &header_stream_offset,
+ &spdy_request_headers_frame_length, {kUploadData}));
+ AddWrite(ConstructClientAckPacket(3, 3, 1, 1));
Initialize();
@@ -1286,15 +1326,13 @@ TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
size_t spdy_request_headers_frame_length;
QuicStreamOffset header_stream_offset = 0;
AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
- AddWrite(InnerConstructRequestHeadersPacket(
+ AddWrite(ConstructRequestHeadersAndDataFramesPacket(
2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
- DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
- &header_stream_offset));
- AddWrite(
- ConstructClientDataPacket(3, kIncludeVersion, !kFin, 0, kUploadData));
- AddWrite(ConstructClientDataPacket(4, kIncludeVersion, kFin, chunk_size,
+ DEFAULT_PRIORITY, 0, &header_stream_offset,
+ &spdy_request_headers_frame_length, {kUploadData}));
+ AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, chunk_size,
kUploadData));
- AddWrite(ConstructClientAckPacket(5, 3, 1, 1));
+ AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
Initialize();
upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
@@ -1361,14 +1399,12 @@ TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
size_t spdy_request_headers_frame_length;
QuicStreamOffset header_stream_offset = 0;
AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
- AddWrite(InnerConstructRequestHeadersPacket(
+ AddWrite(ConstructRequestHeadersAndDataFramesPacket(
2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
- DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
- &header_stream_offset));
- AddWrite(
- ConstructClientDataPacket(3, kIncludeVersion, !kFin, 0, kUploadData));
- AddWrite(ConstructClientDataPacket(4, kIncludeVersion, kFin, chunk_size, ""));
- AddWrite(ConstructClientAckPacket(5, 3, 1, 1));
+ DEFAULT_PRIORITY, 0, &header_stream_offset,
+ &spdy_request_headers_frame_length, {kUploadData}));
+ AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
+ AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
Initialize();
upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
@@ -1589,12 +1625,10 @@ TEST_P(QuicHttpStreamTest, SessionClosedDuringDoLoop) {
size_t spdy_request_headers_frame_length;
QuicStreamOffset header_stream_offset = 0;
AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
- AddWrite(InnerConstructRequestHeadersPacket(
+ AddWrite(ConstructRequestHeadersAndDataFramesPacket(
2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
- DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
- &header_stream_offset));
- AddWrite(
- ConstructClientDataPacket(3, kIncludeVersion, !kFin, 0, kUploadData));
+ DEFAULT_PRIORITY, 0, &header_stream_offset,
+ &spdy_request_headers_frame_length, {kUploadData}));
// Second data write will result in a synchronous failure which will close
// the session.
AddWrite(SYNCHRONOUS, ERR_FAILED);
@@ -1618,11 +1652,16 @@ TEST_P(QuicHttpStreamTest, SessionClosedDuringDoLoop) {
QuicHttpStream* stream = stream_.get();
DeleteStreamCallback delete_stream_callback(std::move(stream_));
// SendRequest() completes asynchronously after the final chunk is added.
+ // Error does not surface yet since packet write is triggered by a packet
+ // flusher that tries to bundle request body writes.
ASSERT_EQ(ERR_IO_PENDING,
stream->SendRequest(headers_, &response_, callback_.callback()));
chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
int rv = callback_.WaitForResult();
- EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, rv);
+ EXPECT_EQ(OK, rv);
+ // Error will be surfaced once an attempt to read the response occurs.
+ ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
+ stream->ReadResponseHeaders(callback_.callback()));
}
TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) {
@@ -1633,6 +1672,8 @@ TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) {
Initialize();
upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
+ auto* chunked_upload_stream =
+ static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
request_.method = "POST";
request_.url = GURL("https://www.example.org/");
@@ -1643,9 +1684,49 @@ TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) {
ASSERT_EQ(OK,
stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
- ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
+ ASSERT_EQ(ERR_IO_PENDING,
stream_->SendRequest(headers_, &response_, callback_.callback()));
+ // Error will be surfaced once |upload_data_stream| triggers the next write.
+ size_t chunk_size = strlen(kUploadData);
+ chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
+ ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
+
+ EXPECT_LE(0, stream_->GetTotalSentBytes());
+ EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
+}
+
+TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersCompleteReadResponse) {
+ SetRequest("POST", "/", DEFAULT_PRIORITY);
+ QuicStreamOffset header_stream_offset = 0;
+ AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
+ AddWrite(SYNCHRONOUS, ERR_FAILED);
+ Initialize();
+
+ upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
+ auto* chunked_upload_stream =
+ static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
+
+ request_.method = "POST";
+ request_.url = GURL("https://www.example.org/");
+ request_.upload_data_stream = upload_data_stream_.get();
+
+ size_t chunk_size = strlen(kUploadData);
+ chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
+
+ ASSERT_EQ(OK, request_.upload_data_stream->Init(
+ TestCompletionCallback().callback(), NetLogWithSource()));
+
+ ASSERT_EQ(OK,
+ stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
+ net_log_.bound(), callback_.callback()));
+ ASSERT_EQ(OK,
+ stream_->SendRequest(headers_, &response_, callback_.callback()));
+
+ // Error will be surfaced once an attempt to read the response occurs.
+ ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
+ stream_->ReadResponseHeaders(callback_.callback()));
+
EXPECT_LE(0, stream_->GetTotalSentBytes());
EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
}
@@ -1665,8 +1746,6 @@ TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBodyComplete) {
upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
auto* chunked_upload_stream =
static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
- size_t chunk_size = strlen(kUploadData);
- chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
request_.method = "POST";
request_.url = GURL("https://www.example.org/");
@@ -1677,8 +1756,65 @@ TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBodyComplete) {
ASSERT_EQ(OK,
stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
net_log_.bound(), callback_.callback()));
+ ASSERT_EQ(ERR_IO_PENDING,
+ stream_->SendRequest(headers_, &response_, callback_.callback()));
+
+ size_t chunk_size = strlen(kUploadData);
+ chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
+ // Error does not surface yet since packet write is triggered by a packet
+ // flusher that tries to bundle request body writes.
+ ASSERT_EQ(OK, callback_.WaitForResult());
+ // Error will be surfaced once an attempt to read the response occurs.
ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
+ stream_->ReadResponseHeaders(callback_.callback()));
+
+ EXPECT_LE(0, stream_->GetTotalSentBytes());
+ EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
+}
+
+TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBundledBodyComplete) {
+ SetRequest("POST", "/", DEFAULT_PRIORITY);
+ size_t spdy_request_headers_frame_length;
+ QuicStreamOffset header_stream_offset = 0;
+ AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
+ AddWrite(ConstructRequestHeadersAndDataFramesPacket(
+ 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
+ DEFAULT_PRIORITY, 0, &header_stream_offset,
+ &spdy_request_headers_frame_length, {kUploadData}));
+ AddWrite(SYNCHRONOUS, ERR_FAILED);
+ Initialize();
+
+ upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
+ auto* chunked_upload_stream =
+ static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
+
+ request_.method = "POST";
+ request_.url = GURL("https://www.example.org/");
+ request_.upload_data_stream = upload_data_stream_.get();
+
+ size_t chunk_size = strlen(kUploadData);
+ chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
+
+ ASSERT_EQ(OK, request_.upload_data_stream->Init(
+ TestCompletionCallback().callback(), NetLogWithSource()));
+
+ ASSERT_EQ(OK,
+ stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
+ net_log_.bound(), callback_.callback()));
+ ASSERT_EQ(ERR_IO_PENDING,
stream_->SendRequest(headers_, &response_, callback_.callback()));
+
+ chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
+
+ // Error does not surface yet since packet write is triggered by a packet
+ // flusher that tries to bundle request body writes.
+ ASSERT_EQ(OK, callback_.WaitForResult());
+ // Error will be surfaced once an attempt to read the response occurs.
+ ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
+ stream_->ReadResponseHeaders(callback_.callback()));
+
+ EXPECT_LE(0, stream_->GetTotalSentBytes());
+ EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
}
TEST_P(QuicHttpStreamTest, ServerPushGetRequest) {
@@ -2164,11 +2300,10 @@ TEST_P(QuicHttpStreamTest, DataReadErrorSynchronous) {
size_t spdy_request_headers_frame_length;
QuicStreamOffset header_stream_offset = 0;
AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
- AddWrite(InnerConstructRequestHeadersPacket(
+ AddWrite(ConstructRequestAndRstPacket(
2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
- DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
- &header_stream_offset));
- AddWrite(ConstructClientRstStreamErrorPacket(3, kIncludeVersion));
+ DEFAULT_PRIORITY, 0, &spdy_request_headers_frame_length,
+ &header_stream_offset, QUIC_ERROR_PROCESSING_STREAM, 0));
Initialize();
diff --git a/chromium/net/quic/chromium/quic_http_utils.cc b/chromium/net/quic/chromium/quic_http_utils.cc
index 664ab42bd65..a0b52a27552 100644
--- a/chromium/net/quic/chromium/quic_http_utils.cc
+++ b/chromium/net/quic/chromium/quic_http_utils.cc
@@ -8,6 +8,7 @@
#include "base/metrics/histogram_macros.h"
#include "net/quic/platform/api/quic_endian.h"
+#include "net/spdy/chromium/spdy_log_util.h"
namespace net {
diff --git a/chromium/net/quic/chromium/quic_http_utils.h b/chromium/net/quic/chromium/quic_http_utils.h
index f2839b82724..1c2d4848bea 100644
--- a/chromium/net/quic/chromium/quic_http_utils.h
+++ b/chromium/net/quic/chromium/quic_http_utils.h
@@ -8,6 +8,7 @@
#include "base/values.h"
#include "net/base/net_export.h"
#include "net/base/request_priority.h"
+#include "net/log/net_log_capture_mode.h"
#include "net/quic/core/quic_packets.h"
#include "net/spdy/core/spdy_header_block.h"
#include "net/spdy/core/spdy_protocol.h"
diff --git a/chromium/net/quic/chromium/quic_network_transaction_unittest.cc b/chromium/net/quic/chromium/quic_network_transaction_unittest.cc
index ca11773b3b0..e270c0d8e8d 100644
--- a/chromium/net/quic/chromium/quic_network_transaction_unittest.cc
+++ b/chromium/net/quic/chromium/quic_network_transaction_unittest.cc
@@ -37,8 +37,8 @@
#include "net/log/test_net_log_entry.h"
#include "net/log/test_net_log_util.h"
#include "net/proxy_resolution/proxy_config_service_fixed.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/proxy_resolution/proxy_resolver.h"
-#include "net/proxy_resolution/proxy_service.h"
#include "net/quic/chromium/crypto/proof_verifier_chromium.h"
#include "net/quic/chromium/mock_crypto_client_stream_factory.h"
#include "net/quic/chromium/mock_quic_data.h"
@@ -53,7 +53,7 @@
#include "net/quic/core/quic_framer.h"
#include "net/quic/platform/api/quic_str_cat.h"
#include "net/quic/platform/api/quic_string_piece.h"
-#include "net/quic/platform/impl/quic_test_impl.h"
+#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/mock_clock.h"
#include "net/quic/test_tools/mock_random.h"
@@ -423,20 +423,19 @@ class QuicNetworkTransactionTest : public PlatformTest,
ConvertRequestPriorityToQuicPriority(request_priority), offset);
}
- std::unique_ptr<QuicEncryptedPacket> ConstructClientAckAndPriorityPacket(
+ std::unique_ptr<QuicEncryptedPacket>
+ ConstructClientAckAndPriorityFramesPacket(
QuicPacketNumber packet_number,
bool should_include_version,
QuicPacketNumber largest_received,
QuicPacketNumber smallest_received,
QuicPacketNumber least_unacked,
- QuicStreamId stream_id,
- QuicStreamId parent_stream_id,
- RequestPriority request_priority,
+ const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
+ priority_frames,
QuicStreamOffset* offset) {
- return client_maker_.MakeAckAndPriorityPacket(
+ return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
packet_number, should_include_version, largest_received,
- smallest_received, least_unacked, stream_id, parent_stream_id,
- ConvertRequestPriorityToQuicPriority(request_priority), offset);
+ smallest_received, least_unacked, priority_frames, offset);
}
// Uses default QuicTestPacketMaker.
@@ -568,6 +567,26 @@ class QuicNetworkTransactionTest : public PlatformTest,
std::move(headers), parent_stream_id, offset);
}
+ std::unique_ptr<QuicReceivedPacket>
+ ConstructClientRequestHeadersAndDataFramesPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ RequestPriority request_priority,
+ SpdyHeaderBlock headers,
+ QuicStreamId parent_stream_id,
+ QuicStreamOffset* offset,
+ size_t* spdy_headers_frame_length,
+ const std::vector<std::string>& data_writes) {
+ SpdyPriority priority =
+ ConvertRequestPriorityToQuicPriority(request_priority);
+ return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
+ packet_number, stream_id, should_include_version, fin, priority,
+ std::move(headers), parent_stream_id, offset, spdy_headers_frame_length,
+ data_writes);
+ }
+
std::unique_ptr<QuicEncryptedPacket> ConstructClientMultipleDataFramesPacket(
QuicPacketNumber packet_number,
QuicStreamId stream_id,
@@ -837,7 +856,7 @@ class QuicNetworkTransactionTest : public PlatformTest,
session_context_.proxy_delegate = &test_proxy_delegate;
proxy_resolution_service_ =
ProxyResolutionService::CreateFixedFromPacResult(
- "HTTPS myproxy.org:443");
+ "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
CreateSession();
EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
@@ -928,6 +947,7 @@ INSTANTIATE_TEST_CASE_P(
::testing::Bool()));
TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
+ session_params_.retry_without_alt_svc_on_quic_errors = false;
base::HistogramTester histograms;
session_params_.origins_to_force_quic_on.insert(
HostPortPair::FromString("mail.example.org:443"));
@@ -959,6 +979,7 @@ TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
}
TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
+ session_params_.retry_without_alt_svc_on_quic_errors = false;
base::HistogramTester histograms;
session_params_.origins_to_force_quic_on.insert(
HostPortPair::FromString("mail.example.org:443"));
@@ -1166,6 +1187,7 @@ TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
}
TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
+ session_params_.retry_without_alt_svc_on_quic_errors = false;
session_params_.origins_to_force_quic_on.insert(
HostPortPair::FromString("mail.example.org:443"));
@@ -1253,7 +1275,7 @@ TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
TEST_P(QuicNetworkTransactionTest, QuicProxy) {
session_params_.enable_quic = true;
proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
- "QUIC mail.example.org:70");
+ "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
MockQuicData mock_quic_data;
QuicStreamOffset header_stream_offset = 0;
@@ -1295,7 +1317,7 @@ TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
session_params_.enable_quic = true;
proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
- "QUIC " + proxy_host + ":70");
+ "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
client_maker_.set_hostname(origin_host);
MockQuicData mock_quic_data;
@@ -2050,6 +2072,7 @@ TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
// Verify that if a QUIC connection times out, the QuicHttpStream will
// return QUIC_PROTOCOL_ERROR.
TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
+ session_params_.retry_without_alt_svc_on_quic_errors = false;
session_params_.quic_idle_connection_timeout_seconds = 5;
// The request will initially go out over QUIC.
@@ -2143,6 +2166,7 @@ TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
// Verify that if a QUIC connection RTOs, the QuicHttpStream will
// return QUIC_PROTOCOL_ERROR.
TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
+ session_params_.retry_without_alt_svc_on_quic_errors = false;
session_params_.quic_connection_options.push_back(k5RTO);
// The request will initially go out over QUIC.
@@ -2345,6 +2369,7 @@ TEST_P(QuicNetworkTransactionTest,
// Verify that if a QUIC protocol error occurs after the handshake is confirmed
// the request fails with QUIC_PROTOCOL_ERROR.
TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
+ session_params_.retry_without_alt_svc_on_quic_errors = false;
// The request will initially go out over QUIC.
MockQuicData quic_data;
QuicStreamOffset header_stream_offset = 0;
@@ -2527,7 +2552,6 @@ TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
// connection times out, then QUIC will be marked as broken and the request
// retried over TCP.
TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
- session_params_.retry_without_alt_svc_on_quic_errors = true;
session_params_.quic_idle_connection_timeout_seconds = 5;
// The request will initially go out over QUIC.
@@ -2997,7 +3021,6 @@ TEST_P(QuicNetworkTransactionTest,
// retried over TCP and the QUIC will be marked as broken.
TEST_P(QuicNetworkTransactionTest,
ProtocolErrorAfterHandshakeConfirmedThenBroken) {
- session_params_.retry_without_alt_svc_on_quic_errors = true;
session_params_.quic_idle_connection_timeout_seconds = 5;
// The request will initially go out over QUIC.
@@ -3085,8 +3108,6 @@ TEST_P(QuicNetworkTransactionTest,
// request is reset from, then QUIC will be marked as broken and the request
// retried over TCP.
TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
- session_params_.retry_without_alt_svc_on_quic_errors = true;
-
// The request will initially go out over QUIC.
MockQuicData quic_data;
QuicStreamOffset header_stream_offset = 0;
@@ -3247,7 +3268,6 @@ TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
TEST_P(QuicNetworkTransactionTest,
ResetPooledAfterHandshakeConfirmedThenBroken) {
session_params_.quic_allow_remote_alt_svc = true;
- session_params_.retry_without_alt_svc_on_quic_errors = true;
GURL origin1 = request_.url;
GURL origin2("https://www.example.org/");
@@ -3374,10 +3394,10 @@ TEST_P(QuicNetworkTransactionTest,
SendRequestAndExpectHttpResponse("hello world");
}
-// When multiple alternative services are advertised,
-// HttpStreamFactoryImpl::RequestStreamInternal() should select the alternative
-// service which uses existing QUIC session if available. If no existing QUIC
-// session can be used, use the first alternative service from the list.
+// When multiple alternative services are advertised, HttpStreamFactoryImpl
+// should select the alternative service which uses existing QUIC session if
+// available. If no existing QUIC session can be used, use the first alternative
+// service from the list.
TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
session_params_.quic_allow_remote_alt_svc = true;
MockRead http_reads[] = {
@@ -3492,7 +3512,7 @@ TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
TestProxyDelegate test_proxy_delegate;
proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
- "HTTPS mail.example.org:443");
+ "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
test_proxy_delegate.set_alternative_proxy_server(
ProxyServer::FromPacString("QUIC mail.example.org:443"));
@@ -3889,7 +3909,7 @@ TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
base::HistogramTester histogram_tester;
proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
- "HTTPS mail.example.org:443");
+ "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
MockQuicData mock_quic_data;
QuicStreamOffset header_stream_offset = 0;
@@ -4054,8 +4074,8 @@ TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
}
TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
- proxy_resolution_service_ =
- ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70");
+ proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
// Since we are using a proxy, the QUIC job will not succeed.
MockWrite http_writes[] = {
@@ -4144,6 +4164,7 @@ TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
TEST_P(QuicNetworkTransactionTest,
LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
+ session_params_.retry_without_alt_svc_on_quic_errors = false;
MockQuicData mock_quic_data;
QuicStreamOffset header_stream_offset = 0;
mock_quic_data.AddWrite(
@@ -4197,6 +4218,7 @@ TEST_P(QuicNetworkTransactionTest,
TEST_P(QuicNetworkTransactionTest,
LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
+ session_params_.retry_without_alt_svc_on_quic_errors = false;
MockQuicData mock_quic_data;
QuicStreamOffset header_stream_offset = 0;
mock_quic_data.AddWrite(
@@ -4315,6 +4337,7 @@ TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
}
TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
+ session_params_.retry_without_alt_svc_on_quic_errors = false;
MockQuicData mock_quic_data;
QuicStreamOffset header_stream_offset = 0;
mock_quic_data.AddWrite(
@@ -4781,8 +4804,8 @@ TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
session_context_.proxy_delegate = &test_proxy_delegate;
- proxy_resolution_service_ =
- ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy.org:443");
+ proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
+ "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
request_.url = GURL("http://mail.example.org/");
// In order for a new QUIC session to be established via alternate-protocol
@@ -4837,7 +4860,7 @@ TEST_P(QuicNetworkTransactionTest,
DISABLED_QuicUploadToAlternativeProxyServer) {
base::HistogramTester histogram_tester;
proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
- "HTTPS mail.example.org:443");
+ "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
TestProxyDelegate test_proxy_delegate;
@@ -4910,6 +4933,7 @@ TEST_P(QuicNetworkTransactionTest, QuicUpload) {
}
TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
+ session_params_.retry_without_alt_svc_on_quic_errors = false;
ScopedMockNetworkChangeNotifier network_change_notifier;
MockNetworkChangeNotifier* mock_ncn =
network_change_notifier.mock_network_change_notifier();
@@ -5015,6 +5039,7 @@ TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
}
TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
+ session_params_.retry_without_alt_svc_on_quic_errors = false;
session_params_.origins_to_force_quic_on.insert(
HostPortPair::FromString("mail.example.org:443"));
@@ -5052,6 +5077,7 @@ TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
}
TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
+ session_params_.retry_without_alt_svc_on_quic_errors = false;
session_params_.origins_to_force_quic_on.insert(
HostPortPair::FromString("mail.example.org:443"));
@@ -5089,6 +5115,7 @@ TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
}
TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
+ session_params_.retry_without_alt_svc_on_quic_errors = false;
session_params_.origins_to_force_quic_on.insert(
HostPortPair::FromString("mail.example.org:443"));
const QuicString error_details =
@@ -5192,6 +5219,7 @@ TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
// is closed before the pushed headers arrive, but after the connection
// is closed and before the callbacks are executed.
TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
+ session_params_.retry_without_alt_svc_on_quic_errors = false;
session_params_.origins_to_force_quic_on.insert(
HostPortPair::FromString("mail.example.org:443"));
@@ -5278,14 +5306,10 @@ TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
QuicStreamOffset offset = 0;
mock_quic_data.AddWrite(ConstructInitialSettingsPacket(1, &offset));
- mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket(
- 2, GetNthClientInitiatedStreamId(0), true, false,
- GetRequestHeaders("POST", "https", "/"), &offset));
- std::unique_ptr<QuicEncryptedPacket> packet;
- packet = ConstructClientDataPacket(3, GetNthClientInitiatedStreamId(0), true,
- true, 0, "1");
- mock_quic_data.AddWrite(std::move(packet));
+ mock_quic_data.AddWrite(ConstructClientRequestHeadersAndDataFramesPacket(
+ 2, GetNthClientInitiatedStreamId(0), true, true, DEFAULT_PRIORITY,
+ GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr, {"1"}));
mock_quic_data.AddRead(ConstructServerResponseHeadersPacket(
1, GetNthClientInitiatedStreamId(0), false, false,
@@ -5294,7 +5318,7 @@ TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mock_quic_data.AddRead(ConstructServerDataPacket(
2, GetNthClientInitiatedStreamId(0), false, true, 0, "hello!"));
- mock_quic_data.AddWrite(ConstructClientAckPacket(4, 2, 1, 1));
+ mock_quic_data.AddWrite(ConstructClientAckPacket(3, 2, 1, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mock_quic_data.AddRead(ASYNC, 0); // EOF
@@ -6068,13 +6092,11 @@ TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
client_packet_number++, GetNthServerInitiatedStreamId(0),
QUIC_STREAM_CANCELLED, 5, 5, 1));
const char kBody[] = "1";
- mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket(
- client_packet_number++, GetNthClientInitiatedStreamId(1), false, false,
- GetRequestHeaders("GET", "https", "/pushed.jpg"),
- GetNthServerInitiatedStreamId(0), &header_stream_offset));
- mock_quic_data.AddWrite(ConstructClientMultipleDataFramesPacket(
+ mock_quic_data.AddWrite(ConstructClientRequestHeadersAndDataFramesPacket(
client_packet_number++, GetNthClientInitiatedStreamId(1), false, true,
- {kBody}, 0));
+ DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
+ GetNthServerInitiatedStreamId(0), &header_stream_offset, nullptr,
+ {kBody}));
// We see the same response as for the earlier pushed and cancelled
// stream.
@@ -6168,7 +6190,7 @@ TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
session_params_.enable_quic = true;
proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
- "QUIC proxy.example.org:70");
+ "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
MockQuicData mock_quic_data;
QuicStreamOffset header_stream_offset = 0;
@@ -6237,7 +6259,7 @@ TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
session_params_.enable_quic = true;
proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
- "QUIC proxy.example.org:70");
+ "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
MockQuicData mock_quic_data;
QuicStreamOffset header_stream_offset = 0;
@@ -6310,7 +6332,7 @@ TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
session_params_.enable_quic = true;
proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
- "QUIC proxy.example.org:70");
+ "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
MockQuicData mock_quic_data;
QuicStreamOffset header_stream_offset = 0;
@@ -6425,7 +6447,7 @@ TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
session_params_.enable_quic = true;
proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
- "QUIC proxy.example.org:70");
+ "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
MockQuicData mock_quic_data;
QuicStreamOffset client_header_stream_offset = 0;
@@ -6549,7 +6571,7 @@ TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
session_params_.enable_quic = true;
proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
- "QUIC proxy.example.org:70");
+ "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
MockQuicData mock_quic_data;
QuicStreamOffset header_stream_offset = 0;
@@ -6591,7 +6613,7 @@ TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
session_params_.enable_quic = true;
proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
- "QUIC proxy.example.org:70");
+ "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
MockQuicData mock_quic_data;
QuicStreamOffset header_stream_offset = 0;
@@ -6626,7 +6648,7 @@ TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
session_params_.enable_quic = true;
proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
- "QUIC proxy.example.org:70");
+ "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
MockQuicData mock_quic_data;
QuicStreamOffset client_header_stream_offset = 0;
@@ -6720,7 +6742,7 @@ TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
session_params_.enable_quic = true;
proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
- "QUIC proxy.example.org:70");
+ "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
MockQuicData mock_quic_data;
QuicStreamOffset header_stream_offset = 0;
@@ -6762,7 +6784,7 @@ TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
session_params_.enable_quic = true;
proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
- "QUIC proxy.example.org:70");
+ "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
const RequestPriority request_priority = MEDIUM;
@@ -6817,7 +6839,7 @@ TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
session_params_.enable_quic = true;
proxy_resolution_service_ =
ProxyResolutionService::CreateFixedFromPacResult(
- "QUIC proxy.example.org:70");
+ "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
MockQuicData mock_quic_data;
QuicStreamOffset client_header_stream_offset = 0;
@@ -7004,8 +7026,10 @@ TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
4, client_stream_0, push_stream_0, false,
GetRequestHeaders("GET", "https", "/pushed_0.jpg"), &server_header_offset,
&server_maker_));
- mock_quic_data.AddWrite(ConstructClientAckAndPriorityPacket(
- 6, false, 4, 3, 1, push_stream_0, client_stream_2, DEFAULT_PRIORITY,
+ mock_quic_data.AddWrite(ConstructClientAckAndPriorityFramesPacket(
+ 6, false, 4, 3, 1,
+ {{push_stream_0, client_stream_2,
+ ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
&header_stream_offset));
mock_quic_data.AddRead(ConstructServerPushPromisePacket(
5, client_stream_0, push_stream_1, false,
@@ -7027,29 +7051,30 @@ TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
// Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
// priority updates to match the request's priority. Client sends PRIORITY
// frames to inform server of new HTTP/2 stream dependencies.
- mock_quic_data.AddWrite(ConstructClientAckAndPriorityPacket(
- 9, false, 7, 7, 1, push_stream_1, client_stream_2, DEFAULT_PRIORITY,
+ mock_quic_data.AddWrite(ConstructClientAckAndPriorityFramesPacket(
+ 9, false, 7, 7, 1,
+ {{push_stream_1, client_stream_2,
+ ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
+ {push_stream_0, client_stream_0,
+ ConvertRequestPriorityToQuicPriority(HIGHEST)}},
&header_stream_offset));
- mock_quic_data.AddWrite(
- ConstructClientPriorityPacket(10, false, push_stream_0, client_stream_0,
- HIGHEST, &header_stream_offset));
// Server sends data for the three requests and the two push promises.
mock_quic_data.AddRead(ConstructServerDataPacket(8, client_stream_0, false,
true, 0, "hello 0!"));
mock_quic_data.AddSynchronousRead(ConstructServerDataPacket(
9, client_stream_1, false, true, 0, "hello 1!"));
- mock_quic_data.AddWrite(ConstructClientAckPacket(11, 9, 8, 1));
+ mock_quic_data.AddWrite(ConstructClientAckPacket(10, 9, 8, 1));
mock_quic_data.AddRead(ConstructServerDataPacket(10, client_stream_2, false,
true, 0, "hello 2!"));
mock_quic_data.AddSynchronousRead(ConstructServerDataPacket(
11, push_stream_0, false, true, 0, "and hello 0!"));
- mock_quic_data.AddWrite(ConstructClientAckPacket(12, 11, 10, 1));
+ mock_quic_data.AddWrite(ConstructClientAckPacket(11, 11, 10, 1));
mock_quic_data.AddRead(ConstructServerDataPacket(12, push_stream_1, false,
true, 0, "and hello 1!"));
mock_quic_data.AddWrite(ConstructClientAckAndRstPacket(
- 13, push_stream_0, QUIC_RST_ACKNOWLEDGEMENT, 12, 12, 1));
+ 12, push_stream_0, QUIC_RST_ACKNOWLEDGEMENT, 12, 12, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mock_quic_data.AddRead(ASYNC, 0); // EOF
diff --git a/chromium/net/quic/chromium/quic_proxy_client_socket_unittest.cc b/chromium/net/quic/chromium/quic_proxy_client_socket_unittest.cc
index b87795d17b7..cd205c97287 100644
--- a/chromium/net/quic/chromium/quic_proxy_client_socket_unittest.cc
+++ b/chromium/net/quic/chromium/quic_proxy_client_socket_unittest.cc
@@ -25,6 +25,7 @@
#include "net/quic/chromium/quic_chromium_packet_writer.h"
#include "net/quic/chromium/quic_http_utils.h"
#include "net/quic/chromium/quic_server_info.h"
+#include "net/quic/chromium/quic_stream_factory.h"
#include "net/quic/chromium/quic_test_packet_maker.h"
#include "net/quic/chromium/test_task_runner.h"
#include "net/quic/core/crypto/null_encrypter.h"
@@ -1362,13 +1363,8 @@ TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePending) {
mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
mock_quic_data_.AddAsyncWrite(
ConstructAckAndDataPacket(3, 1, 1, 1, 0, kMsg2, kLen2));
- if (FLAGS_quic_reloadable_flag_quic_use_control_frame_manager) {
mock_quic_data_.AddWrite(
ConstructAckAndRstPacket(4, QUIC_RST_ACKNOWLEDGEMENT, 2, 2, 1, kLen2));
- } else {
- mock_quic_data_.AddWrite(
- ConstructRstPacket(4, QUIC_RST_ACKNOWLEDGEMENT, kLen2));
- }
Initialize();
@@ -1485,13 +1481,8 @@ TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
mock_quic_data_.AddAsyncWrite(
ConstructAckAndDataPacket(3, 1, 1, 1, 0, kMsg1, kLen1));
- if (FLAGS_quic_reloadable_flag_quic_use_control_frame_manager) {
mock_quic_data_.AddWrite(
ConstructAckAndRstPacket(4, QUIC_RST_ACKNOWLEDGEMENT, 2, 2, 1, kLen1));
- } else {
- mock_quic_data_.AddWrite(
- ConstructRstPacket(4, QUIC_RST_ACKNOWLEDGEMENT, kLen1));
- }
Initialize();
diff --git a/chromium/net/quic/chromium/quic_stream_factory.cc b/chromium/net/quic/chromium/quic_stream_factory.cc
index 6e816ad9edf..9448749cd60 100644
--- a/chromium/net/quic/chromium/quic_stream_factory.cc
+++ b/chromium/net/quic/chromium/quic_stream_factory.cc
@@ -14,7 +14,6 @@
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
-#include "base/rand_util.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
@@ -32,6 +31,7 @@
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_verifier.h"
#include "net/dns/host_resolver.h"
+#include "net/log/net_log.h"
#include "net/log/net_log_capture_mode.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_source_type.h"
@@ -1346,7 +1346,7 @@ std::unique_ptr<DatagramClientSocket> QuicStreamFactory::CreateSocket(
NetLog* net_log,
const NetLogSource& source) {
auto socket = client_socket_factory_->CreateDatagramClientSocket(
- DatagramSocket::DEFAULT_BIND, RandIntCallback(), net_log, source);
+ DatagramSocket::DEFAULT_BIND, net_log, source);
if (enable_socket_recv_optimization_)
socket->EnableRecvOptimization();
return socket;
diff --git a/chromium/net/quic/chromium/quic_stream_factory.h b/chromium/net/quic/chromium/quic_stream_factory.h
index 92dab824bfc..041bd2e52e9 100644
--- a/chromium/net/quic/chromium/quic_stream_factory.h
+++ b/chromium/net/quic/chromium/quic_stream_factory.h
@@ -77,19 +77,13 @@ class QuicStreamFactoryPeer;
// When a connection is idle for 30 seconds it will be closed.
const int kIdleConnectionTimeoutSeconds = 30;
-enum QuicConnectionMigrationStatus {
- MIGRATION_STATUS_NO_MIGRATABLE_STREAMS,
- MIGRATION_STATUS_ALREADY_MIGRATED,
- MIGRATION_STATUS_INTERNAL_ERROR,
- MIGRATION_STATUS_TOO_MANY_CHANGES,
- MIGRATION_STATUS_SUCCESS,
- MIGRATION_STATUS_NON_MIGRATABLE_STREAM,
- MIGRATION_STATUS_NOT_ENABLED,
- MIGRATION_STATUS_NO_ALTERNATE_NETWORK,
- MIGRATION_STATUS_ON_PATH_DEGRADING_DISABLED,
- MIGRATION_STATUS_DISABLED_BY_CONFIG,
- MIGRATION_STATUS_MAX
-};
+// The default maximum time QUIC session could be on non-default network before
+// migrate back to default network.
+const int64_t kMaxTimeOnNonDefaultNetworkSecs = 128;
+
+// The default maximum number of migrations to non default network on path
+// degrading per network. Used in chromium only.
+const int64_t kMaxMigrationsToNonDefaultNetworkOnPathDegrading = 5;
enum QuicPlatformNotification {
NETWORK_CONNECTED,
diff --git a/chromium/net/quic/chromium/quic_stream_factory_test.cc b/chromium/net/quic/chromium/quic_stream_factory_test.cc
index 0122d1f6696..03c813265b5 100644
--- a/chromium/net/quic/chromium/quic_stream_factory_test.cc
+++ b/chromium/net/quic/chromium/quic_stream_factory_test.cc
@@ -40,7 +40,7 @@
#include "net/quic/core/crypto/quic_decrypter.h"
#include "net/quic/core/crypto/quic_encrypter.h"
#include "net/quic/core/quic_client_promised_info.h"
-#include "net/quic/platform/impl/quic_test_impl.h"
+#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/mock_clock.h"
#include "net/quic/test_tools/mock_random.h"
#include "net/quic/test_tools/quic_config_peer.h"
@@ -49,6 +49,7 @@
#include "net/socket/next_proto.h"
#include "net/socket/socket_test_util.h"
#include "net/spdy/chromium/spdy_session_test_util.h"
+#include "net/spdy/chromium/spdy_test_util_common.h"
#include "net/spdy/core/spdy_test_utils.h"
#include "net/ssl/channel_id_service.h"
#include "net/ssl/default_channel_id_store.h"
@@ -189,7 +190,6 @@ class TestConnectionMigrationSocketFactory : public MockClientSocketFactory {
std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
NetLog* net_log,
const NetLogSource& source) override {
SocketDataProvider* data_provider = mock_data().GetNext();
@@ -2067,11 +2067,7 @@ void QuicStreamFactoryTestBase::OnNetworkMadeDefault(bool async_write_before) {
// Do an async write to leave writer blocked.
if (async_write_before) {
- if (session->use_control_frame_manager()) {
- session->SendPing();
- } else {
- session->connection()->SendPing();
- }
+ session->SendPing();
}
// Set up second socket data provider that is used after migration.
@@ -2206,11 +2202,7 @@ void QuicStreamFactoryTestBase::OnNetworkDisconnected(bool async_write_before) {
// Do an async write to leave writer blocked.
if (async_write_before) {
- if (session->use_control_frame_manager()) {
- session->SendPing();
- } else {
- session->connection()->SendPing();
- }
+ session->SendPing();
}
// Set up second socket data provider that is used after migration.
diff --git a/chromium/net/quic/chromium/quic_test_packet_maker.cc b/chromium/net/quic/chromium/quic_test_packet_maker.cc
index 9676a59007d..70d83bb4234 100644
--- a/chromium/net/quic/chromium/quic_test_packet_maker.cc
+++ b/chromium/net/quic/chromium/quic_test_packet_maker.cc
@@ -439,8 +439,9 @@ QuicTestPacketMaker::MakeRequestHeadersAndMultipleDataFramesPacket(
size_t* spdy_headers_frame_length,
const std::vector<std::string>& data_writes) {
InitializeHeader(packet_number, should_include_version);
- SpdySerializedFrame spdy_frame = MakeSpdyHeadersFrame(
- stream_id, fin, priority, std::move(headers), parent_stream_id);
+ SpdySerializedFrame spdy_frame =
+ MakeSpdyHeadersFrame(stream_id, fin && data_writes.empty(), priority,
+ std::move(headers), parent_stream_id);
if (spdy_headers_frame_length) {
*spdy_headers_frame_length = spdy_frame.size();
@@ -451,6 +452,7 @@ QuicTestPacketMaker::MakeRequestHeadersAndMultipleDataFramesPacket(
QuicStreamFrame frame(kHeadersStreamId, false, header_offset,
QuicStringPiece(spdy_frame.data(), spdy_frame.size()));
frames.push_back(QuicFrame(&frame));
+ DVLOG(1) << "Adding frame: " << frames.back();
if (header_stream_offset != nullptr) {
*header_stream_offset += spdy_frame.size();
}
@@ -542,6 +544,45 @@ QuicTestPacketMaker::MakeRequestHeadersPacketAndSaveData(
}
}
+std::unique_ptr<QuicReceivedPacket>
+QuicTestPacketMaker::MakeRequestHeadersAndRstPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ SpdyPriority priority,
+ SpdyHeaderBlock headers,
+ QuicStreamId parent_stream_id,
+ size_t* spdy_headers_frame_length,
+ QuicStreamOffset* header_stream_offset,
+ QuicRstStreamErrorCode error_code,
+ size_t bytes_written) {
+ SpdySerializedFrame spdy_frame = MakeSpdyHeadersFrame(
+ stream_id, fin, priority, std::move(headers), parent_stream_id);
+ if (spdy_headers_frame_length) {
+ *spdy_headers_frame_length = spdy_frame.size();
+ }
+ QuicStreamOffset header_offset = 0;
+ if (header_stream_offset != nullptr) {
+ header_offset = *header_stream_offset;
+ *header_stream_offset += spdy_frame.size();
+ }
+ QuicStreamFrame headers_frame(
+ kHeadersStreamId, false, header_offset,
+ QuicStringPiece(spdy_frame.data(), spdy_frame.size()));
+
+ QuicRstStreamFrame rst_frame(1, stream_id, error_code, bytes_written);
+
+ QuicFrames frames;
+ frames.push_back(QuicFrame(&headers_frame));
+ DVLOG(1) << "Adding frame: " << frames.back();
+ frames.push_back(QuicFrame(&rst_frame));
+ DVLOG(1) << "Adding frame: " << frames.back();
+
+ InitializeHeader(packet_number, should_include_version);
+ return MakeMultipleFramesPacket(header_, frames);
+}
+
SpdySerializedFrame QuicTestPacketMaker::MakeSpdyHeadersFrame(
QuicStreamId stream_id,
bool fin,
@@ -830,15 +871,13 @@ std::unique_ptr<QuicReceivedPacket> QuicTestPacketMaker::MakePriorityPacket(
}
std::unique_ptr<QuicReceivedPacket>
-QuicTestPacketMaker::MakeAckAndPriorityPacket(
+QuicTestPacketMaker::MakeAckAndMultiplePriorityFramesPacket(
QuicPacketNumber packet_number,
bool should_include_version,
QuicPacketNumber largest_received,
QuicPacketNumber smallest_received,
QuicPacketNumber least_unacked,
- QuicStreamId stream_id,
- QuicStreamId parent_stream_id,
- SpdyPriority spdy_priority,
+ const std::vector<Http2StreamDependency>& priority_frames,
QuicStreamOffset* offset) {
QuicAckFrame ack(MakeAckFrame(largest_received));
ack.ack_delay_time = QuicTime::Delta::Zero();
@@ -857,22 +896,33 @@ QuicTestPacketMaker::MakeAckAndPriorityPacket(
frames.push_back(QuicFrame(&stop_waiting));
DVLOG(1) << "Adding frame: " << frames[1];
- bool exclusive = client_headers_include_h2_stream_dependency_;
- SpdyPriorityIR priority_frame(stream_id, parent_stream_id,
- Spdy3PriorityToHttp2Weight(spdy_priority),
- exclusive);
- SpdySerializedFrame spdy_frame =
- spdy_request_framer_.SerializeFrame(priority_frame);
+ const bool exclusive = client_headers_include_h2_stream_dependency_;
QuicStreamOffset header_offset = 0;
- if (offset != nullptr) {
- header_offset = *offset;
- *offset += spdy_frame.size();
+ if (offset == nullptr) {
+ offset = &header_offset;
+ }
+ // Keep SpdySerializedFrames alive until MakeMultipleFramesPacket is done.
+ // Keep StreamFrames alive until MakeMultipleFramesPacket is done.
+ std::vector<std::unique_ptr<SpdySerializedFrame>> spdy_frames;
+ std::vector<std::unique_ptr<QuicStreamFrame>> stream_frames;
+ for (const Http2StreamDependency& info : priority_frames) {
+ SpdyPriorityIR priority_frame(
+ info.stream_id, info.parent_stream_id,
+ Spdy3PriorityToHttp2Weight(info.spdy_priority), exclusive);
+
+ spdy_frames.push_back(std::make_unique<SpdySerializedFrame>(
+ spdy_request_framer_.SerializeFrame(priority_frame)));
+
+ SpdySerializedFrame* spdy_frame = spdy_frames.back().get();
+ stream_frames.push_back(std::make_unique<QuicStreamFrame>(
+ kHeadersStreamId, false, *offset,
+ QuicStringPiece(spdy_frame->data(), spdy_frame->size())));
+ *offset += spdy_frame->size();
+
+ frames.push_back(QuicFrame(stream_frames.back().get()));
+ DVLOG(1) << "Adding frame: " << frames.back();
+ ;
}
- QuicStreamFrame priority(
- kHeadersStreamId, false, header_offset,
- QuicStringPiece(spdy_frame.data(), spdy_frame.size()));
- frames.push_back(QuicFrame(&priority));
- DVLOG(1) << "Adding frame: " << frames[2];
InitializeHeader(packet_number, should_include_version);
return MakeMultipleFramesPacket(header_, frames);
diff --git a/chromium/net/quic/chromium/quic_test_packet_maker.h b/chromium/net/quic/chromium/quic_test_packet_maker.h
index 925596dee09..c5a4a2b10b4 100644
--- a/chromium/net/quic/chromium/quic_test_packet_maker.h
+++ b/chromium/net/quic/chromium/quic_test_packet_maker.h
@@ -27,6 +27,12 @@ namespace test {
class QuicTestPacketMaker {
public:
+ struct Http2StreamDependency {
+ QuicStreamId stream_id;
+ QuicStreamId parent_stream_id;
+ SpdyPriority spdy_priority;
+ };
+
// |client_headers_include_h2_stream_dependency| affects the output of
// the MakeRequestHeaders...() methods. If its value is true, then request
// headers are constructed with the exclusive flag set to true and the parent
@@ -194,6 +200,19 @@ class QuicTestPacketMaker {
QuicStreamOffset* offset,
std::string* stream_data);
+ std::unique_ptr<QuicReceivedPacket> MakeRequestHeadersAndRstPacket(
+ QuicPacketNumber packet_number,
+ QuicStreamId stream_id,
+ bool should_include_version,
+ bool fin,
+ SpdyPriority priority,
+ SpdyHeaderBlock headers,
+ QuicStreamId parent_stream_id,
+ size_t* spdy_headers_frame_length,
+ QuicStreamOffset* header_stream_offset,
+ QuicRstStreamErrorCode error_code,
+ size_t bytes_written);
+
// Convenience method for calling MakeRequestHeadersPacket with nullptr for
// |spdy_headers_frame_length|.
std::unique_ptr<QuicReceivedPacket>
@@ -268,15 +287,13 @@ class QuicTestPacketMaker {
SpdyPriority priority,
QuicStreamOffset* offset);
- std::unique_ptr<QuicReceivedPacket> MakeAckAndPriorityPacket(
+ std::unique_ptr<QuicReceivedPacket> MakeAckAndMultiplePriorityFramesPacket(
QuicPacketNumber packet_number,
bool should_include_version,
QuicPacketNumber largest_received,
QuicPacketNumber smallest_received,
QuicPacketNumber least_unacked,
- QuicStreamId stream_id,
- QuicStreamId parent_stream_id,
- SpdyPriority spdy_priority,
+ const std::vector<Http2StreamDependency>& priority_frames,
QuicStreamOffset* offset);
SpdyHeaderBlock GetRequestHeaders(const std::string& method,
diff --git a/chromium/net/quic/core/congestion_control/bandwidth_sampler.h b/chromium/net/quic/core/congestion_control/bandwidth_sampler.h
index b42e8b91569..4255e614650 100644
--- a/chromium/net/quic/core/congestion_control/bandwidth_sampler.h
+++ b/chromium/net/quic/core/congestion_control/bandwidth_sampler.h
@@ -9,7 +9,6 @@
#include "net/quic/core/quic_bandwidth.h"
#include "net/quic/core/quic_packets.h"
#include "net/quic/core/quic_time.h"
-#include "net/quic/platform/api/quic_containers.h"
#include "net/quic/platform/api/quic_export.h"
namespace net {
@@ -250,9 +249,6 @@ class QUIC_EXPORT_PRIVATE BandwidthSampler : public BandwidthSamplerInterface {
is_app_limited(false) {}
};
- typedef QuicLinkedHashMap<QuicPacketNumber, ConnectionStateOnSentPacket>
- ConnectionStateMap;
-
// The total number of congestion controlled bytes sent during the connection.
QuicByteCount total_bytes_sent_;
diff --git a/chromium/net/quic/core/congestion_control/bbr_sender.cc b/chromium/net/quic/core/congestion_control/bbr_sender.cc
index 05266e3176f..ecbdbd78b2f 100644
--- a/chromium/net/quic/core/congestion_control/bbr_sender.cc
+++ b/chromium/net/quic/core/congestion_control/bbr_sender.cc
@@ -138,6 +138,14 @@ BbrSender::BbrSender(const RttStats* rtt_stats,
BbrSender::~BbrSender() {}
+void BbrSender::SetInitialCongestionWindowInPackets(
+ QuicPacketCount congestion_window) {
+ if (mode_ == STARTUP) {
+ initial_congestion_window_ = congestion_window * kDefaultTCPMSS;
+ congestion_window_ = congestion_window * kDefaultTCPMSS;
+ }
+}
+
bool BbrSender::InSlowStart() const {
return mode_ == STARTUP;
}
@@ -412,6 +420,11 @@ bool BbrSender::UpdateBandwidthAndMinRtt(
const AckedPacketVector& acked_packets) {
QuicTime::Delta sample_min_rtt = QuicTime::Delta::Infinite();
for (const auto& packet : acked_packets) {
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3) &&
+ packet.bytes_acked == 0) {
+ // Skip acked packets with 0 in flight bytes when updating bandwidth.
+ continue;
+ }
BandwidthSample bandwidth_sample =
sampler_->OnPacketAcknowledged(now, packet.packet_number);
last_sample_is_app_limited_ = bandwidth_sample.is_app_limited;
diff --git a/chromium/net/quic/core/congestion_control/bbr_sender.h b/chromium/net/quic/core/congestion_control/bbr_sender.h
index b351665bcd7..46993fc2891 100644
--- a/chromium/net/quic/core/congestion_control/bbr_sender.h
+++ b/chromium/net/quic/core/congestion_control/bbr_sender.h
@@ -109,6 +109,8 @@ class QUIC_EXPORT_PRIVATE BbrSender : public SendAlgorithmInterface {
void AdjustNetworkParameters(QuicBandwidth bandwidth,
QuicTime::Delta rtt) override;
void SetNumEmulatedConnections(int num_connections) override {}
+ void SetInitialCongestionWindowInPackets(
+ QuicPacketCount congestion_window) override;
void OnCongestionEvent(bool rtt_updated,
QuicByteCount prior_in_flight,
QuicTime event_time,
diff --git a/chromium/net/quic/core/congestion_control/bbr_sender_test.cc b/chromium/net/quic/core/congestion_control/bbr_sender_test.cc
index 3de677b22ca..38fee561d62 100644
--- a/chromium/net/quic/core/congestion_control/bbr_sender_test.cc
+++ b/chromium/net/quic/core/congestion_control/bbr_sender_test.cc
@@ -250,6 +250,12 @@ class BbrSenderTest : public QuicTest {
}
};
+TEST_F(BbrSenderTest, SetInitialCongestionWindow) {
+ EXPECT_NE(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
+ sender_->SetInitialCongestionWindowInPackets(3);
+ EXPECT_EQ(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
+}
+
// Test a simple long data transfer in the default setup.
TEST_F(BbrSenderTest, SimpleTransfer) {
// Adding TSO CWND causes packet loss before exiting startup.
diff --git a/chromium/net/quic/core/congestion_control/rtt_stats.cc b/chromium/net/quic/core/congestion_control/rtt_stats.cc
index 8bf8b6bc4a8..9e098d17f4b 100644
--- a/chromium/net/quic/core/congestion_control/rtt_stats.cc
+++ b/chromium/net/quic/core/congestion_control/rtt_stats.cc
@@ -70,12 +70,8 @@ void RttStats::UpdateRtt(QuicTime::Delta send_delta,
// an RTT sample at least as large as min_rtt. Otherwise, only use the
// send_delta.
if (rtt_sample > ack_delay) {
- if (GetQuicReloadableFlag(quic_min_rtt_ack_delay)) {
- if (rtt_sample - min_rtt_ >= ack_delay) {
- max_ack_delay_ = std::max(max_ack_delay_, ack_delay);
- rtt_sample = rtt_sample - ack_delay;
- }
- } else {
+ if (rtt_sample - min_rtt_ >= ack_delay) {
+ max_ack_delay_ = std::max(max_ack_delay_, ack_delay);
rtt_sample = rtt_sample - ack_delay;
}
}
diff --git a/chromium/net/quic/core/congestion_control/rtt_stats_test.cc b/chromium/net/quic/core/congestion_control/rtt_stats_test.cc
index 1e026bab5af..bc065e094cb 100644
--- a/chromium/net/quic/core/congestion_control/rtt_stats_test.cc
+++ b/chromium/net/quic/core/congestion_control/rtt_stats_test.cc
@@ -30,29 +30,6 @@ TEST_F(RttStatsTest, DefaultsBeforeUpdate) {
}
TEST_F(RttStatsTest, SmoothedRtt) {
- SetQuicReloadableFlag(quic_min_rtt_ack_delay, false);
- // Verify that ack_delay is corrected for in Smoothed RTT.
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
- QuicTime::Delta::FromMilliseconds(100),
- QuicTime::Zero());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
- // Verify that effective RTT of zero does not change Smoothed RTT.
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
- QuicTime::Delta::FromMilliseconds(200),
- QuicTime::Zero());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
- // Verify that large erroneous ack_delay does not change Smoothed RTT.
- rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(200),
- QuicTime::Delta::FromMilliseconds(300),
- QuicTime::Zero());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
-}
-
-TEST_F(RttStatsTest, SmoothedRttMaxAckDelay) {
- SetQuicReloadableFlag(quic_min_rtt_ack_delay, true);
// Verify that ack_delay is ignored in the first measurement.
rtt_stats_.UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
QuicTime::Delta::FromMilliseconds(100),
@@ -241,10 +218,7 @@ TEST_F(RttStatsTest, ResetAfterConnectionMigrations) {
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.latest_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.smoothed_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200), rtt_stats_.min_rtt());
- if (GetQuicReloadableFlag(quic_min_rtt_ack_delay)) {
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100),
- rtt_stats_.max_ack_delay());
- }
+ EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats_.max_ack_delay());
// Reset rtt stats on connection migrations.
rtt_stats_.OnConnectionMigration();
diff --git a/chromium/net/quic/core/congestion_control/send_algorithm_interface.h b/chromium/net/quic/core/congestion_control/send_algorithm_interface.h
index 3b68b9e59fd..df25ba17523 100644
--- a/chromium/net/quic/core/congestion_control/send_algorithm_interface.h
+++ b/chromium/net/quic/core/congestion_control/send_algorithm_interface.h
@@ -49,6 +49,10 @@ class QUIC_EXPORT_PRIVATE SendAlgorithmInterface {
// particularly for congestion avoidance. Can be set any time.
virtual void SetNumEmulatedConnections(int num_connections) = 0;
+ // Sets the initial congestion window in number of packets. May be ignored
+ // if called after the initial congestion window is no longer relevant.
+ virtual void SetInitialCongestionWindowInPackets(QuicPacketCount packets) = 0;
+
// Indicates an update to the congestion state, caused either by an incoming
// ack or loss event timeout. |rtt_updated| indicates whether a new
// latest_rtt sample has been taken, |prior_in_flight| the bytes in flight
diff --git a/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.cc b/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
index f3e77cfccbb..55cda43d009 100644
--- a/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
+++ b/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
@@ -62,30 +62,32 @@ TcpCubicSenderBytes::~TcpCubicSenderBytes() {}
void TcpCubicSenderBytes::SetFromConfig(const QuicConfig& config,
Perspective perspective) {
if (perspective == Perspective::IS_SERVER) {
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW03)) {
- // Initial window experiment.
- SetCongestionWindowInPackets(3);
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) {
- // Initial window experiment.
- SetCongestionWindowInPackets(10);
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW20)) {
- // Initial window experiment.
- SetCongestionWindowInPackets(20);
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kIW50)) {
- // Initial window experiment.
- SetCongestionWindowInPackets(50);
- }
- if (config.HasReceivedConnectionOptions() &&
- ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) {
- // Min CWND experiment.
- SetMinCongestionWindowInPackets(1);
+ if (!GetQuicReloadableFlag(quic_unified_iw_options)) {
+ if (config.HasReceivedConnectionOptions() &&
+ ContainsQuicTag(config.ReceivedConnectionOptions(), kIW03)) {
+ // Initial window experiment.
+ SetInitialCongestionWindowInPackets(3);
+ }
+ if (config.HasReceivedConnectionOptions() &&
+ ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) {
+ // Initial window experiment.
+ SetInitialCongestionWindowInPackets(10);
+ }
+ if (config.HasReceivedConnectionOptions() &&
+ ContainsQuicTag(config.ReceivedConnectionOptions(), kIW20)) {
+ // Initial window experiment.
+ SetInitialCongestionWindowInPackets(20);
+ }
+ if (config.HasReceivedConnectionOptions() &&
+ ContainsQuicTag(config.ReceivedConnectionOptions(), kIW50)) {
+ // Initial window experiment.
+ SetInitialCongestionWindowInPackets(50);
+ }
+ if (config.HasReceivedConnectionOptions() &&
+ ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) {
+ // Min CWND experiment.
+ SetMinCongestionWindowInPackets(1);
+ }
}
if (config.HasReceivedConnectionOptions() &&
ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN4)) {
@@ -272,7 +274,7 @@ void TcpCubicSenderBytes::SetCongestionWindowFromBandwidthAndRtt(
kMaxResumptionCongestionWindow * kDefaultTCPMSS));
}
-void TcpCubicSenderBytes::SetCongestionWindowInPackets(
+void TcpCubicSenderBytes::SetInitialCongestionWindowInPackets(
QuicPacketCount congestion_window) {
congestion_window_ = congestion_window * kDefaultTCPMSS;
}
@@ -321,7 +323,7 @@ void TcpCubicSenderBytes::OnPacketLost(QuicPacketNumber packet_number,
prr_.OnPacketLost(prior_in_flight);
}
- // TODO(jri): Separate out all of slow start into a separate class.
+ // TODO(b/77268641): Separate out all of slow start into a separate class.
if (slow_start_large_reduction_ && InSlowStart()) {
DCHECK_LT(kDefaultTCPMSS, congestion_window_);
if (congestion_window_ >= 2 * initial_tcp_congestion_window_) {
diff --git a/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.h b/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.h
index fde4fbf835f..70071aeba2e 100644
--- a/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.h
+++ b/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes.h
@@ -48,6 +48,8 @@ class QUIC_EXPORT_PRIVATE TcpCubicSenderBytes : public SendAlgorithmInterface {
void AdjustNetworkParameters(QuicBandwidth bandwidth,
QuicTime::Delta rtt) override;
void SetNumEmulatedConnections(int num_connections) override;
+ void SetInitialCongestionWindowInPackets(
+ QuicPacketCount congestion_window) override;
void OnConnectionMigration() override;
void OnCongestionEvent(bool rtt_updated,
QuicByteCount prior_in_flight,
@@ -88,7 +90,6 @@ class QUIC_EXPORT_PRIVATE TcpCubicSenderBytes : public SendAlgorithmInterface {
QuicTime event_time);
void SetCongestionWindowFromBandwidthAndRtt(QuicBandwidth bandwidth,
QuicTime::Delta rtt);
- void SetCongestionWindowInPackets(QuicPacketCount congestion_window);
void SetMinCongestionWindowInPackets(QuicPacketCount congestion_window);
void ExitSlowstart();
void OnPacketLost(QuicPacketNumber largest_loss,
diff --git a/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc b/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
index 187a06036bb..d87be503cd6 100644
--- a/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
+++ b/chromium/net/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
@@ -544,6 +544,7 @@ TEST_F(TcpCubicSenderBytesTest, MultipleLossesInOneWindow) {
}
TEST_F(TcpCubicSenderBytesTest, ConfigureMaxInitialWindow) {
+ SetQuicReloadableFlag(quic_unified_iw_options, false);
QuicConfig config;
// Verify that kCOPT: kIW10 forces the congestion window to the default of 10.
@@ -554,6 +555,12 @@ TEST_F(TcpCubicSenderBytesTest, ConfigureMaxInitialWindow) {
EXPECT_EQ(10u * kDefaultTCPMSS, sender_->GetCongestionWindow());
}
+TEST_F(TcpCubicSenderBytesTest, SetInitialCongestionWindow) {
+ EXPECT_NE(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
+ sender_->SetInitialCongestionWindowInPackets(3);
+ EXPECT_EQ(3u * kDefaultTCPMSS, sender_->GetCongestionWindow());
+}
+
TEST_F(TcpCubicSenderBytesTest, 2ConnectionCongestionAvoidanceAtEndOfRecovery) {
sender_->SetNumEmulatedConnections(2);
// Ack 10 packets in 5 acks to raise the CWND to 20.
diff --git a/chromium/net/quic/core/crypto/cert_compressor.cc b/chromium/net/quic/core/crypto/cert_compressor.cc
index a8cefbcc9b4..a2670935e5e 100644
--- a/chromium/net/quic/core/crypto/cert_compressor.cc
+++ b/chromium/net/quic/core/crypto/cert_compressor.cc
@@ -12,6 +12,8 @@
#include "net/quic/platform/api/quic_string.h"
#include "third_party/zlib/zlib.h"
+using std::string;
+
namespace net {
namespace {
@@ -401,7 +403,7 @@ bool ParseEntries(QuicStringPiece* in_out,
if (cert.empty()) {
return false;
}
- out_certs->push_back(cert.as_string());
+ out_certs->push_back(string(cert));
break;
}
default:
@@ -627,7 +629,7 @@ bool CertCompressor::DecompressChain(
if (uncompressed.size() < cert_len) {
return false;
}
- (*out_certs)[i] = uncompressed.substr(0, cert_len).as_string();
+ (*out_certs)[i] = string(uncompressed.substr(0, cert_len));
uncompressed.remove_prefix(cert_len);
break;
case CertEntry::CACHED:
diff --git a/chromium/net/quic/core/crypto/common_cert_set.cc b/chromium/net/quic/core/crypto/common_cert_set.cc
index 83c3e976706..8d4c2ad35a7 100644
--- a/chromium/net/quic/core/crypto/common_cert_set.cc
+++ b/chromium/net/quic/core/crypto/common_cert_set.cc
@@ -10,6 +10,7 @@
#include "base/memory/singleton.h"
#include "net/quic/core/quic_utils.h"
#include "net/quic/platform/api/quic_arraysize.h"
+#include "net/quic/platform/api/quic_singleton.h"
namespace net {
@@ -143,14 +144,14 @@ class CommonCertSetsQUIC : public CommonCertSets {
}
static CommonCertSetsQUIC* GetInstance() {
- return base::Singleton<CommonCertSetsQUIC>::get();
+ return QuicSingleton<CommonCertSetsQUIC>::get();
}
private:
CommonCertSetsQUIC() {}
~CommonCertSetsQUIC() override {}
- friend struct base::DefaultSingletonTraits<CommonCertSetsQUIC>;
+ friend QuicSingletonFriend<CommonCertSetsQUIC>;
DISALLOW_COPY_AND_ASSIGN(CommonCertSetsQUIC);
};
diff --git a/chromium/net/quic/core/crypto/crypto_framer.cc b/chromium/net/quic/core/crypto/crypto_framer.cc
index 16c6e528d50..74ccacba2cc 100644
--- a/chromium/net/quic/core/crypto/crypto_framer.cc
+++ b/chromium/net/quic/core/crypto/crypto_framer.cc
@@ -9,11 +9,14 @@
#include "net/quic/core/quic_data_writer.h"
#include "net/quic/core/quic_packets.h"
#include "net/quic/platform/api/quic_fallthrough.h"
+#include "net/quic/platform/api/quic_logging.h"
#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/platform/api/quic_str_cat.h"
#include "net/quic/platform/api/quic_string.h"
#include "net/quic/platform/api/quic_string_piece.h"
+using std::string;
+
namespace net {
namespace {
@@ -45,7 +48,11 @@ class OneShotVisitor : public CryptoFramerVisitorInterface {
} // namespace
CryptoFramer::CryptoFramer()
- : visitor_(nullptr), error_detail_(""), num_entries_(0), values_len_(0) {
+ : visitor_(nullptr),
+ error_detail_(""),
+ num_entries_(0),
+ values_len_(0),
+ process_truncated_messages_(false) {
Clear();
}
@@ -302,11 +309,20 @@ QuicErrorCode CryptoFramer::Process(QuicStringPiece input,
}
case STATE_READING_VALUES:
if (reader.BytesRemaining() < values_len_) {
- break;
+ if (!process_truncated_messages_) {
+ break;
+ }
+ QUIC_LOG(ERROR) << "Trunacted message. Missing "
+ << values_len_ - reader.BytesRemaining() << " bytes.";
}
for (const std::pair<QuicTag, size_t>& item : tags_and_lengths_) {
QuicStringPiece value;
- reader.ReadStringPiece(&value, item.second);
+ if (!reader.ReadStringPiece(&value, item.second)) {
+ DCHECK(process_truncated_messages_);
+ // Store an empty value.
+ message_.SetStringPiece(item.first, "");
+ continue;
+ }
message_.SetStringPiece(item.first, value);
}
visitor_->OnHandshakeMessage(message_);
@@ -315,7 +331,7 @@ QuicErrorCode CryptoFramer::Process(QuicStringPiece input,
break;
}
// Save any remaining data.
- buffer_ = reader.PeekRemainingPayload().as_string();
+ buffer_ = string(reader.PeekRemainingPayload());
return QUIC_NO_ERROR;
}
diff --git a/chromium/net/quic/core/crypto/crypto_framer.h b/chromium/net/quic/core/crypto/crypto_framer.h
index a3c3d091494..c4bca2bb8d5 100644
--- a/chromium/net/quic/core/crypto/crypto_framer.h
+++ b/chromium/net/quic/core/crypto/crypto_framer.h
@@ -84,6 +84,11 @@ class QUIC_EXPORT_PRIVATE CryptoFramer : public CryptoMessageParser {
const CryptoHandshakeMessage& message,
Perspective perspective);
+ // Debug only method which permits processing truncated messages.
+ void set_process_truncated_messages(bool process_truncated_messages) {
+ process_truncated_messages_ = process_truncated_messages;
+ }
+
private:
// Clears per-message state. Does not clear the visitor.
void Clear();
@@ -123,6 +128,8 @@ class QUIC_EXPORT_PRIVATE CryptoFramer : public CryptoMessageParser {
std::vector<std::pair<QuicTag, size_t>> tags_and_lengths_;
// Cumulative length of all values in the message currently being parsed.
size_t values_len_;
+ // Set to true to allow of processing of truncated messages for debugging.
+ bool process_truncated_messages_;
};
} // namespace net
diff --git a/chromium/net/quic/core/crypto/crypto_handshake_message.cc b/chromium/net/quic/core/crypto/crypto_handshake_message.cc
index f29bb5863a0..3c9b2a678d5 100644
--- a/chromium/net/quic/core/crypto/crypto_handshake_message.cc
+++ b/chromium/net/quic/core/crypto/crypto_handshake_message.cc
@@ -17,6 +17,7 @@
#include "net/quic/platform/api/quic_string.h"
#include "net/quic/platform/api/quic_text_utils.h"
+using std::string;
namespace net {
@@ -89,7 +90,7 @@ void CryptoHandshakeMessage::SetVersion(QuicTag tag,
void CryptoHandshakeMessage::SetStringPiece(QuicTag tag,
QuicStringPiece value) {
- tag_value_map_[tag] = value.as_string();
+ tag_value_map_[tag] = string(value);
}
void CryptoHandshakeMessage::Erase(QuicTag tag) {
@@ -212,8 +213,8 @@ QuicErrorCode CryptoHandshakeMessage::GetUint64(QuicTag tag,
}
QuicErrorCode CryptoHandshakeMessage::GetUint128(QuicTag tag,
- uint128* out) const {
- return GetPOD(tag, out, sizeof(uint128));
+ QuicUint128* out) const {
+ return GetPOD(tag, out, sizeof(QuicUint128));
}
size_t CryptoHandshakeMessage::size() const {
diff --git a/chromium/net/quic/core/crypto/crypto_handshake_message.h b/chromium/net/quic/core/crypto/crypto_handshake_message.h
index abdfe4c5651..772c0365f81 100644
--- a/chromium/net/quic/core/crypto/crypto_handshake_message.h
+++ b/chromium/net/quic/core/crypto/crypto_handshake_message.h
@@ -10,11 +10,11 @@
#include <memory>
#include <vector>
-#include "net/base/int128.h"
#include "net/quic/core/quic_packets.h"
#include "net/quic/platform/api/quic_export.h"
#include "net/quic/platform/api/quic_string.h"
#include "net/quic/platform/api/quic_string_piece.h"
+#include "net/quic/platform/api/quic_uint128.h"
namespace net {
@@ -107,7 +107,7 @@ class QUIC_EXPORT_PRIVATE CryptoHandshakeMessage {
QuicStringPiece* out) const;
QuicErrorCode GetUint32(QuicTag tag, uint32_t* out) const;
QuicErrorCode GetUint64(QuicTag tag, uint64_t* out) const;
- QuicErrorCode GetUint128(QuicTag tag, uint128* out) const;
+ QuicErrorCode GetUint128(QuicTag tag, QuicUint128* out) const;
// size returns 4 (message tag) + 2 (uint16_t, number of entries) +
// (4 (tag) + 4 (end offset))*tag_value_map_.size() + ∑ value sizes.
diff --git a/chromium/net/quic/core/crypto/crypto_server_test.cc b/chromium/net/quic/core/crypto/crypto_server_test.cc
index c7a9a336d75..8012d752fc7 100644
--- a/chromium/net/quic/core/crypto/crypto_server_test.cc
+++ b/chromium/net/quic/core/crypto/crypto_server_test.cc
@@ -35,6 +35,8 @@
#include "net/quic/test_tools/quic_test_utils.h"
#include "third_party/boringssl/src/include/openssl/sha.h"
+using std::string;
+
namespace net {
namespace test {
@@ -848,8 +850,8 @@ TEST_P(CryptoServerTest, ProofForSuppliedServerConfig) {
CryptoUtils::HashHandshakeMessage(msg, &chlo_hash, Perspective::IS_SERVER);
EXPECT_EQ(QUIC_SUCCESS,
proof_verifier->VerifyProof(
- "test.example.com", 443, scfg_str.as_string(), client_version_,
- chlo_hash, certs, "", proof.as_string(), verify_context.get(),
+ "test.example.com", 443, (string(scfg_str)), client_version_,
+ chlo_hash, certs, "", (string(proof)), verify_context.get(),
&error_details, &details, std::move(callback)));
}
@@ -1061,7 +1063,7 @@ TEST_F(CryptoServerConfigGenerationTest, SCIDIsHashOfServerConfig) {
QuicStringPiece scid;
EXPECT_TRUE(scfg->GetStringPiece(kSCID, &scid));
// Need to take a copy of |scid| has we're about to call |Erase|.
- const QuicString scid_str(scid.as_string());
+ const QuicString scid_str(scid);
scfg->Erase(kSCID);
scfg->MarkDirty();
diff --git a/chromium/net/quic/core/crypto/crypto_utils.cc b/chromium/net/quic/core/crypto/crypto_utils.cc
index fd8fe1f9224..ccd1fd71b43 100644
--- a/chromium/net/quic/core/crypto/crypto_utils.cc
+++ b/chromium/net/quic/core/crypto/crypto_utils.cc
@@ -7,6 +7,8 @@
#include <memory>
#include "crypto/hkdf.h"
+#include "net/quic/core/crypto/aes_128_gcm_decrypter.h"
+#include "net/quic/core/crypto/aes_128_gcm_encrypter.h"
#include "net/quic/core/crypto/crypto_handshake.h"
#include "net/quic/core/crypto/crypto_protocol.h"
#include "net/quic/core/crypto/quic_decrypter.h"
@@ -17,47 +19,118 @@
#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_bug_tracker.h"
#include "net/quic/platform/api/quic_logging.h"
+#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/platform/api/quic_string.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/hkdf.h"
#include "third_party/boringssl/src/include/openssl/sha.h"
+using std::string;
namespace net {
// static
-std::vector<uint8_t> CryptoUtils::HkdfExpandLabel(
+std::vector<uint8_t> CryptoUtils::QhkdfExpand(
const EVP_MD* prf,
const std::vector<uint8_t>& secret,
const QuicString& label,
size_t out_len) {
- CBB hkdf_label, inner_label;
- const char label_prefix[] = "tls13 ";
- if (!CBB_init(&hkdf_label, 1) || !CBB_add_u16(&hkdf_label, out_len) ||
- !CBB_add_u8_length_prefixed(&hkdf_label, &inner_label) ||
+ bssl::ScopedCBB quic_hkdf_label;
+ CBB inner_label;
+ const char label_prefix[] = "QUIC ";
+ // The minimum possible length for the QuicHkdfLabel is 10 bytes - 2 bytes for
+ // Length, plus 1 byte for the length of the inner label, plus the length of
+ // that label (which is at least 6), plus 1 byte at the end.
+ if (!CBB_init(quic_hkdf_label.get(), 10) ||
+ !CBB_add_u16(quic_hkdf_label.get(), out_len) ||
+ !CBB_add_u8_length_prefixed(quic_hkdf_label.get(), &inner_label) ||
!CBB_add_bytes(&inner_label,
reinterpret_cast<const uint8_t*>(label_prefix),
QUIC_ARRAYSIZE(label_prefix) - 1) ||
!CBB_add_bytes(&inner_label,
reinterpret_cast<const uint8_t*>(label.data()),
label.size()) ||
- !CBB_add_u8(&hkdf_label, 0) || !CBB_flush(&hkdf_label)) {
+ !CBB_add_u8(quic_hkdf_label.get(), 0) ||
+ !CBB_flush(quic_hkdf_label.get())) {
QUIC_LOG(ERROR) << "Building HKDF label failed";
- CBB_cleanup(&hkdf_label);
- std::vector<uint8_t>();
+ return std::vector<uint8_t>();
}
std::vector<uint8_t> out;
out.resize(out_len);
if (!HKDF_expand(out.data(), out_len, prf, secret.data(), secret.size(),
- CBB_data(&hkdf_label), CBB_len(&hkdf_label))) {
+ CBB_data(quic_hkdf_label.get()),
+ CBB_len(quic_hkdf_label.get()))) {
QUIC_LOG(ERROR) << "Running HKDF-Expand-Label failed";
- CBB_cleanup(&hkdf_label);
- std::vector<uint8_t>();
+ return std::vector<uint8_t>();
}
- CBB_cleanup(&hkdf_label);
return out;
}
+template <class QuicCrypter>
+void CryptoUtils::SetKeyAndIV(const EVP_MD* prf,
+ const std::vector<uint8_t>& pp_secret,
+ QuicCrypter* crypter) {
+ std::vector<uint8_t> key =
+ CryptoUtils::QhkdfExpand(prf, pp_secret, "key", crypter->GetKeySize());
+ std::vector<uint8_t> iv =
+ CryptoUtils::QhkdfExpand(prf, pp_secret, "iv", crypter->GetIVSize());
+ crypter->SetKey(
+ QuicStringPiece(reinterpret_cast<char*>(key.data()), key.size()));
+ crypter->SetIV(
+ QuicStringPiece(reinterpret_cast<char*>(iv.data()), iv.size()));
+}
+
+namespace {
+
+const uint8_t kQuicVersion1Salt[] = {0xaf, 0xc8, 0x24, 0xec, 0x5f, 0xc7, 0x7e,
+ 0xca, 0x1e, 0x9d, 0x36, 0xf3, 0x7f, 0xb2,
+ 0xd4, 0x65, 0x18, 0xc3, 0x66, 0x39};
+
+} // namespace
+
+// static
+void CryptoUtils::CreateTlsInitialCrypters(Perspective perspective,
+ QuicConnectionId connection_id,
+ CrypterPair* crypters) {
+ const EVP_MD* hash = EVP_sha256();
+
+ uint8_t connection_id_bytes[sizeof(connection_id)];
+ for (size_t i = 0; i < sizeof(connection_id); ++i) {
+ connection_id_bytes[i] =
+ (connection_id >> ((sizeof(connection_id) - i - 1) * 8)) & 0xff;
+ }
+
+ std::vector<uint8_t> handshake_secret;
+ handshake_secret.resize(EVP_MAX_MD_SIZE);
+ size_t handshake_secret_len;
+ if (!HKDF_extract(handshake_secret.data(), &handshake_secret_len, hash,
+ connection_id_bytes, arraysize(connection_id_bytes),
+ kQuicVersion1Salt, arraysize(kQuicVersion1Salt))) {
+ QUIC_BUG << "HKDF_extract failed when creating initial crypters";
+ }
+ handshake_secret.resize(handshake_secret_len);
+
+ const string client_label = "client hs";
+ const string server_label = "server hs";
+ string encryption_label, decryption_label;
+ if (perspective == Perspective::IS_CLIENT) {
+ encryption_label = client_label;
+ decryption_label = server_label;
+ } else {
+ encryption_label = server_label;
+ decryption_label = client_label;
+ }
+ crypters->encrypter = QuicMakeUnique<Aes128GcmEncrypter>();
+ std::vector<uint8_t> encryption_secret =
+ QhkdfExpand(hash, handshake_secret, encryption_label, EVP_MD_size(hash));
+ SetKeyAndIV(hash, encryption_secret, crypters->encrypter.get());
+
+ crypters->decrypter = QuicMakeUnique<Aes128GcmDecrypter>();
+ std::vector<uint8_t> decryption_secret =
+ QhkdfExpand(hash, handshake_secret, decryption_label, EVP_MD_size(hash));
+ SetKeyAndIV(hash, decryption_secret, crypters->decrypter.get());
+}
+
// static
void CryptoUtils::GenerateNonce(QuicWallTime now,
QuicRandom* random_generator,
@@ -105,7 +178,7 @@ bool CryptoUtils::DeriveKeys(QuicStringPiece premaster_secret,
QuicStringPiece nonce = client_nonce;
QuicString nonce_storage;
if (!server_nonce.empty()) {
- nonce_storage = client_nonce.as_string() + server_nonce.as_string();
+ nonce_storage = string(client_nonce) + string(server_nonce);
nonce = nonce_storage;
}
@@ -197,7 +270,7 @@ bool CryptoUtils::ExportKeyingMaterial(QuicStringPiece subkey_secret,
return false;
}
uint32_t context_length = static_cast<uint32_t>(context.length());
- QuicString info = label.as_string();
+ QuicString info = string(label);
info.push_back('\0');
info.append(reinterpret_cast<char*>(&context_length), sizeof(context_length));
info.append(context.data(), context.length());
diff --git a/chromium/net/quic/core/crypto/crypto_utils.h b/chromium/net/quic/core/crypto/crypto_utils.h
index fc9545a24df..ab8f492aa72 100644
--- a/chromium/net/quic/core/crypto/crypto_utils.h
+++ b/chromium/net/quic/core/crypto/crypto_utils.h
@@ -69,21 +69,37 @@ class QUIC_EXPORT_PRIVATE CryptoUtils {
DiversificationNonce* nonce_;
};
- // Implements the HKDF-Expand-Label function as defined in section 7.1 of TLS
- // 1.3. The HKDF-Expand-Label definition assumes that the TLS connection's PRF
- // will be used as the Hash function for HKDF; in this function it is
- // explicitly passed in as |prf|. The inputs to HKDF-Expand-Label are as
- // follows:
+ // Implements the QHKDF-Expand function defined in section 5.2.3 of
+ // draft-ietf-quic-tls-09. The QHKDF-Expand function takes 3 explicit
+ // arguments, as well as an implicit PRF which is the hash function negotiated
+ // by TLS. This PRF is passed in as |prf|; the explicit arguments to
+ // QHKDF-Expand - Secret, Label, and Length - are passed in as |secret|,
+ // |label|, and |out_len|, respectively.
+ static std::vector<uint8_t> QhkdfExpand(const EVP_MD* prf,
+ const std::vector<uint8_t>& secret,
+ const std::string& label,
+ size_t out_len);
+
+ // SetKeyAndIV derives the key and IV from the given packet protection secret
+ // |pp_secret| and sets those fields on the given QuicEncrypter or
+ // QuicDecrypter |*crypter|. This follows the derivation described in section
+ // 5.2.4 of draft-ietf-quic-tls-09.
+ template <class QuicCrypter>
+ static void SetKeyAndIV(const EVP_MD* prf,
+ const std::vector<uint8_t>& pp_secret,
+ QuicCrypter* crypter);
+
+ // QUIC encrypts TLS handshake messages with a version-specific key (to
+ // prevent network observers that are not aware of that QUIC version from
+ // making decisions based on the TLS handshake). This packet protection secret
+ // is derived from the connection ID in the client's Initial packet.
//
- // Secret: |secret|
- // Label: |label|
- // Context: zero-length context
- // Length: |out_len|
- static std::vector<uint8_t> HkdfExpandLabel(
- const EVP_MD* prf,
- const std::vector<uint8_t>& secret,
- const QuicString& label,
- size_t out_len);
+ // This function takes that |connection_id| and creates the encrypter and
+ // decrypter (put in |*crypters|) to use for this packet protection, as well
+ // as setting the key and IV on those crypters.
+ static void CreateTlsInitialCrypters(Perspective perspective,
+ QuicConnectionId connection_id,
+ CrypterPair* crypters);
// Generates the connection nonce. The nonce is formed as:
// <4 bytes> current time
diff --git a/chromium/net/quic/core/crypto/crypto_utils_test.cc b/chromium/net/quic/core/crypto/crypto_utils_test.cc
index 58ff13b2c94..dfecd9195bd 100644
--- a/chromium/net/quic/core/crypto/crypto_utils_test.cc
+++ b/chromium/net/quic/core/crypto/crypto_utils_test.cc
@@ -18,21 +18,19 @@ namespace {
class CryptoUtilsTest : public QuicTest {};
-TEST_F(CryptoUtilsTest, TestHkdfExpandLabel) {
- // This test vector is from
- // https://github.com/quicwg/base-drafts/wiki/Test-Vector-for-the-Clear-Text-AEAD-key-derivation
+TEST_F(CryptoUtilsTest, TestQhkdfExpand) {
const std::vector<uint8_t> secret = {
0x8f, 0x01, 0x00, 0x67, 0x9c, 0x96, 0x5a, 0xc5, 0x9f, 0x28, 0x3a,
0x02, 0x52, 0x2a, 0x6e, 0x43, 0xcf, 0xae, 0xf6, 0x3c, 0x45, 0x48,
0xb0, 0xa6, 0x8f, 0x91, 0x91, 0x40, 0xee, 0x7d, 0x9a, 0x48};
- const QuicString label = "QUIC client cleartext Secret";
+ const QuicString label = "client hs";
std::vector<uint8_t> out =
- CryptoUtils::HkdfExpandLabel(EVP_sha256(), secret, label, 32);
+ CryptoUtils::QhkdfExpand(EVP_sha256(), secret, label, 32);
std::vector<uint8_t> expected_out = {
- 0x31, 0xba, 0x96, 0x68, 0x73, 0xf7, 0xf4, 0x53, 0xe6, 0xc8, 0xa1,
- 0xbf, 0x78, 0xed, 0x70, 0x13, 0xfa, 0xd8, 0x3f, 0xfc, 0xee, 0xfc,
- 0x95, 0x68, 0x81, 0xcd, 0x24, 0x1c, 0x0a, 0xe3, 0xa7, 0xa6};
+ 0x8e, 0x28, 0x6a, 0x27, 0x38, 0xe6, 0x66, 0x50, 0xb4, 0xf8, 0x8f,
+ 0xac, 0x5d, 0xc5, 0xd0, 0xef, 0x7d, 0x36, 0x9b, 0x07, 0xd4, 0x74,
+ 0x42, 0x99, 0x1a, 0x00, 0x0c, 0x55, 0xac, 0xc4, 0x0c, 0xf4};
EXPECT_EQ(out, expected_out);
}
diff --git a/chromium/net/quic/core/crypto/null_decrypter.cc b/chromium/net/quic/core/crypto/null_decrypter.cc
index 8d76dfb7b0b..38f3fbb3c2f 100644
--- a/chromium/net/quic/core/crypto/null_decrypter.cc
+++ b/chromium/net/quic/core/crypto/null_decrypter.cc
@@ -6,10 +6,10 @@
#include <cstdint>
-#include "net/base/int128.h"
#include "net/quic/core/quic_data_reader.h"
#include "net/quic/core/quic_utils.h"
#include "net/quic/platform/api/quic_bug_tracker.h"
+#include "net/quic/platform/api/quic_uint128.h"
using std::string;
@@ -49,7 +49,7 @@ bool NullDecrypter::DecryptPacket(QuicTransportVersion version,
size_t max_output_length) {
QuicDataReader reader(ciphertext.data(), ciphertext.length(),
HOST_BYTE_ORDER);
- uint128 hash;
+ QuicUint128 hash;
if (!ReadHash(&reader, &hash)) {
return false;
@@ -89,20 +89,20 @@ uint32_t NullDecrypter::cipher_id() const {
return 0;
}
-bool NullDecrypter::ReadHash(QuicDataReader* reader, uint128* hash) {
+bool NullDecrypter::ReadHash(QuicDataReader* reader, QuicUint128* hash) {
uint64_t lo;
uint32_t hi;
if (!reader->ReadUInt64(&lo) || !reader->ReadUInt32(&hi)) {
return false;
}
- *hash = MakeUint128(hi, lo);
+ *hash = MakeQuicUint128(hi, lo);
return true;
}
-uint128 NullDecrypter::ComputeHash(QuicTransportVersion version,
- const QuicStringPiece data1,
- const QuicStringPiece data2) const {
- uint128 correct_hash;
+QuicUint128 NullDecrypter::ComputeHash(QuicTransportVersion version,
+ const QuicStringPiece data1,
+ const QuicStringPiece data2) const {
+ QuicUint128 correct_hash;
if (version > QUIC_VERSION_35) {
if (perspective_ == Perspective::IS_CLIENT) {
// Peer is a server.
@@ -115,7 +115,7 @@ uint128 NullDecrypter::ComputeHash(QuicTransportVersion version,
} else {
correct_hash = QuicUtils::FNV1a_128_Hash_Two(data1, data2);
}
- uint128 mask = MakeUint128(UINT64_C(0x0), UINT64_C(0xffffffff));
+ QuicUint128 mask = MakeQuicUint128(UINT64_C(0x0), UINT64_C(0xffffffff));
mask <<= 96;
correct_hash &= ~mask;
return correct_hash;
diff --git a/chromium/net/quic/core/crypto/null_decrypter.h b/chromium/net/quic/core/crypto/null_decrypter.h
index 0ca74fe8cc0..67743dc429c 100644
--- a/chromium/net/quic/core/crypto/null_decrypter.h
+++ b/chromium/net/quic/core/crypto/null_decrypter.h
@@ -8,13 +8,12 @@
#include <cstddef>
#include <cstdint>
-#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "net/base/int128.h"
#include "net/quic/core/crypto/quic_decrypter.h"
#include "net/quic/core/quic_types.h"
#include "net/quic/platform/api/quic_export.h"
#include "net/quic/platform/api/quic_string_piece.h"
+#include "net/quic/platform/api/quic_uint128.h"
namespace net {
@@ -49,10 +48,10 @@ class QUIC_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter {
uint32_t cipher_id() const override;
private:
- bool ReadHash(QuicDataReader* reader, uint128* hash);
- uint128 ComputeHash(QuicTransportVersion version,
- QuicStringPiece data1,
- QuicStringPiece data2) const;
+ bool ReadHash(QuicDataReader* reader, QuicUint128* hash);
+ QuicUint128 ComputeHash(QuicTransportVersion version,
+ QuicStringPiece data1,
+ QuicStringPiece data2) const;
Perspective perspective_;
diff --git a/chromium/net/quic/core/crypto/null_encrypter.cc b/chromium/net/quic/core/crypto/null_encrypter.cc
index 999d717c85b..4ea40c13328 100644
--- a/chromium/net/quic/core/crypto/null_encrypter.cc
+++ b/chromium/net/quic/core/crypto/null_encrypter.cc
@@ -39,7 +39,7 @@ bool NullEncrypter::EncryptPacket(QuicTransportVersion version,
if (max_output_length < len) {
return false;
}
- uint128 hash;
+ QuicUint128 hash;
if (version > QUIC_VERSION_35) {
if (perspective_ == Perspective::IS_SERVER) {
hash =
diff --git a/chromium/net/quic/core/crypto/quic_crypto_client_config.cc b/chromium/net/quic/core/crypto/quic_crypto_client_config.cc
index 6d64c19b43d..1ce64244329 100644
--- a/chromium/net/quic/core/crypto/quic_crypto_client_config.cc
+++ b/chromium/net/quic/core/crypto/quic_crypto_client_config.cc
@@ -32,6 +32,7 @@
#include "net/quic/platform/api/quic_text_utils.h"
#include "third_party/boringssl/src/include/openssl/ssl.h"
+using std::string;
namespace net {
@@ -184,7 +185,7 @@ QuicCryptoClientConfig::CachedState::SetServerConfig(
}
if (!matches_existing) {
- server_config_ = server_config.as_string();
+ server_config_ = string(server_config);
SetProofInvalid();
scfg_ = std::move(new_scfg_storage);
}
@@ -224,9 +225,9 @@ void QuicCryptoClientConfig::CachedState::SetProof(
// If the proof has changed then it needs to be revalidated.
SetProofInvalid();
certs_ = certs;
- cert_sct_ = cert_sct.as_string();
- chlo_hash_ = chlo_hash.as_string();
- server_config_sig_ = signature.as_string();
+ cert_sct_ = string(cert_sct);
+ chlo_hash_ = string(chlo_hash);
+ server_config_sig_ = string(signature);
}
void QuicCryptoClientConfig::CachedState::Clear() {
@@ -337,12 +338,12 @@ QuicCryptoClientConfig::CachedState::proof_verify_details() const {
void QuicCryptoClientConfig::CachedState::set_source_address_token(
QuicStringPiece token) {
- source_address_token_ = token.as_string();
+ source_address_token_ = string(token);
}
void QuicCryptoClientConfig::CachedState::set_cert_sct(
QuicStringPiece cert_sct) {
- cert_sct_ = cert_sct.as_string();
+ cert_sct_ = string(cert_sct);
}
void QuicCryptoClientConfig::CachedState::SetProofVerifyDetails(
@@ -818,7 +819,7 @@ QuicErrorCode QuicCryptoClientConfig::ProcessRejection(
QuicStringPiece nonce;
if (rej.GetStringPiece(kServerNonceTag, &nonce)) {
- out_params->server_nonce = nonce.as_string();
+ out_params->server_nonce = string(nonce);
}
if (rej.tag() == kSREJ) {
@@ -830,7 +831,7 @@ QuicErrorCode QuicCryptoClientConfig::ProcessRejection(
connection_id = QuicEndian::NetToHost64(connection_id);
cached->add_server_designated_connection_id(connection_id);
if (!nonce.empty()) {
- cached->add_server_nonce(nonce.as_string());
+ cached->add_server_nonce(string(nonce));
}
return QUIC_NO_ERROR;
}
diff --git a/chromium/net/quic/core/crypto/quic_crypto_server_config.cc b/chromium/net/quic/core/crypto/quic_crypto_server_config.cc
index 9e677ac8094..a376ea9fae6 100644
--- a/chromium/net/quic/core/crypto/quic_crypto_server_config.cc
+++ b/chromium/net/quic/core/crypto/quic_crypto_server_config.cc
@@ -45,6 +45,7 @@
#include "third_party/boringssl/src/include/openssl/sha.h"
#include "third_party/boringssl/src/include/openssl/ssl.h"
+using std::string;
namespace net {
@@ -64,7 +65,7 @@ QuicString DeriveSourceAddressTokenKey(
source_address_token_secret, QuicStringPiece() /* no salt */,
"QUIC source address token key", CryptoSecretBoxer::GetKeySize(),
0 /* no fixed IV needed */, 0 /* no subkey secret */);
- return hkdf.server_write_key().as_string();
+ return string(hkdf.server_write_key());
}
} // namespace
@@ -707,7 +708,7 @@ void QuicCryptoServerConfig::ProcessClientHello(
compressed_certs_cache, params, signed_config,
total_framing_overhead, chlo_packet_size, requested_config,
primary_config, std::move(done_cb)));
- proof_source_->GetProof(server_address, info.sni.as_string(),
+ proof_source_->GetProof(server_address, string(info.sni),
primary_config->serialized, version, chlo_hash,
std::move(cb));
helper.DetachCallback();
@@ -918,7 +919,7 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof(
return;
}
- params->channel_id = key.as_string();
+ params->channel_id = string(key);
}
}
@@ -952,7 +953,7 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof(
std::unique_ptr<KeyExchange> forward_secure_key_exchange(
key_exchange->NewKeyPair(rand));
forward_secure_public_value =
- forward_secure_key_exchange->public_value().as_string();
+ string(forward_secure_key_exchange->public_value());
if (!forward_secure_key_exchange->CalculateSharedKey(
public_value, &params->forward_secure_premaster_secret)) {
helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
@@ -1004,7 +1005,7 @@ QuicCryptoServerConfig::GetConfigWithScid(
configs_lock_.AssertReaderHeld();
if (!requested_scid.empty()) {
- ConfigMap::const_iterator it = configs_.find(requested_scid.as_string());
+ ConfigMap::const_iterator it = configs_.find((string(requested_scid)));
if (it != configs_.end()) {
// We'll use the config that the client requested in order to do
// key-agreement.
@@ -1262,7 +1263,7 @@ void QuicCryptoServerConfig::EvaluateClientHello(
*this, found_error, server_address.host(), version,
requested_config, primary_config, signed_config, client_hello_state,
std::move(done_cb)));
- proof_source_->GetProof(server_address, info->sni.as_string(),
+ proof_source_->GetProof(server_address, string(info->sni),
serialized_config, version, chlo_hash,
std::move(cb));
helper.DetachCallback();
@@ -1490,12 +1491,12 @@ void QuicCryptoServerConfig::BuildRejection(
QuicStringPiece client_common_set_hashes;
if (client_hello.GetStringPiece(kCCS, &client_common_set_hashes)) {
- params->client_common_set_hashes = client_common_set_hashes.as_string();
+ params->client_common_set_hashes = string(client_common_set_hashes);
}
QuicStringPiece client_cached_cert_hashes;
if (client_hello.GetStringPiece(kCCRT, &client_cached_cert_hashes)) {
- params->client_cached_cert_hashes = client_cached_cert_hashes.as_string();
+ params->client_cached_cert_hashes = string(client_cached_cert_hashes);
} else {
params->client_cached_cert_hashes.clear();
}
@@ -1597,7 +1598,7 @@ QuicCryptoServerConfig::ParseConfigProtobuf(
QUIC_LOG(WARNING) << "Server config message is missing SCID";
return nullptr;
}
- config->id = scid.as_string();
+ config->id = string(scid);
if (msg->GetTaglist(kAEAD, &config->aead) != QUIC_NO_ERROR) {
QUIC_LOG(WARNING) << "Server config message is missing AEAD";
diff --git a/chromium/net/quic/core/crypto/quic_crypto_server_config_test.cc b/chromium/net/quic/core/crypto/quic_crypto_server_config_test.cc
index 94350e48099..00d5e9816e5 100644
--- a/chromium/net/quic/core/crypto/quic_crypto_server_config_test.cc
+++ b/chromium/net/quic/core/crypto/quic_crypto_server_config_test.cc
@@ -23,6 +23,7 @@
#include "net/quic/test_tools/mock_clock.h"
#include "net/quic/test_tools/quic_crypto_server_config_peer.h"
+using std::string;
namespace net {
namespace test {
@@ -132,7 +133,7 @@ TEST_F(QuicCryptoServerConfigTest, CompressDifferentCerts) {
QuicStringPiece different_common_certs(
reinterpret_cast<const char*>(&set_hash), sizeof(set_hash));
QuicString compressed3 = QuicCryptoServerConfigPeer::CompressChain(
- &compressed_certs_cache, chain, different_common_certs.as_string(),
+ &compressed_certs_cache, chain, string(different_common_certs),
cached_certs, common_sets.get());
EXPECT_EQ(compressed_certs_cache.Size(), 3u);
}
diff --git a/chromium/net/quic/core/crypto/quic_decrypter.cc b/chromium/net/quic/core/crypto/quic_decrypter.cc
index 73d2f2f59a3..83f97ccc07b 100644
--- a/chromium/net/quic/core/crypto/quic_decrypter.cc
+++ b/chromium/net/quic/core/crypto/quic_decrypter.cc
@@ -14,18 +14,21 @@
#include "net/quic/core/crypto/null_decrypter.h"
#include "net/quic/platform/api/quic_bug_tracker.h"
#include "net/quic/platform/api/quic_logging.h"
+#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/platform/api/quic_string.h"
#include "third_party/boringssl/src/include/openssl/tls1.h"
+using std::string;
+
namespace net {
// static
std::unique_ptr<QuicDecrypter> QuicDecrypter::Create(QuicTag algorithm) {
switch (algorithm) {
case kAESG:
- return std::make_unique<Aes128Gcm12Decrypter>();
+ return QuicMakeUnique<Aes128Gcm12Decrypter>();
case kCC20:
- return std::make_unique<ChaCha20Poly1305Decrypter>();
+ return QuicMakeUnique<ChaCha20Poly1305Decrypter>();
default:
QUIC_LOG(FATAL) << "Unsupported algorithm: " << algorithm;
return nullptr;
@@ -33,23 +36,19 @@ std::unique_ptr<QuicDecrypter> QuicDecrypter::Create(QuicTag algorithm) {
}
// static
-QuicDecrypter* QuicDecrypter::CreateFromCipherSuite(uint32_t cipher_suite) {
- QuicDecrypter* decrypter;
+std::unique_ptr<QuicDecrypter> QuicDecrypter::CreateFromCipherSuite(
+ uint32_t cipher_suite) {
switch (cipher_suite) {
case TLS1_CK_AES_128_GCM_SHA256:
- decrypter = new Aes128GcmDecrypter();
- break;
+ return QuicMakeUnique<Aes128GcmDecrypter>();
case TLS1_CK_AES_256_GCM_SHA384:
- decrypter = new Aes256GcmDecrypter();
- break;
+ return QuicMakeUnique<Aes256GcmDecrypter>();
case TLS1_CK_CHACHA20_POLY1305_SHA256:
- decrypter = new ChaCha20Poly1305TlsDecrypter();
- break;
+ return QuicMakeUnique<ChaCha20Poly1305TlsDecrypter>();
default:
QUIC_BUG << "TLS cipher suite is unknown to QUIC";
return nullptr;
}
- return decrypter;
}
// static
@@ -60,12 +59,12 @@ void QuicDecrypter::DiversifyPreliminaryKey(QuicStringPiece preliminary_key,
size_t nonce_prefix_size,
QuicString* out_key,
QuicString* out_nonce_prefix) {
- crypto::HKDF hkdf(preliminary_key.as_string() + nonce_prefix.as_string(),
+ crypto::HKDF hkdf((string(preliminary_key)) + (string(nonce_prefix)),
QuicStringPiece(nonce.data(), nonce.size()),
"QUIC key diversification", 0, key_size, 0,
nonce_prefix_size, 0);
- *out_key = hkdf.server_write_key().as_string();
- *out_nonce_prefix = hkdf.server_write_iv().as_string();
+ *out_key = string(hkdf.server_write_key());
+ *out_nonce_prefix = string(hkdf.server_write_iv());
}
} // namespace net
diff --git a/chromium/net/quic/core/crypto/quic_decrypter.h b/chromium/net/quic/core/crypto/quic_decrypter.h
index 62d25d4bcda..2ffd26f6761 100644
--- a/chromium/net/quic/core/crypto/quic_decrypter.h
+++ b/chromium/net/quic/core/crypto/quic_decrypter.h
@@ -25,7 +25,8 @@ class QUIC_EXPORT_PRIVATE QuicDecrypter {
// Creates an IETF QuicDecrypter based on |cipher_suite| which must be an id
// returned by SSL_CIPHER_get_id. The caller is responsible for taking
// ownership of the new QuicDecrypter.
- static QuicDecrypter* CreateFromCipherSuite(uint32_t cipher_suite);
+ static std::unique_ptr<QuicDecrypter> CreateFromCipherSuite(
+ uint32_t cipher_suite);
// Sets the encryption key. Returns true on success, false on failure.
//
diff --git a/chromium/net/quic/core/crypto/quic_encrypter.cc b/chromium/net/quic/core/crypto/quic_encrypter.cc
index ef78336035e..15d84f1bc1d 100644
--- a/chromium/net/quic/core/crypto/quic_encrypter.cc
+++ b/chromium/net/quic/core/crypto/quic_encrypter.cc
@@ -13,6 +13,7 @@
#include "net/quic/core/crypto/null_encrypter.h"
#include "net/quic/platform/api/quic_bug_tracker.h"
#include "net/quic/platform/api/quic_logging.h"
+#include "net/quic/platform/api/quic_ptr_util.h"
#include "third_party/boringssl/src/include/openssl/tls1.h"
namespace net {
@@ -21,9 +22,9 @@ namespace net {
std::unique_ptr<QuicEncrypter> QuicEncrypter::Create(QuicTag algorithm) {
switch (algorithm) {
case kAESG:
- return std::make_unique<Aes128Gcm12Encrypter>();
+ return QuicMakeUnique<Aes128Gcm12Encrypter>();
case kCC20:
- return std::make_unique<ChaCha20Poly1305Encrypter>();
+ return QuicMakeUnique<ChaCha20Poly1305Encrypter>();
default:
QUIC_LOG(FATAL) << "Unsupported algorithm: " << algorithm;
return nullptr;
@@ -31,23 +32,19 @@ std::unique_ptr<QuicEncrypter> QuicEncrypter::Create(QuicTag algorithm) {
}
// static
-QuicEncrypter* QuicEncrypter::CreateFromCipherSuite(uint32_t cipher_suite) {
- QuicEncrypter* encrypter;
+std::unique_ptr<QuicEncrypter> QuicEncrypter::CreateFromCipherSuite(
+ uint32_t cipher_suite) {
switch (cipher_suite) {
case TLS1_CK_AES_128_GCM_SHA256:
- encrypter = new Aes128GcmEncrypter();
- break;
+ return QuicMakeUnique<Aes128GcmEncrypter>();
case TLS1_CK_AES_256_GCM_SHA384:
- encrypter = new Aes256GcmEncrypter();
- break;
+ return QuicMakeUnique<Aes256GcmEncrypter>();
case TLS1_CK_CHACHA20_POLY1305_SHA256:
- encrypter = new ChaCha20Poly1305TlsEncrypter();
- break;
+ return QuicMakeUnique<ChaCha20Poly1305TlsEncrypter>();
default:
QUIC_BUG << "TLS cipher suite is unknown to QUIC";
return nullptr;
}
- return encrypter;
}
} // namespace net
diff --git a/chromium/net/quic/core/crypto/quic_encrypter.h b/chromium/net/quic/core/crypto/quic_encrypter.h
index bc32213a1eb..d84f4342e23 100644
--- a/chromium/net/quic/core/crypto/quic_encrypter.h
+++ b/chromium/net/quic/core/crypto/quic_encrypter.h
@@ -22,8 +22,9 @@ class QUIC_EXPORT_PRIVATE QuicEncrypter {
// Creates an IETF QuicEncrypter based on |cipher_suite| which must be an id
// returned by SSL_CIPHER_get_id. The caller is responsible for taking
- // ownership of the new QuicEncrypter.
- static QuicEncrypter* CreateFromCipherSuite(uint32_t cipher_suite);
+ // ownership of the nwe QuicEncrypter.
+ static std::unique_ptr<QuicEncrypter> CreateFromCipherSuite(
+ uint32_t cipher_suite);
// Sets the encryption key. Returns true on success, false on failure.
//
diff --git a/chromium/net/quic/core/crypto/quic_random.cc b/chromium/net/quic/core/crypto/quic_random.cc
index ac54517bff1..2c5e1e22a1b 100644
--- a/chromium/net/quic/core/crypto/quic_random.cc
+++ b/chromium/net/quic/core/crypto/quic_random.cc
@@ -8,6 +8,7 @@
#include "base/memory/singleton.h"
#include "crypto/random.h"
#include "net/quic/platform/api/quic_bug_tracker.h"
+#include "net/quic/platform/api/quic_singleton.h"
namespace net {
@@ -26,12 +27,12 @@ class DefaultRandom : public QuicRandom {
DefaultRandom() {}
~DefaultRandom() override {}
- friend struct base::DefaultSingletonTraits<DefaultRandom>;
+ friend QuicSingletonFriend<DefaultRandom>;
DISALLOW_COPY_AND_ASSIGN(DefaultRandom);
};
DefaultRandom* DefaultRandom::GetInstance() {
- return base::Singleton<DefaultRandom>::get();
+ return QuicSingleton<DefaultRandom>::get();
}
void DefaultRandom::RandBytes(void* data, size_t len) {
diff --git a/chromium/net/quic/core/frames/quic_connection_close_frame.cc b/chromium/net/quic/core/frames/quic_connection_close_frame.cc
index 4aef61dbc15..0d6062e726f 100644
--- a/chromium/net/quic/core/frames/quic_connection_close_frame.cc
+++ b/chromium/net/quic/core/frames/quic_connection_close_frame.cc
@@ -9,6 +9,10 @@ namespace net {
QuicConnectionCloseFrame::QuicConnectionCloseFrame()
: error_code(QUIC_NO_ERROR) {}
+QuicConnectionCloseFrame::QuicConnectionCloseFrame(QuicErrorCode error_code,
+ QuicString error_details)
+ : error_code(error_code), error_details(error_details) {}
+
std::ostream& operator<<(
std::ostream& os,
const QuicConnectionCloseFrame& connection_close_frame) {
diff --git a/chromium/net/quic/core/frames/quic_connection_close_frame.h b/chromium/net/quic/core/frames/quic_connection_close_frame.h
index 31f05d1e53a..89fa51c698a 100644
--- a/chromium/net/quic/core/frames/quic_connection_close_frame.h
+++ b/chromium/net/quic/core/frames/quic_connection_close_frame.h
@@ -15,6 +15,7 @@ namespace net {
struct QUIC_EXPORT_PRIVATE QuicConnectionCloseFrame {
QuicConnectionCloseFrame();
+ QuicConnectionCloseFrame(QuicErrorCode error_code, QuicString error_details);
friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
std::ostream& os,
diff --git a/chromium/net/quic/core/frames/quic_frame.h b/chromium/net/quic/core/frames/quic_frame.h
index affa1d6d1f3..244fe3f8102 100644
--- a/chromium/net/quic/core/frames/quic_frame.h
+++ b/chromium/net/quic/core/frames/quic_frame.h
@@ -12,10 +12,16 @@
#include "net/quic/core/frames/quic_blocked_frame.h"
#include "net/quic/core/frames/quic_connection_close_frame.h"
#include "net/quic/core/frames/quic_goaway_frame.h"
+#include "net/quic/core/frames/quic_ietf_blocked_frame.h"
+#include "net/quic/core/frames/quic_ietf_max_stream_id_frame.h"
+#include "net/quic/core/frames/quic_ietf_stream_id_blocked_frame.h"
#include "net/quic/core/frames/quic_mtu_discovery_frame.h"
#include "net/quic/core/frames/quic_padding_frame.h"
+#include "net/quic/core/frames/quic_path_challenge_frame.h"
+#include "net/quic/core/frames/quic_path_response_frame.h"
#include "net/quic/core/frames/quic_ping_frame.h"
#include "net/quic/core/frames/quic_rst_stream_frame.h"
+#include "net/quic/core/frames/quic_stop_sending_frame.h"
#include "net/quic/core/frames/quic_stop_waiting_frame.h"
#include "net/quic/core/frames/quic_stream_frame.h"
#include "net/quic/core/frames/quic_window_update_frame.h"
diff --git a/chromium/net/quic/core/frames/quic_ietf_blocked_frame.cc b/chromium/net/quic/core/frames/quic_ietf_blocked_frame.cc
new file mode 100644
index 00000000000..f31f0555a1b
--- /dev/null
+++ b/chromium/net/quic/core/frames/quic_ietf_blocked_frame.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/core/frames/quic_ietf_blocked_frame.h"
+
+namespace net {
+
+QuicIetfBlockedFrame::QuicIetfBlockedFrame() {}
+
+QuicIetfBlockedFrame::QuicIetfBlockedFrame(QuicControlFrameId control_frame_id,
+ QuicStreamOffset offset)
+ : QuicControlFrame(control_frame_id), offset(offset) {}
+
+std::ostream& operator<<(std::ostream& os, const QuicIetfBlockedFrame& frame) {
+ os << "{ control_frame_id: " << frame.control_frame_id
+ << ", offset: " << frame.offset << " }\n";
+ return os;
+}
+
+} // namespace net
diff --git a/chromium/net/quic/core/frames/quic_ietf_blocked_frame.h b/chromium/net/quic/core/frames/quic_ietf_blocked_frame.h
new file mode 100644
index 00000000000..b0474f2cd11
--- /dev/null
+++ b/chromium/net/quic/core/frames/quic_ietf_blocked_frame.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_CORE_FRAMES_QUIC_IETF_BLOCKED_FRAME_H_
+#define NET_QUIC_CORE_FRAMES_QUIC_IETF_BLOCKED_FRAME_H_
+
+#include <ostream>
+
+#include "net/quic/core/frames/quic_control_frame.h"
+
+namespace net {
+
+// IETF format BLOCKED frame.
+// The sender uses the BLOCKED frame to inform the receiver that the
+// sender is unable to send data because of connection-level flow control.
+struct QUIC_EXPORT_PRIVATE QuicIetfBlockedFrame : public QuicControlFrame {
+ QuicIetfBlockedFrame();
+ QuicIetfBlockedFrame(QuicControlFrameId control_frame_id,
+ QuicStreamOffset offset);
+
+ friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+ std::ostream& os,
+ const QuicIetfBlockedFrame& frame);
+
+ // Offset at which the BLOCKED applies
+ QuicStreamOffset offset;
+};
+
+} // namespace net
+
+#endif // NET_QUIC_CORE_FRAMES_QUIC_IETF_BLOCKED_FRAME_H_
diff --git a/chromium/net/quic/core/frames/quic_ietf_max_stream_id_frame.cc b/chromium/net/quic/core/frames/quic_ietf_max_stream_id_frame.cc
new file mode 100644
index 00000000000..bd7ef723593
--- /dev/null
+++ b/chromium/net/quic/core/frames/quic_ietf_max_stream_id_frame.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/core/frames/quic_ietf_max_stream_id_frame.h"
+
+namespace net {
+
+QuicIetfMaxStreamIdFrame::QuicIetfMaxStreamIdFrame() {}
+
+QuicIetfMaxStreamIdFrame::QuicIetfMaxStreamIdFrame(
+ QuicControlFrameId control_frame_id,
+ QuicStreamId max_stream_id)
+ : QuicControlFrame(control_frame_id), max_stream_id(max_stream_id) {}
+
+std::ostream& operator<<(std::ostream& os,
+ const QuicIetfMaxStreamIdFrame& frame) {
+ os << "{ control_frame_id: " << frame.control_frame_id
+ << ", stream_id: " << frame.max_stream_id << " }\n";
+ return os;
+}
+
+} // namespace net
diff --git a/chromium/net/quic/core/frames/quic_ietf_max_stream_id_frame.h b/chromium/net/quic/core/frames/quic_ietf_max_stream_id_frame.h
new file mode 100644
index 00000000000..bfb1a97364c
--- /dev/null
+++ b/chromium/net/quic/core/frames/quic_ietf_max_stream_id_frame.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_CORE_FRAMES_QUIC_IETF_MAX_STREAM_ID_FRAME_H_
+#define NET_QUIC_CORE_FRAMES_QUIC_IETF_MAX_STREAM_ID_FRAME_H_
+
+#include <ostream>
+
+#include "net/quic/core/frames/quic_control_frame.h"
+
+namespace net {
+
+// IETF format max-stream id frame.
+// This frame is used by the sender to inform the peer of the largest
+// stream id that the peer may open and that the sender will accept.
+struct QUIC_EXPORT_PRIVATE QuicIetfMaxStreamIdFrame : public QuicControlFrame {
+ QuicIetfMaxStreamIdFrame();
+ QuicIetfMaxStreamIdFrame(QuicControlFrameId control_frame_id,
+ QuicStreamId max_stream_id);
+
+ friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+ std::ostream& os,
+ const QuicIetfMaxStreamIdFrame& frame);
+
+ // The maximum stream id to support.
+ QuicStreamId max_stream_id;
+};
+
+} // namespace net
+
+#endif // NET_QUIC_CORE_FRAMES_QUIC_IETF_MAX_STREAM_ID_FRAME_H_
diff --git a/chromium/net/quic/core/frames/quic_ietf_stream_id_blocked_frame.cc b/chromium/net/quic/core/frames/quic_ietf_stream_id_blocked_frame.cc
new file mode 100644
index 00000000000..7cbc06ef85c
--- /dev/null
+++ b/chromium/net/quic/core/frames/quic_ietf_stream_id_blocked_frame.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/core/frames/quic_ietf_stream_id_blocked_frame.h"
+
+namespace net {
+
+QuicIetfStreamIdBlockedFrame::QuicIetfStreamIdBlockedFrame() {}
+
+QuicIetfStreamIdBlockedFrame::QuicIetfStreamIdBlockedFrame(
+ QuicControlFrameId control_frame_id,
+ QuicStreamId stream_id)
+ : QuicControlFrame(control_frame_id), stream_id(stream_id) {}
+
+std::ostream& operator<<(std::ostream& os,
+ const QuicIetfStreamIdBlockedFrame& frame) {
+ os << "{ control_frame_id: " << frame.control_frame_id
+ << ", stream id: " << frame.stream_id << " }\n";
+ return os;
+}
+
+} // namespace net
diff --git a/chromium/net/quic/core/frames/quic_ietf_stream_id_blocked_frame.h b/chromium/net/quic/core/frames/quic_ietf_stream_id_blocked_frame.h
new file mode 100644
index 00000000000..91ad6f0eb7d
--- /dev/null
+++ b/chromium/net/quic/core/frames/quic_ietf_stream_id_blocked_frame.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_CORE_FRAMES_QUIC_IETF_STREAM_ID_BLOCKED_FRAME_H_
+#define NET_QUIC_CORE_FRAMES_QUIC_IETF_STREAM_ID_BLOCKED_FRAME_H_
+
+#include <ostream>
+
+#include "net/quic/core/frames/quic_control_frame.h"
+
+namespace net {
+
+// IETF format STREAM ID BLOCKED frame.
+// The sender uses this to inform the peer that the sender wished to
+// open a new stream but was blocked from doing so due due to the
+// maximum stream ID limit set by the peer (via a MAX_STREAM_ID frame)
+struct QUIC_EXPORT_PRIVATE QuicIetfStreamIdBlockedFrame
+ : public QuicControlFrame {
+ QuicIetfStreamIdBlockedFrame();
+ QuicIetfStreamIdBlockedFrame(QuicControlFrameId control_frame_id,
+ QuicStreamId stream_id);
+
+ friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+ std::ostream& os,
+ const QuicIetfStreamIdBlockedFrame& frame);
+
+ QuicStreamId stream_id;
+};
+
+} // namespace net
+
+#endif // NET_QUIC_CORE_FRAMES_QUIC_IETF_STREAM_ID_BLOCKED_FRAME_H_
diff --git a/chromium/net/quic/core/frames/quic_path_challenge_frame.cc b/chromium/net/quic/core/frames/quic_path_challenge_frame.cc
new file mode 100644
index 00000000000..a7463e5b4ba
--- /dev/null
+++ b/chromium/net/quic/core/frames/quic_path_challenge_frame.cc
@@ -0,0 +1,35 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/core/frames/quic_path_challenge_frame.h"
+#include "net/quic/platform/api/quic_bug_tracker.h"
+
+namespace net {
+
+QuicPathChallengeFrame::QuicPathChallengeFrame() : QuicControlFrame(0) {}
+
+QuicPathChallengeFrame::QuicPathChallengeFrame(
+ QuicControlFrameId control_frame_id,
+ const QuicPathFrameBuffer& data_buff)
+ : QuicControlFrame(control_frame_id) {
+ memcpy(data_buffer.data(), data_buff.data(), data_buffer.size());
+}
+
+QuicPathChallengeFrame::~QuicPathChallengeFrame() {}
+
+std::ostream& operator<<(std::ostream& os,
+ const QuicPathChallengeFrame& frame) {
+ os << "{ control_frame_id: " << frame.control_frame_id
+ << ", data: " << static_cast<unsigned>(frame.data_buffer[0]) << " "
+ << static_cast<unsigned>(frame.data_buffer[1]) << " "
+ << static_cast<unsigned>(frame.data_buffer[2]) << " "
+ << static_cast<unsigned>(frame.data_buffer[3]) << " "
+ << static_cast<unsigned>(frame.data_buffer[4]) << " "
+ << static_cast<unsigned>(frame.data_buffer[5]) << " "
+ << static_cast<unsigned>(frame.data_buffer[6]) << " "
+ << static_cast<unsigned>(frame.data_buffer[7]) << " }\n";
+ return os;
+}
+
+} // namespace net
diff --git a/chromium/net/quic/core/frames/quic_path_challenge_frame.h b/chromium/net/quic/core/frames/quic_path_challenge_frame.h
new file mode 100644
index 00000000000..3fabb7b58a9
--- /dev/null
+++ b/chromium/net/quic/core/frames/quic_path_challenge_frame.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_CORE_FRAMES_QUIC_PATH_CHALLENGE_FRAME_H_
+#define NET_QUIC_CORE_FRAMES_QUIC_PATH_CHALLENGE_FRAME_H_
+
+#include <memory>
+#include <ostream>
+
+#include "net/quic/core/frames/quic_control_frame.h"
+#include "net/quic/core/quic_types.h"
+
+namespace net {
+
+// Size of the entire IETF Quic Path Challenge frame, including
+// type byte.
+const size_t kQuicPathChallengeFrameSize = (kQuicPathFrameBufferSize + 1);
+
+struct QUIC_EXPORT_PRIVATE QuicPathChallengeFrame : public QuicControlFrame {
+ QuicPathChallengeFrame();
+ QuicPathChallengeFrame(QuicControlFrameId control_frame_id,
+ const QuicPathFrameBuffer& data_buff);
+ ~QuicPathChallengeFrame();
+
+ friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+ std::ostream& os,
+ const QuicPathChallengeFrame& frame);
+
+ QuicPathFrameBuffer data_buffer;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(QuicPathChallengeFrame);
+};
+} // namespace net
+
+#endif // NET_QUIC_CORE_FRAMES_QUIC_PATH_CHALLENGE_FRAME_H_
diff --git a/chromium/net/quic/core/frames/quic_path_response_frame.cc b/chromium/net/quic/core/frames/quic_path_response_frame.cc
new file mode 100644
index 00000000000..2d0068a7354
--- /dev/null
+++ b/chromium/net/quic/core/frames/quic_path_response_frame.cc
@@ -0,0 +1,34 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/core/frames/quic_path_response_frame.h"
+#include "net/quic/platform/api/quic_bug_tracker.h"
+
+namespace net {
+
+QuicPathResponseFrame::QuicPathResponseFrame() : QuicControlFrame(0) {}
+
+QuicPathResponseFrame::QuicPathResponseFrame(
+ QuicControlFrameId control_frame_id,
+ const QuicPathFrameBuffer& data_buff)
+ : QuicControlFrame(control_frame_id) {
+ memcpy(data_buffer.data(), data_buff.data(), data_buffer.size());
+}
+
+QuicPathResponseFrame::~QuicPathResponseFrame() {}
+
+std::ostream& operator<<(std::ostream& os, const QuicPathResponseFrame& frame) {
+ os << "{ control_frame_id: " << frame.control_frame_id
+ << ", data: " << static_cast<unsigned>(frame.data_buffer[0]) << " "
+ << static_cast<unsigned>(frame.data_buffer[1]) << " "
+ << static_cast<unsigned>(frame.data_buffer[2]) << " "
+ << static_cast<unsigned>(frame.data_buffer[3]) << " "
+ << static_cast<unsigned>(frame.data_buffer[4]) << " "
+ << static_cast<unsigned>(frame.data_buffer[5]) << " "
+ << static_cast<unsigned>(frame.data_buffer[6]) << " "
+ << static_cast<unsigned>(frame.data_buffer[7]) << " }\n";
+ return os;
+}
+
+} // namespace net
diff --git a/chromium/net/quic/core/frames/quic_path_response_frame.h b/chromium/net/quic/core/frames/quic_path_response_frame.h
new file mode 100644
index 00000000000..c56dc6779d2
--- /dev/null
+++ b/chromium/net/quic/core/frames/quic_path_response_frame.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_CORE_FRAMES_QUIC_PATH_RESPONSE_FRAME_H_
+#define NET_QUIC_CORE_FRAMES_QUIC_PATH_RESPONSE_FRAME_H_
+
+#include <memory>
+#include <ostream>
+
+#include "net/quic/core/frames/quic_control_frame.h"
+#include "net/quic/core/quic_types.h"
+
+namespace net {
+
+// Size of the entire IETF Quic Path Response frame, including
+// type byte.
+const size_t kQuicPathResponseFrameSize = (kQuicPathFrameBufferSize + 1);
+
+struct QUIC_EXPORT_PRIVATE QuicPathResponseFrame : public QuicControlFrame {
+ QuicPathResponseFrame();
+ QuicPathResponseFrame(QuicControlFrameId control_frame_id,
+ const QuicPathFrameBuffer& data_buff);
+ ~QuicPathResponseFrame();
+
+ friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+ std::ostream& os,
+ const QuicPathResponseFrame& frame);
+
+ QuicPathFrameBuffer data_buffer;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(QuicPathResponseFrame);
+};
+} // namespace net
+
+#endif // NET_QUIC_CORE_FRAMES_QUIC_PATH_RESPONSE_FRAME_H_
diff --git a/chromium/net/quic/core/frames/quic_stop_sending_frame.cc b/chromium/net/quic/core/frames/quic_stop_sending_frame.cc
new file mode 100644
index 00000000000..203baeb6076
--- /dev/null
+++ b/chromium/net/quic/core/frames/quic_stop_sending_frame.cc
@@ -0,0 +1,27 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/core/frames/quic_stop_sending_frame.h"
+
+namespace net {
+
+QuicStopSendingFrame::QuicStopSendingFrame()
+ : stream_id(0), application_error_code(0) {}
+
+QuicStopSendingFrame::QuicStopSendingFrame(
+ QuicControlFrameId control_frame_id,
+ QuicStreamId stream_id,
+ QuicApplicationErrorCode application_error_code)
+ : QuicControlFrame(control_frame_id),
+ stream_id(stream_id),
+ application_error_code(application_error_code) {}
+
+std::ostream& operator<<(std::ostream& os, const QuicStopSendingFrame& frame) {
+ os << "{ control_frame_id: " << frame.control_frame_id
+ << ", stream_id: " << frame.stream_id
+ << ", application_error_code: " << frame.application_error_code << " }\n";
+ return os;
+}
+
+} // namespace net
diff --git a/chromium/net/quic/core/frames/quic_stop_sending_frame.h b/chromium/net/quic/core/frames/quic_stop_sending_frame.h
new file mode 100644
index 00000000000..0cc2c55192e
--- /dev/null
+++ b/chromium/net/quic/core/frames/quic_stop_sending_frame.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_CORE_FRAMES_QUIC_STOP_SENDING_FRAME_H_
+#define NET_QUIC_CORE_FRAMES_QUIC_STOP_SENDING_FRAME_H_
+
+#include <ostream>
+
+#include "net/quic/core/frames/quic_control_frame.h"
+#include "net/quic/core/quic_error_codes.h"
+
+namespace net {
+
+struct QUIC_EXPORT_PRIVATE QuicStopSendingFrame : public QuicControlFrame {
+ QuicStopSendingFrame();
+ QuicStopSendingFrame(QuicControlFrameId control_frame_id,
+ QuicStreamId stream_id,
+ uint16_t application_error_code);
+
+ friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
+ std::ostream& os,
+ const QuicStopSendingFrame& frame);
+
+ QuicStreamId stream_id;
+ QuicApplicationErrorCode application_error_code;
+};
+
+} // namespace net
+
+#endif // NET_QUIC_CORE_FRAMES_QUIC_STOP_SENDING_FRAME_H_
diff --git a/chromium/net/quic/core/frames/quic_window_update_frame.h b/chromium/net/quic/core/frames/quic_window_update_frame.h
index e94496658e7..fa2f973e66f 100644
--- a/chromium/net/quic/core/frames/quic_window_update_frame.h
+++ b/chromium/net/quic/core/frames/quic_window_update_frame.h
@@ -32,6 +32,10 @@ struct QUIC_EXPORT_PRIVATE QuicWindowUpdateFrame : public QuicControlFrame {
// Byte offset in the stream or connection. The receiver of this frame must
// not send data which would result in this offset being exceeded.
+ //
+ // TODO(fkastenholz): Rename this to max_data and change the type to
+ // QuicByteCount because the IETF defines this as the "maximum
+ // amount of data that can be sent".
QuicStreamOffset byte_offset;
};
diff --git a/chromium/net/quic/core/quic_buffered_packet_store.cc b/chromium/net/quic/core/quic_buffered_packet_store.cc
index 8dc6dd069cb..40429da6ec3 100644
--- a/chromium/net/quic/core/quic_buffered_packet_store.cc
+++ b/chromium/net/quic/core/quic_buffered_packet_store.cc
@@ -54,7 +54,8 @@ BufferedPacket& BufferedPacket::operator=(BufferedPacket&& other) = default;
BufferedPacket::~BufferedPacket() {}
-BufferedPacketList::BufferedPacketList() : creation_time(QuicTime::Zero()) {}
+BufferedPacketList::BufferedPacketList()
+ : creation_time(QuicTime::Zero()), ietf_quic(false) {}
BufferedPacketList::BufferedPacketList(BufferedPacketList&& other) = default;
@@ -78,6 +79,7 @@ QuicBufferedPacketStore::~QuicBufferedPacketStore() {}
EnqueuePacketResult QuicBufferedPacketStore::EnqueuePacket(
QuicConnectionId connection_id,
+ bool ietf_quic,
const QuicReceivedPacket& packet,
QuicSocketAddress server_address,
QuicSocketAddress client_address,
@@ -98,6 +100,7 @@ EnqueuePacketResult QuicBufferedPacketStore::EnqueuePacket(
} else if (!QuicContainsKey(undecryptable_packets_, connection_id)) {
undecryptable_packets_.emplace(
std::make_pair(connection_id, BufferedPacketList()));
+ undecryptable_packets_.back().second.ietf_quic = ietf_quic;
}
CHECK(QuicContainsKey(undecryptable_packets_, connection_id));
BufferedPacketList& queue =
diff --git a/chromium/net/quic/core/quic_buffered_packet_store.h b/chromium/net/quic/core/quic_buffered_packet_store.h
index 42e22feebda..b2271640cee 100644
--- a/chromium/net/quic/core/quic_buffered_packet_store.h
+++ b/chromium/net/quic/core/quic_buffered_packet_store.h
@@ -69,6 +69,8 @@ class QUIC_EXPORT_PRIVATE QuicBufferedPacketStore {
QuicTime creation_time;
// The alpn from the CHLO, if one was found.
QuicString alpn;
+ // Indicating whether this is an IETF QUIC connection.
+ bool ietf_quic;
};
typedef QuicLinkedHashMap<QuicConnectionId, BufferedPacketList>
@@ -95,6 +97,7 @@ class QUIC_EXPORT_PRIVATE QuicBufferedPacketStore {
// Adds a copy of packet into packet queue for given connection.
EnqueuePacketResult EnqueuePacket(QuicConnectionId connection_id,
+ bool ietf_quic,
const QuicReceivedPacket& packet,
QuicSocketAddress server_address,
QuicSocketAddress client_address,
diff --git a/chromium/net/quic/core/quic_buffered_packet_store_test.cc b/chromium/net/quic/core/quic_buffered_packet_store_test.cc
index f7dc69dbb14..aaa29ce2b19 100644
--- a/chromium/net/quic/core/quic_buffered_packet_store_test.cc
+++ b/chromium/net/quic/core/quic_buffered_packet_store_test.cc
@@ -69,8 +69,8 @@ class QuicBufferedPacketStoreTest : public QuicTest {
TEST_F(QuicBufferedPacketStoreTest, SimpleEnqueueAndDeliverPacket) {
QuicConnectionId connection_id = 1;
- store_.EnqueuePacket(connection_id, packet_, server_address_, client_address_,
- false, "");
+ store_.EnqueuePacket(connection_id, false, packet_, server_address_,
+ client_address_, false, "");
EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
auto packets = store_.DeliverPackets(connection_id);
const std::list<BufferedPacket>& queue = packets.buffered_packets;
@@ -90,9 +90,9 @@ TEST_F(QuicBufferedPacketStoreTest, SimpleEnqueueAndDeliverPacket) {
TEST_F(QuicBufferedPacketStoreTest, DifferentPacketAddressOnOneConnection) {
QuicSocketAddress addr_with_new_port(QuicIpAddress::Any4(), 256);
QuicConnectionId connection_id = 1;
- store_.EnqueuePacket(connection_id, packet_, server_address_, client_address_,
- false, "");
- store_.EnqueuePacket(connection_id, packet_, server_address_,
+ store_.EnqueuePacket(connection_id, false, packet_, server_address_,
+ client_address_, false, "");
+ store_.EnqueuePacket(connection_id, false, packet_, server_address_,
addr_with_new_port, false, "");
std::list<BufferedPacket> queue =
store_.DeliverPackets(connection_id).buffered_packets;
@@ -107,9 +107,9 @@ TEST_F(QuicBufferedPacketStoreTest,
size_t num_connections = 10;
for (QuicConnectionId connection_id = 1; connection_id <= num_connections;
++connection_id) {
- store_.EnqueuePacket(connection_id, packet_, server_address_,
+ store_.EnqueuePacket(connection_id, false, packet_, server_address_,
client_address_, false, "");
- store_.EnqueuePacket(connection_id, packet_, server_address_,
+ store_.EnqueuePacket(connection_id, false, packet_, server_address_,
client_address_, false, "");
}
@@ -131,12 +131,13 @@ TEST_F(QuicBufferedPacketStoreTest,
// Arrived CHLO packet shouldn't affect how many non-CHLO pacekts store can
// keep.
EXPECT_EQ(QuicBufferedPacketStore::SUCCESS,
- store_.EnqueuePacket(connection_id, packet_, server_address_,
+ store_.EnqueuePacket(connection_id, false, packet_, server_address_,
client_address_, true, ""));
for (size_t i = 1; i <= num_packets; ++i) {
// Only first |kDefaultMaxUndecryptablePackets packets| will be buffered.
- EnqueuePacketResult result = store_.EnqueuePacket(
- connection_id, packet_, server_address_, client_address_, false, "");
+ EnqueuePacketResult result =
+ store_.EnqueuePacket(connection_id, false, packet_, server_address_,
+ client_address_, false, "");
if (i <= kDefaultMaxUndecryptablePackets) {
EXPECT_EQ(EnqueuePacketResult::SUCCESS, result);
} else {
@@ -156,8 +157,9 @@ TEST_F(QuicBufferedPacketStoreTest, ReachNonChloConnectionUpperLimit) {
const size_t kNumConnections = kMaxConnectionsWithoutCHLO + 1;
for (size_t connection_id = 1; connection_id <= kNumConnections;
++connection_id) {
- EnqueuePacketResult result = store_.EnqueuePacket(
- connection_id, packet_, server_address_, client_address_, false, "");
+ EnqueuePacketResult result =
+ store_.EnqueuePacket(connection_id, false, packet_, server_address_,
+ client_address_, false, "");
if (connection_id <= kMaxConnectionsWithoutCHLO) {
EXPECT_EQ(EnqueuePacketResult::SUCCESS, result);
} else {
@@ -185,8 +187,8 @@ TEST_F(QuicBufferedPacketStoreTest,
kDefaultMaxConnectionsInStore - kMaxConnectionsWithoutCHLO + 1;
for (size_t connection_id = 1; connection_id <= num_chlos; ++connection_id) {
EXPECT_EQ(EnqueuePacketResult::SUCCESS,
- store_.EnqueuePacket(connection_id, packet_, server_address_,
- client_address_, true, ""));
+ store_.EnqueuePacket(connection_id, false, packet_,
+ server_address_, client_address_, true, ""));
}
// Send data packets on another |kMaxConnectionsWithoutCHLO| connections.
@@ -194,7 +196,7 @@ TEST_F(QuicBufferedPacketStoreTest,
for (size_t conn_id = num_chlos + 1;
conn_id <= (kDefaultMaxConnectionsInStore + 1); ++conn_id) {
EnqueuePacketResult result = store_.EnqueuePacket(
- conn_id, packet_, server_address_, client_address_, true, "");
+ conn_id, false, packet_, server_address_, client_address_, true, "");
if (conn_id <= kDefaultMaxConnectionsInStore) {
EXPECT_EQ(EnqueuePacketResult::SUCCESS, result);
} else {
@@ -208,7 +210,7 @@ TEST_F(QuicBufferedPacketStoreTest, EnqueueChloOnTooManyDifferentConnections) {
for (QuicConnectionId conn_id = 1; conn_id <= kMaxConnectionsWithoutCHLO;
++conn_id) {
EXPECT_EQ(EnqueuePacketResult::SUCCESS,
- store_.EnqueuePacket(conn_id, packet_, server_address_,
+ store_.EnqueuePacket(conn_id, false, packet_, server_address_,
client_address_, false, ""));
}
@@ -216,8 +218,8 @@ TEST_F(QuicBufferedPacketStoreTest, EnqueueChloOnTooManyDifferentConnections) {
for (size_t i = kMaxConnectionsWithoutCHLO + 1;
i <= kDefaultMaxConnectionsInStore + 1; ++i) {
EnqueuePacketResult rs = store_.EnqueuePacket(
- /*connection_id=*/i, packet_, server_address_, client_address_, true,
- "");
+ /*connection_id=*/i, false, packet_, server_address_, client_address_,
+ true, "");
if (i <= kDefaultMaxConnectionsInStore) {
EXPECT_EQ(EnqueuePacketResult::SUCCESS, rs);
EXPECT_TRUE(store_.HasChloForConnection(/*connection_id=*/i));
@@ -232,8 +234,8 @@ TEST_F(QuicBufferedPacketStoreTest, EnqueueChloOnTooManyDifferentConnections) {
// buffered in the store should success. This is the connection should be
// delivered at last.
EXPECT_EQ(EnqueuePacketResult::SUCCESS,
- store_.EnqueuePacket(/*connection_id=*/1, packet_, server_address_,
- client_address_, true, ""));
+ store_.EnqueuePacket(/*connection_id=*/1, false, packet_,
+ server_address_, client_address_, true, ""));
EXPECT_TRUE(store_.HasChloForConnection(/*connection_id=*/1));
QuicConnectionId delivered_conn_id;
@@ -258,15 +260,15 @@ TEST_F(QuicBufferedPacketStoreTest, EnqueueChloOnTooManyDifferentConnections) {
// connections both with and without CHLOs.
TEST_F(QuicBufferedPacketStoreTest, PacketQueueExpiredBeforeDelivery) {
QuicConnectionId connection_id = 1;
- store_.EnqueuePacket(connection_id, packet_, server_address_, client_address_,
- false, "");
+ store_.EnqueuePacket(connection_id, false, packet_, server_address_,
+ client_address_, false, "");
EXPECT_EQ(EnqueuePacketResult::SUCCESS,
- store_.EnqueuePacket(connection_id, packet_, server_address_,
+ store_.EnqueuePacket(connection_id, false, packet_, server_address_,
client_address_, true, ""));
QuicConnectionId connection_id2 = 2;
EXPECT_EQ(EnqueuePacketResult::SUCCESS,
- store_.EnqueuePacket(connection_id2, packet_, server_address_,
- client_address_, false, ""));
+ store_.EnqueuePacket(connection_id2, false, packet_,
+ server_address_, client_address_, false, ""));
// CHLO on connection 3 arrives 1ms later.
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
@@ -274,7 +276,7 @@ TEST_F(QuicBufferedPacketStoreTest, PacketQueueExpiredBeforeDelivery) {
// Use different client address to differetiate packets from different
// connections.
QuicSocketAddress another_client_address(QuicIpAddress::Any4(), 255);
- store_.EnqueuePacket(connection_id3, packet_, server_address_,
+ store_.EnqueuePacket(connection_id3, false, packet_, server_address_,
another_client_address, true, "");
// Advance clock to the time when connection 1 and 2 expires.
@@ -306,9 +308,9 @@ TEST_F(QuicBufferedPacketStoreTest, PacketQueueExpiredBeforeDelivery) {
// Test the alarm is reset by enqueueing 2 packets for 4th connection and wait
// for them to expire.
QuicConnectionId connection_id4 = 4;
- store_.EnqueuePacket(connection_id4, packet_, server_address_,
+ store_.EnqueuePacket(connection_id4, false, packet_, server_address_,
client_address_, false, "");
- store_.EnqueuePacket(connection_id4, packet_, server_address_,
+ store_.EnqueuePacket(connection_id4, false, packet_, server_address_,
client_address_, false, "");
clock_.AdvanceTime(
QuicBufferedPacketStorePeer::expiration_alarm(&store_)->deadline() -
@@ -323,10 +325,10 @@ TEST_F(QuicBufferedPacketStoreTest, SimpleDiscardPackets) {
QuicConnectionId connection_id = 1;
// Enqueue some packets
- store_.EnqueuePacket(connection_id, packet_, server_address_, client_address_,
- false, "");
- store_.EnqueuePacket(connection_id, packet_, server_address_, client_address_,
- false, "");
+ store_.EnqueuePacket(connection_id, false, packet_, server_address_,
+ client_address_, false, "");
+ store_.EnqueuePacket(connection_id, false, packet_, server_address_,
+ client_address_, false, "");
EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
EXPECT_FALSE(store_.HasChlosBuffered());
@@ -349,12 +351,12 @@ TEST_F(QuicBufferedPacketStoreTest, DiscardWithCHLOs) {
QuicConnectionId connection_id = 1;
// Enqueue some packets, which include a CHLO
- store_.EnqueuePacket(connection_id, packet_, server_address_, client_address_,
- false, "");
- store_.EnqueuePacket(connection_id, packet_, server_address_, client_address_,
- true, "");
- store_.EnqueuePacket(connection_id, packet_, server_address_, client_address_,
- false, "");
+ store_.EnqueuePacket(connection_id, false, packet_, server_address_,
+ client_address_, false, "");
+ store_.EnqueuePacket(connection_id, false, packet_, server_address_,
+ client_address_, true, "");
+ store_.EnqueuePacket(connection_id, false, packet_, server_address_,
+ client_address_, false, "");
EXPECT_TRUE(store_.HasBufferedPackets(connection_id));
EXPECT_TRUE(store_.HasChlosBuffered());
@@ -378,11 +380,11 @@ TEST_F(QuicBufferedPacketStoreTest, MultipleDiscardPackets) {
QuicConnectionId connection_id_2 = 2;
// Enqueue some packets for two connection IDs
- store_.EnqueuePacket(connection_id_1, packet_, server_address_,
+ store_.EnqueuePacket(connection_id_1, false, packet_, server_address_,
client_address_, false, "");
- store_.EnqueuePacket(connection_id_1, packet_, server_address_,
+ store_.EnqueuePacket(connection_id_1, false, packet_, server_address_,
client_address_, false, "");
- store_.EnqueuePacket(connection_id_2, packet_, server_address_,
+ store_.EnqueuePacket(connection_id_2, false, packet_, server_address_,
client_address_, true, "h3");
EXPECT_TRUE(store_.HasBufferedPackets(connection_id_1));
EXPECT_TRUE(store_.HasBufferedPackets(connection_id_2));
diff --git a/chromium/net/quic/core/quic_client_promised_info_test.cc b/chromium/net/quic/core/quic_client_promised_info_test.cc
index 54a4c919f16..3fae76e470c 100644
--- a/chromium/net/quic/core/quic_client_promised_info_test.cc
+++ b/chromium/net/quic/core/quic_client_promised_info_test.cc
@@ -138,14 +138,9 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseCleanupAlarm) {
ASSERT_NE(promised, nullptr);
// Fire the alarm that will cancel the promised stream.
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promise_id_, QUIC_PUSH_STREAM_TIMED_OUT));
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(promise_id_, QUIC_PUSH_STREAM_TIMED_OUT, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(promise_id_, QUIC_PUSH_STREAM_TIMED_OUT));
alarm_factory_.FireAlarm(QuicClientPromisedInfoPeer::GetAlarm(promised));
// Verify that the promise is gone after the alarm fires.
@@ -157,14 +152,9 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseInvalidMethod) {
// Promise with an unsafe method
push_promise_[":method"] = "PUT";
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD));
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(promise_id_, QUIC_INVALID_PROMISE_METHOD, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD));
ReceivePromise(promise_id_);
// Verify that the promise headers were ignored
@@ -176,14 +166,9 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseMissingMethod) {
// Promise with a missing method
push_promise_.erase(":method");
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD));
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(promise_id_, QUIC_INVALID_PROMISE_METHOD, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_METHOD));
ReceivePromise(promise_id_);
// Verify that the promise headers were ignored
@@ -195,14 +180,9 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseInvalidUrl) {
// Remove required header field to make URL invalid
push_promise_.erase(":authority");
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_URL));
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(promise_id_, QUIC_INVALID_PROMISE_URL, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(promise_id_, QUIC_INVALID_PROMISE_URL));
ReceivePromise(promise_id_);
// Verify that the promise headers were ignored
@@ -213,14 +193,9 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseInvalidUrl) {
TEST_F(QuicClientPromisedInfoTest, PushPromiseUnauthorizedUrl) {
session_.set_authorized(false);
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promise_id_, QUIC_UNAUTHORIZED_PROMISE_URL));
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(promise_id_, QUIC_UNAUTHORIZED_PROMISE_URL, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(promise_id_, QUIC_UNAUTHORIZED_PROMISE_URL));
ReceivePromise(promise_id_);
@@ -243,14 +218,9 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseMismatch) {
headers);
TestPushPromiseDelegate delegate(/*match=*/false);
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promise_id_, QUIC_PROMISE_VARY_MISMATCH));
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(promise_id_, QUIC_PROMISE_VARY_MISMATCH, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(promise_id_, QUIC_PROMISE_VARY_MISMATCH));
EXPECT_CALL(session_, CloseStream(promise_id_));
promised->HandleClientRequest(client_request_, &delegate);
@@ -328,14 +298,8 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseWaitCancels) {
// Cancel the promised stream.
EXPECT_CALL(session_, CloseStream(promise_id_));
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promise_id_, QUIC_STREAM_CANCELLED));
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(promise_id_, QUIC_STREAM_CANCELLED, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(promise_id_, QUIC_STREAM_CANCELLED));
promised->Cancel();
// Promise is gone
@@ -358,14 +322,9 @@ TEST_F(QuicClientPromisedInfoTest, PushPromiseDataClosed) {
headers);
EXPECT_CALL(session_, CloseStream(promise_id_));
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promise_id_, QUIC_STREAM_PEER_GOING_AWAY));
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(promise_id_, QUIC_STREAM_PEER_GOING_AWAY, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(promise_id_, QUIC_STREAM_PEER_GOING_AWAY));
session_.SendRstStream(promise_id_, QUIC_STREAM_PEER_GOING_AWAY, 0);
// Now initiate rendezvous.
diff --git a/chromium/net/quic/core/quic_config.cc b/chromium/net/quic/core/quic_config.cc
index 4a3d18f810f..0a89a756ee6 100644
--- a/chromium/net/quic/core/quic_config.cc
+++ b/chromium/net/quic/core/quic_config.cc
@@ -17,7 +17,6 @@
#include "net/quic/platform/api/quic_string.h"
#include "net/quic/platform/api/quic_string_piece.h"
-
namespace net {
// Reads the value corresponding to |name_| from |msg| into |out|. If the
@@ -190,13 +189,13 @@ bool QuicFixedUint128::HasSendValue() const {
return has_send_value_;
}
-uint128 QuicFixedUint128::GetSendValue() const {
+QuicUint128 QuicFixedUint128::GetSendValue() const {
QUIC_BUG_IF(!has_send_value_)
<< "No send value to get for tag:" << QuicTagToString(tag_);
return send_value_;
}
-void QuicFixedUint128::SetSendValue(uint128 value) {
+void QuicFixedUint128::SetSendValue(QuicUint128 value) {
has_send_value_ = true;
send_value_ = value;
}
@@ -205,13 +204,13 @@ bool QuicFixedUint128::HasReceivedValue() const {
return has_receive_value_;
}
-uint128 QuicFixedUint128::GetReceivedValue() const {
+QuicUint128 QuicFixedUint128::GetReceivedValue() const {
QUIC_BUG_IF(!has_receive_value_)
<< "No receive value to get for tag:" << QuicTagToString(tag_);
return receive_value_;
}
-void QuicFixedUint128::SetReceivedValue(uint128 value) {
+void QuicFixedUint128::SetReceivedValue(QuicUint128 value) {
has_receive_value_ = true;
receive_value_ = value;
}
@@ -399,7 +398,6 @@ QuicConfig::QuicConfig()
initial_round_trip_time_us_(kIRTT, PRESENCE_OPTIONAL),
initial_stream_flow_control_window_bytes_(kSFCW, PRESENCE_OPTIONAL),
initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL),
- socket_receive_buffer_(kSRBF, PRESENCE_OPTIONAL),
connection_migration_disabled_(kNCMR, PRESENCE_OPTIONAL),
alternate_server_address_(kASAD, PRESENCE_OPTIONAL),
support_max_header_list_size_(kSMHL, PRESENCE_OPTIONAL),
@@ -633,7 +631,8 @@ bool QuicConfig::SupportMaxHeaderListSize() const {
return support_max_header_list_size_.HasReceivedValue();
}
-void QuicConfig::SetStatelessResetTokenToSend(uint128 stateless_reset_token) {
+void QuicConfig::SetStatelessResetTokenToSend(
+ QuicUint128 stateless_reset_token) {
stateless_reset_token_.SetSendValue(stateless_reset_token);
}
@@ -641,7 +640,7 @@ bool QuicConfig::HasReceivedStatelessResetToken() const {
return stateless_reset_token_.HasReceivedValue();
}
-uint128 QuicConfig::ReceivedStatelessResetToken() const {
+QuicUint128 QuicConfig::ReceivedStatelessResetToken() const {
return stateless_reset_token_.GetReceivedValue();
}
diff --git a/chromium/net/quic/core/quic_config.h b/chromium/net/quic/core/quic_config.h
index 3f2be56636d..c421198f3f9 100644
--- a/chromium/net/quic/core/quic_config.h
+++ b/chromium/net/quic/core/quic_config.h
@@ -8,11 +8,11 @@
#include <cstddef>
#include <cstdint>
-#include "net/base/int128.h"
#include "net/quic/core/quic_packets.h"
#include "net/quic/core/quic_time.h"
#include "net/quic/platform/api/quic_export.h"
#include "net/quic/platform/api/quic_string.h"
+#include "net/quic/platform/api/quic_uint128.h"
namespace net {
@@ -155,15 +155,15 @@ class QUIC_EXPORT_PRIVATE QuicFixedUint128 : public QuicConfigValue {
bool HasSendValue() const;
- uint128 GetSendValue() const;
+ QuicUint128 GetSendValue() const;
- void SetSendValue(uint128 value);
+ void SetSendValue(QuicUint128 value);
bool HasReceivedValue() const;
- uint128 GetReceivedValue() const;
+ QuicUint128 GetReceivedValue() const;
- void SetReceivedValue(uint128 value);
+ void SetReceivedValue(QuicUint128 value);
// If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
@@ -174,9 +174,9 @@ class QUIC_EXPORT_PRIVATE QuicFixedUint128 : public QuicConfigValue {
QuicString* error_details) override;
private:
- uint128 send_value_;
+ QuicUint128 send_value_;
bool has_send_value_;
- uint128 receive_value_;
+ QuicUint128 receive_value_;
bool has_receive_value_;
};
@@ -393,11 +393,11 @@ class QUIC_EXPORT_PRIVATE QuicConfig {
bool SupportMaxHeaderListSize() const;
- void SetStatelessResetTokenToSend(uint128 stateless_reset_token);
+ void SetStatelessResetTokenToSend(QuicUint128 stateless_reset_token);
bool HasReceivedStatelessResetToken() const;
- uint128 ReceivedStatelessResetToken() const;
+ QuicUint128 ReceivedStatelessResetToken() const;
bool negotiated() const;
@@ -453,10 +453,6 @@ class QUIC_EXPORT_PRIVATE QuicConfig {
// Initial session flow control receive window in bytes.
QuicFixedUint32 initial_session_flow_control_window_bytes_;
- // Socket receive buffer in bytes.
- // TODO(ianswett): Deprecate once QUIC_VERSION_34 is deprecated.
- QuicFixedUint32 socket_receive_buffer_;
-
// Whether tell peer not to attempt connection migration.
QuicFixedUint32 connection_migration_disabled_;
diff --git a/chromium/net/quic/core/quic_config_test.cc b/chromium/net/quic/core/quic_config_test.cc
index 630f631d653..6b1f620e855 100644
--- a/chromium/net/quic/core/quic_config_test.cc
+++ b/chromium/net/quic/core/quic_config_test.cc
@@ -11,11 +11,11 @@
#include "net/quic/core/quic_utils.h"
#include "net/quic/platform/api/quic_string.h"
#include "net/quic/platform/api/quic_test.h"
+#include "net/quic/platform/api/quic_uint128.h"
#include "net/quic/test_tools/quic_config_peer.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/test/gtest_util.h"
-
namespace net {
namespace test {
namespace {
@@ -107,7 +107,7 @@ TEST_F(QuicConfigTest, ProcessServerHello) {
QuicIpAddress host;
host.FromString("127.0.3.1");
const QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
- const uint128 kTestResetToken = MakeUint128(0, 10111100001);
+ const QuicUint128 kTestResetToken = MakeQuicUint128(0, 10111100001);
QuicConfig server_config;
QuicTagVector cgst;
cgst.push_back(kQBIC);
diff --git a/chromium/net/quic/core/quic_connection.cc b/chromium/net/quic/core/quic_connection.cc
index d7127b07efd..77ca7bd1eec 100644
--- a/chromium/net/quic/core/quic_connection.cc
+++ b/chromium/net/quic/core/quic_connection.cc
@@ -126,6 +126,19 @@ class SendAlarmDelegate : public QuicAlarm::Delegate {
DISALLOW_COPY_AND_ASSIGN(SendAlarmDelegate);
};
+class PathDegradingAlarmDelegate : public QuicAlarm::Delegate {
+ public:
+ explicit PathDegradingAlarmDelegate(QuicConnection* connection)
+ : connection_(connection) {}
+
+ void OnAlarm() override { connection_->OnPathDegradingTimeout(); }
+
+ private:
+ QuicConnection* connection_;
+
+ DISALLOW_COPY_AND_ASSIGN(PathDegradingAlarmDelegate);
+};
+
class TimeoutAlarmDelegate : public QuicAlarm::Delegate {
public:
explicit TimeoutAlarmDelegate(QuicConnection* connection)
@@ -165,6 +178,19 @@ class MtuDiscoveryAlarmDelegate : public QuicAlarm::Delegate {
DISALLOW_COPY_AND_ASSIGN(MtuDiscoveryAlarmDelegate);
};
+class RetransmittableOnWireAlarmDelegate : public QuicAlarm::Delegate {
+ public:
+ explicit RetransmittableOnWireAlarmDelegate(QuicConnection* connection)
+ : connection_(connection) {}
+
+ void OnAlarm() override { connection_->OnPingTimeout(); }
+
+ private:
+ QuicConnection* connection_;
+
+ DISALLOW_COPY_AND_ASSIGN(RetransmittableOnWireAlarmDelegate);
+};
+
} // namespace
#define ENDPOINT \
@@ -184,6 +210,7 @@ QuicConnection::QuicConnection(
perspective),
current_packet_content_(NO_FRAMES_RECEIVED),
current_peer_migration_type_(NO_CHANGE),
+ current_effective_peer_migration_type_(NO_CHANGE),
helper_(helper),
alarm_factory_(alarm_factory),
per_packet_options_(nullptr),
@@ -194,8 +221,11 @@ QuicConnection::QuicConnection(
random_generator_(helper->GetRandomGenerator()),
connection_id_(connection_id),
peer_address_(initial_peer_address),
+ direct_peer_address_(initial_peer_address),
active_peer_migration_type_(NO_CHANGE),
highest_packet_sent_before_peer_migration_(0),
+ active_effective_peer_migration_type_(NO_CHANGE),
+ highest_packet_sent_before_effective_peer_migration_(0),
last_packet_decrypted_(false),
last_size_(0),
current_packet_data_(nullptr),
@@ -225,6 +255,7 @@ QuicConnection::QuicConnection(
pending_retransmission_alarm_(false),
defer_send_in_response_to_packets_(false),
ping_timeout_(QuicTime::Delta::FromSeconds(kPingTimeoutSecs)),
+ retransmittable_on_wire_timeout_(QuicTime::Delta::Infinite()),
arena_(),
ack_alarm_(alarm_factory_->CreateAlarm(arena_.New<AckAlarmDelegate>(this),
&arena_)),
@@ -246,6 +277,12 @@ QuicConnection::QuicConnection(
mtu_discovery_alarm_(alarm_factory_->CreateAlarm(
arena_.New<MtuDiscoveryAlarmDelegate>(this),
&arena_)),
+ retransmittable_on_wire_alarm_(alarm_factory_->CreateAlarm(
+ arena_.New<RetransmittableOnWireAlarmDelegate>(this),
+ &arena_)),
+ path_degrading_alarm_(alarm_factory_->CreateAlarm(
+ arena_.New<PathDegradingAlarmDelegate>(this),
+ &arena_)),
visitor_(nullptr),
debug_visitor_(nullptr),
packet_generator_(connection_id_, &framer_, random_generator_, this),
@@ -273,9 +310,18 @@ QuicConnection::QuicConnection(
consecutive_num_packets_with_no_retransmittable_frames_(0),
fill_up_link_during_probing_(false),
probing_retransmission_pending_(false),
+ stateless_reset_token_received_(false),
+ received_stateless_reset_token_(0),
last_control_frame_id_(kInvalidControlFrameId),
- use_control_frame_manager_(
- GetQuicReloadableFlag(quic_use_control_frame_manager)) {
+ negotiate_version_early_(
+ GetQuicReloadableFlag(quic_server_early_version_negotiation)),
+ always_discard_packets_after_close_(
+ GetQuicReloadableFlag(quic_always_discard_packets_after_close)),
+ handle_write_results_for_connectivity_probe_(GetQuicReloadableFlag(
+ quic_handle_write_results_for_connectivity_probe)),
+ use_path_degrading_alarm_(
+ GetQuicReloadableFlag(quic_path_degrading_alarm)),
+ enable_server_proxy_(GetQuicReloadableFlag(quic_enable_server_proxy)) {
QUIC_DLOG(INFO) << ENDPOINT
<< "Created connection with connection_id: " << connection_id
<< " and version: "
@@ -372,6 +418,10 @@ void QuicConnection::SetFromConfig(const QuicConfig& config) {
config.HasClientSentConnectionOption(kNSTP, perspective_)) {
no_stop_waiting_frames_ = true;
}
+ if (config.HasReceivedStatelessResetToken()) {
+ stateless_reset_token_received_ = true;
+ received_stateless_reset_token_ = config.ReceivedStatelessResetToken();
+ }
}
void QuicConnection::OnSendConnectionState(
@@ -468,7 +518,7 @@ bool QuicConnection::OnProtocolVersionMismatch(
QUIC_BUG << ENDPOINT << error_details;
TearDownLocalConnectionState(QUIC_INTERNAL_ERROR, error_details,
ConnectionCloseSource::FROM_SELF);
- RecordInternalErrorLocation(QUIC_CONNECTION_1);
+ RecordInternalErrorLocation(QUIC_CONNECTION_PROTOCOL_VERSION_MISMATCH);
return false;
}
DCHECK_NE(version(), received_version);
@@ -505,6 +555,7 @@ bool QuicConnection::OnProtocolVersionMismatch(
const bool set_version_early =
GetQuicReloadableFlag(quic_store_version_before_signalling);
if (set_version_early) {
+ QUIC_FLAG_COUNT(quic_reloadable_flag_quic_store_version_before_signalling);
// Store the new version.
framer_.set_version(received_version);
}
@@ -512,8 +563,7 @@ bool QuicConnection::OnProtocolVersionMismatch(
version_negotiation_state_ = NEGOTIATED_VERSION;
visitor_->OnSuccessfulVersionNegotiation(received_version);
if (debug_visitor_ != nullptr) {
- debug_visitor_->OnSuccessfulVersionNegotiation(
- received_version.transport_version);
+ debug_visitor_->OnSuccessfulVersionNegotiation(received_version);
}
QUIC_DLOG(INFO) << ENDPOINT << "version negotiated "
<< ParsedQuicVersionToString(received_version);
@@ -544,7 +594,7 @@ void QuicConnection::OnVersionNegotiationPacket(
QUIC_BUG << error_details;
TearDownLocalConnectionState(QUIC_INTERNAL_ERROR, error_details,
ConnectionCloseSource::FROM_SELF);
- RecordInternalErrorLocation(QUIC_CONNECTION_2);
+ RecordInternalErrorLocation(QUIC_CONNECTION_VERSION_NEGOTIATION_PACKET);
return;
}
if (debug_visitor_ != nullptr) {
@@ -625,7 +675,7 @@ bool QuicConnection::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
QUIC_BUG << error_details;
CloseConnection(QUIC_INTERNAL_ERROR, error_details,
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- RecordInternalErrorLocation(QUIC_CONNECTION_3);
+ RecordInternalErrorLocation(QUIC_CONNECTION_UNAUTHENTICATED_HEADER);
return false;
}
@@ -641,6 +691,31 @@ bool QuicConnection::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
return false;
}
+ if (negotiate_version_early_ &&
+ version_negotiation_state_ != NEGOTIATED_VERSION &&
+ perspective_ == Perspective::IS_SERVER) {
+ QUIC_FLAG_COUNT(quic_reloadable_flag_quic_server_early_version_negotiation);
+ if (!header.version_flag) {
+ // Packets should have the version flag till version negotiation is
+ // done.
+ QuicString error_details =
+ QuicStrCat(ENDPOINT, "Packet ", header.packet_number,
+ " without version flag before version negotiated.");
+ QUIC_DLOG(WARNING) << error_details;
+ CloseConnection(QUIC_INVALID_VERSION, error_details,
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return false;
+ } else {
+ DCHECK_EQ(header.version, version());
+ version_negotiation_state_ = NEGOTIATED_VERSION;
+ visitor_->OnSuccessfulVersionNegotiation(version());
+ if (debug_visitor_ != nullptr) {
+ debug_visitor_->OnSuccessfulVersionNegotiation(version());
+ }
+ }
+ DCHECK_EQ(NEGOTIATED_VERSION, version_negotiation_state_);
+ }
+
return true;
}
@@ -656,6 +731,14 @@ void QuicConnection::OnDecryptedPacket(EncryptionLevel level) {
}
}
+QuicSocketAddress QuicConnection::GetEffectivePeerAddressFromCurrentPacket()
+ const {
+ DCHECK(enable_server_proxy_);
+ // By default, the connection is not proxied, and the effective peer address
+ // is the packet's source address, i.e. the direct peer address.
+ return last_packet_source_address_;
+}
+
bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
if (debug_visitor_ != nullptr) {
debug_visitor_->OnPacketHeader(header);
@@ -670,26 +753,68 @@ bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
// Initialize the current packet content stats.
current_packet_content_ = NO_FRAMES_RECEIVED;
- current_peer_migration_type_ = NO_CHANGE;
- AddressChangeType peer_migration_type = QuicUtils::DetermineAddressChangeType(
- peer_address_, last_packet_source_address_);
-
- // Initiate connection migration if a non-reordered packet is received from a
- // new address.
- if (header.packet_number > received_packet_manager_.GetLargestObserved() &&
- peer_migration_type != NO_CHANGE) {
- QUIC_DLOG(INFO) << ENDPOINT << "Peer's ip:port changed from "
- << peer_address_.ToString() << " to "
- << last_packet_source_address_.ToString();
- if (perspective_ == Perspective::IS_CLIENT) {
- peer_address_ = last_packet_source_address_;
- } else if (active_peer_migration_type_ == NO_CHANGE) {
- // Only migrate connection to a new peer address if there is no
- // pending change underway.
- // Cache the current migration change type, which will start peer
- // migration immediately if this packet is not a connectivity probing
- // packet.
- current_peer_migration_type_ = peer_migration_type;
+ is_current_packet_connectivity_probing_ = false;
+
+ if (!enable_server_proxy_) {
+ current_peer_migration_type_ = NO_CHANGE;
+
+ AddressChangeType peer_migration_type =
+ QuicUtils::DetermineAddressChangeType(peer_address_,
+ last_packet_source_address_);
+ // Initiate connection migration if a non-reordered packet is received from
+ // a new address.
+ if (header.packet_number > received_packet_manager_.GetLargestObserved() &&
+ peer_migration_type != NO_CHANGE) {
+ QUIC_DLOG(INFO) << ENDPOINT << "Peer's ip:port changed from "
+ << peer_address_.ToString() << " to "
+ << last_packet_source_address_.ToString();
+ if (perspective_ == Perspective::IS_CLIENT) {
+ peer_address_ = last_packet_source_address_;
+ } else if (active_peer_migration_type_ == NO_CHANGE) {
+ // Only migrate connection to a new peer address if there is no
+ // pending change underway.
+ // Cache the current migration change type, which will start peer
+ // migration immediately if this packet is not a connectivity probing
+ // packet.
+ current_peer_migration_type_ = peer_migration_type;
+ }
+ }
+ } else {
+ current_effective_peer_migration_type_ = NO_CHANGE;
+ // Initiate connection migration if a non-reordered packet is received from
+ // a new address.
+ if (header.packet_number > received_packet_manager_.GetLargestObserved()) {
+ if (perspective_ == Perspective::IS_CLIENT) {
+ // Update peer_address_ and effective_peer_address_ immediately for
+ // client connections.
+ direct_peer_address_ = last_packet_source_address_;
+ effective_peer_address_ = GetEffectivePeerAddressFromCurrentPacket();
+ } else {
+ // At server, direct_peer_address_ and effective_peer_address_ will be
+ // updated once the current packet is confirmed to be not a connectivity
+ // probing packet.
+ AddressChangeType effective_peer_migration_type =
+ QuicUtils::DetermineAddressChangeType(
+ effective_peer_address_,
+ GetEffectivePeerAddressFromCurrentPacket());
+
+ if (effective_peer_migration_type != NO_CHANGE) {
+ QUIC_DLOG(INFO)
+ << ENDPOINT << "Effective peer's ip:port changed from "
+ << effective_peer_address_.ToString() << " to "
+ << GetEffectivePeerAddressFromCurrentPacket().ToString()
+ << ", active_effective_peer_migration_type is "
+ << active_effective_peer_migration_type_;
+ if (active_effective_peer_migration_type_ == NO_CHANGE) {
+ // Only migrate connection to a new effective peer address if there
+ // is no pending change underway. Cache the current migration change
+ // type, which will start effective peer migration immediately if
+ // this packet is not a connectivity probing packet.
+ current_effective_peer_migration_type_ =
+ effective_peer_migration_type;
+ }
+ }
+ }
}
}
@@ -772,9 +897,14 @@ bool QuicConnection::OnAckFrame(const QuicAckFrame& incoming_ack) {
if (send_alarm_->IsSet()) {
send_alarm_->Cancel();
}
+
+ if (LargestAcked(incoming_ack) > sent_packet_manager_.GetLargestObserved()) {
+ visitor_->OnForwardProgressConfirmed();
+ }
+
largest_seen_packet_with_ack_ = last_header_.packet_number;
- sent_packet_manager_.OnIncomingAck(incoming_ack,
- time_of_last_received_packet_);
+ bool acked_new_packet = sent_packet_manager_.OnIncomingAck(
+ incoming_ack, time_of_last_received_packet_);
// If the incoming ack's packets set expresses missing packets: peer is still
// waiting for a packet lower than a packet that we are no longer planning to
// send.
@@ -782,7 +912,8 @@ bool QuicConnection::OnAckFrame(const QuicAckFrame& incoming_ack) {
// acking packets which we never care about.
// Send an ack to raise the high water mark.
PostProcessAfterAckFrame(!incoming_ack.packets.Empty() &&
- GetLeastUnacked() > incoming_ack.packets.Min());
+ GetLeastUnacked() > incoming_ack.packets.Min(),
+ acked_new_packet);
return connected_;
}
@@ -814,7 +945,9 @@ bool QuicConnection::OnAckFrameStart(QuicPacketNumber largest_acked,
return false;
}
- if (largest_acked < sent_packet_manager_.GetLargestObserved()) {
+ if (largest_acked > sent_packet_manager_.GetLargestObserved()) {
+ visitor_->OnForwardProgressConfirmed();
+ } else if (largest_acked < sent_packet_manager_.GetLargestObserved()) {
QUIC_LOG(INFO) << ENDPOINT << "Peer's largest_observed packet decreased:"
<< largest_acked << " vs "
<< sent_packet_manager_.GetLargestObserved()
@@ -828,7 +961,8 @@ bool QuicConnection::OnAckFrameStart(QuicPacketNumber largest_acked,
return false;
}
- sent_packet_manager_.OnAckFrameStart(largest_acked, ack_delay_time);
+ sent_packet_manager_.OnAckFrameStart(largest_acked, ack_delay_time,
+ time_of_last_received_packet_);
return true;
}
@@ -845,11 +979,12 @@ bool QuicConnection::OnAckRange(QuicPacketNumber start,
return true;
}
- sent_packet_manager_.OnAckRange(start, end, last_range,
- time_of_last_received_packet_);
+ sent_packet_manager_.OnAckRange(start, end);
if (!last_range) {
return true;
}
+ bool acked_new_packet =
+ sent_packet_manager_.OnAckFrameEnd(time_of_last_received_packet_);
if (send_alarm_->IsSet()) {
send_alarm_->Cancel();
}
@@ -860,7 +995,7 @@ bool QuicConnection::OnAckRange(QuicPacketNumber start,
// If the incoming ack's packets set expresses received packets: peer is still
// acking packets which we never care about.
// Send an ack to raise the high water mark.
- PostProcessAfterAckFrame(GetLeastUnacked() > start);
+ PostProcessAfterAckFrame(GetLeastUnacked() > start, acked_new_packet);
return connected_;
}
@@ -1109,10 +1244,27 @@ void QuicConnection::OnPacketComplete() {
<< last_packet_destination_address_.ToString();
visitor_->OnConnectivityProbeReceived(last_packet_destination_address_,
last_packet_source_address_);
- } else if (current_peer_migration_type_ != NO_CHANGE) {
- StartPeerMigration(current_peer_migration_type_);
+ } else {
+ if (!enable_server_proxy_) {
+ if (current_peer_migration_type_ != NO_CHANGE) {
+ StartPeerMigration(current_peer_migration_type_);
+ }
+ } else {
+ if (last_header_.packet_number ==
+ received_packet_manager_.GetLargestObserved()) {
+ direct_peer_address_ = last_packet_source_address_;
+ }
+ if (current_effective_peer_migration_type_ != NO_CHANGE) {
+ StartEffectivePeerMigration(current_effective_peer_migration_type_);
+ }
+ }
+ }
+
+ if (!enable_server_proxy_) {
+ current_peer_migration_type_ = NO_CHANGE;
+ } else {
+ current_effective_peer_migration_type_ = NO_CHANGE;
}
- current_peer_migration_type_ = NO_CHANGE;
// An ack will be sent if a missing retransmittable packet was received;
const bool was_missing =
@@ -1128,6 +1280,20 @@ void QuicConnection::OnPacketComplete() {
CloseIfTooManyOutstandingSentPackets();
}
+bool QuicConnection::IsValidStatelessResetToken(uint128 token) const {
+ return stateless_reset_token_received_ &&
+ token == received_stateless_reset_token_;
+}
+
+void QuicConnection::OnAuthenticatedIetfStatelessResetPacket(
+ const QuicIetfStatelessResetPacket& packet) {
+ // TODO(fayang): Add OnAuthenticatedIetfStatelessResetPacket to
+ // debug_visitor_.
+ const std::string error_details = "Received stateless reset.";
+ TearDownLocalConnectionState(QUIC_PUBLIC_RESET, error_details,
+ ConnectionCloseSource::FROM_PEER);
+}
+
void QuicConnection::MaybeQueueAck(bool was_missing) {
++num_packets_received_since_last_ack_sent_;
// Always send an ack every 20 packets in order to allow the peer to discard
@@ -1202,11 +1368,6 @@ void QuicConnection::ClearLastFrames() {
}
void QuicConnection::CloseIfTooManyOutstandingSentPackets() {
- if (!GetQuicReloadableFlag(
- quic_close_session_on_too_many_outstanding_sent_packets)) {
- return;
- }
-
// This occurs if we don't discard old packets we've seen fast enough. It's
// possible largest observed is less than leaset unacked.
if (sent_packet_manager_.GetLargestObserved() >
@@ -1253,15 +1414,15 @@ void QuicConnection::SendVersionNegotiationPacket() {
QUIC_DLOG(INFO) << ENDPOINT << "Sending version negotiation packet: {"
<< ParsedQuicVersionVectorToString(
framer_.supported_versions())
- << "}";
+ << "}, ietf_quic: " << framer_.last_packet_is_ietf_quic();
std::unique_ptr<QuicEncryptedPacket> version_packet(
packet_generator_.SerializeVersionNegotiationPacket(
- framer_.supported_versions()));
+ framer_.last_packet_is_ietf_quic(), framer_.supported_versions()));
WriteResult result = writer_->WritePacket(
version_packet->data(), version_packet->length(), self_address().host(),
peer_address(), per_packet_options_);
- if (result.status == WRITE_STATUS_ERROR) {
+ if (IsWriteError(result.status)) {
OnWriteError(result.error_code);
return;
}
@@ -1296,7 +1457,6 @@ QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id,
}
bool QuicConnection::SendControlFrame(const QuicFrame& frame) {
- DCHECK(use_control_frame_manager_);
if (!CanWrite(HAS_RETRANSMITTABLE_DATA) && frame.type != PING_FRAME) {
QUIC_DVLOG(1) << ENDPOINT << "Failed to send control frame: " << frame;
// Do not check congestion window for ping.
@@ -1317,18 +1477,6 @@ bool QuicConnection::SendControlFrame(const QuicFrame& frame) {
return true;
}
-void QuicConnection::SendRstStream(QuicStreamId id,
- QuicRstStreamErrorCode error,
- QuicStreamOffset bytes_written) {
- DCHECK(!use_control_frame_manager_);
- // Opportunistically bundle an ack with this outgoing packet.
- ScopedPacketFlusher flusher(this, SEND_ACK_IF_PENDING);
- packet_generator_.AddControlFrame(QuicFrame(new QuicRstStreamFrame(
- ++last_control_frame_id_, id, error, bytes_written)));
-
- OnStreamReset(id, error);
-}
-
void QuicConnection::OnStreamReset(QuicStreamId id,
QuicRstStreamErrorCode error) {
if (error == QUIC_STREAM_NO_ERROR) {
@@ -1366,24 +1514,6 @@ void QuicConnection::OnStreamReset(QuicStreamId id,
// cancelled as well.
}
-void QuicConnection::SendWindowUpdate(QuicStreamId id,
- QuicStreamOffset byte_offset) {
- DCHECK(!use_control_frame_manager_);
- // Opportunistically bundle an ack with this outgoing packet.
- ScopedPacketFlusher flusher(this, SEND_ACK_IF_PENDING);
- packet_generator_.AddControlFrame(QuicFrame(
- new QuicWindowUpdateFrame(++last_control_frame_id_, id, byte_offset)));
-}
-
-void QuicConnection::SendBlocked(QuicStreamId id) {
- DCHECK(!use_control_frame_manager_);
- // Opportunistically bundle an ack with this outgoing packet.
- ScopedPacketFlusher flusher(this, SEND_ACK_IF_PENDING);
- packet_generator_.AddControlFrame(
- QuicFrame(new QuicBlockedFrame(++last_control_frame_id_, id)));
- stats_.blocked_frames_sent++;
-}
-
const QuicConnectionStats& QuicConnection::GetStats() {
const RttStats* rtt_stats = sent_packet_manager_.GetRttStats();
@@ -1421,14 +1551,34 @@ void QuicConnection::ProcessUdpPacket(const QuicSocketAddress& self_address,
if (!self_address_.IsInitialized()) {
self_address_ = last_packet_destination_address_;
}
- if (!peer_address_.IsInitialized()) {
- peer_address_ = last_packet_source_address_;
+
+ if (!enable_server_proxy_) {
+ if (!peer_address_.IsInitialized()) {
+ peer_address_ = last_packet_source_address_;
+ }
+ } else {
+ if (!direct_peer_address_.IsInitialized()) {
+ direct_peer_address_ = last_packet_source_address_;
+ }
+
+ if (!effective_peer_address_.IsInitialized()) {
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_enable_server_proxy, 1, 3);
+ const QuicSocketAddress effective_peer_addr =
+ GetEffectivePeerAddressFromCurrentPacket();
+
+ // effective_peer_address_ must be initialized at the beginning of the
+ // first packet processed(here). If effective_peer_addr is uninitialized,
+ // just set effective_peer_address_ to the direct peer address.
+ effective_peer_address_ = effective_peer_addr.IsInitialized()
+ ? effective_peer_addr
+ : direct_peer_address_;
+ }
}
stats_.bytes_received += packet.length();
++stats_.packets_received;
- // Ensure the time coming from the packet reader is within a minute of now.
+ // Ensure the time coming from the packet reader is within 2 minutes of now.
if (std::abs((packet.receipt_time() - clock_->ApproximateNow()).ToSeconds()) >
2 * 60) {
QUIC_BUG << "Packet receipt time:"
@@ -1460,11 +1610,26 @@ void QuicConnection::ProcessUdpPacket(const QuicSocketAddress& self_address,
}
++stats_.packets_processed;
- if (active_peer_migration_type_ != NO_CHANGE &&
- sent_packet_manager_.GetLargestObserved() >
- highest_packet_sent_before_peer_migration_) {
- if (perspective_ == Perspective::IS_SERVER) {
- OnPeerMigrationValidated();
+ if (!enable_server_proxy_) {
+ if (active_peer_migration_type_ != NO_CHANGE &&
+ sent_packet_manager_.GetLargestObserved() >
+ highest_packet_sent_before_peer_migration_) {
+ if (perspective_ == Perspective::IS_SERVER) {
+ OnPeerMigrationValidated();
+ }
+ }
+ } else {
+ QUIC_DLOG_IF(INFO, active_effective_peer_migration_type_ != NO_CHANGE)
+ << "sent_packet_manager_.GetLargestObserved() = "
+ << sent_packet_manager_.GetLargestObserved()
+ << ", highest_packet_sent_before_effective_peer_migration_ = "
+ << highest_packet_sent_before_effective_peer_migration_;
+ if (active_effective_peer_migration_type_ != NO_CHANGE &&
+ sent_packet_manager_.GetLargestObserved() >
+ highest_packet_sent_before_effective_peer_migration_) {
+ if (perspective_ == Perspective::IS_SERVER) {
+ OnEffectivePeerMigrationValidated();
+ }
}
}
MaybeProcessUndecryptablePackets();
@@ -1480,6 +1645,14 @@ void QuicConnection::OnBlockedWriterCanWrite() {
void QuicConnection::OnCanWrite() {
DCHECK(!writer_->IsWriteBlocked());
+ // TODO(wub): Deprecate this histogram once crbug.com/818040 is fixed.
+ if (!queued_packets_.empty() &&
+ queued_packets_.front().packet_number <
+ sent_packet_manager_.GetLargestSentPacket()) {
+ UMA_HISTOGRAM_BOOLEAN(
+ "Net.QuicSession.WriteOutOfOrderQueuedPacketAfterClose", !connected_);
+ }
+
WriteQueuedPackets();
if (!session_decides_what_to_write()) {
WritePendingRetransmissions();
@@ -1519,7 +1692,14 @@ void QuicConnection::WriteIfNotBlocked() {
void QuicConnection::WriteAndBundleAcksIfNotBlocked() {
if (!writer_->IsWriteBlocked()) {
ScopedPacketFlusher flusher(this, SEND_ACK_IF_QUEUED);
- OnCanWrite();
+ if (GetQuicReloadableFlag(quic_is_write_blocked)) {
+ // TODO(ianswett): Merge OnCanWrite and WriteIfNotBlocked when deprecating
+ // this flag.
+ QUIC_FLAG_COUNT(quic_reloadable_flag_quic_is_write_blocked);
+ WriteIfNotBlocked();
+ } else {
+ OnCanWrite();
+ }
}
}
@@ -1592,7 +1772,17 @@ bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
}
if (version_negotiation_state_ != NEGOTIATED_VERSION) {
- if (perspective_ == Perspective::IS_SERVER) {
+ if (perspective_ == Perspective::IS_CLIENT) {
+ DCHECK(!header.version_flag);
+ // If the client gets a packet without the version flag from the server
+ // it should stop sending version since the version negotiation is done.
+ packet_generator_.StopSendingVersion();
+ version_negotiation_state_ = NEGOTIATED_VERSION;
+ visitor_->OnSuccessfulVersionNegotiation(version());
+ if (debug_visitor_ != nullptr) {
+ debug_visitor_->OnSuccessfulVersionNegotiation(version());
+ }
+ } else if (!negotiate_version_early_) {
if (!header.version_flag) {
// Packets should have the version flag till version negotiation is
// done.
@@ -1608,24 +1798,12 @@ bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
version_negotiation_state_ = NEGOTIATED_VERSION;
visitor_->OnSuccessfulVersionNegotiation(version());
if (debug_visitor_ != nullptr) {
- debug_visitor_->OnSuccessfulVersionNegotiation(transport_version());
+ debug_visitor_->OnSuccessfulVersionNegotiation(version());
}
}
- } else {
- DCHECK(!header.version_flag);
- // If the client gets a packet without the version flag from the server
- // it should stop sending version since the version negotiation is done.
- packet_generator_.StopSendingVersion();
- version_negotiation_state_ = NEGOTIATED_VERSION;
- visitor_->OnSuccessfulVersionNegotiation(version());
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnSuccessfulVersionNegotiation(transport_version());
- }
}
}
- DCHECK_EQ(NEGOTIATED_VERSION, version_negotiation_state_);
-
if (last_size_ > largest_received_packet_size_) {
largest_received_packet_size_ = last_size_;
}
@@ -1647,12 +1825,42 @@ void QuicConnection::WriteQueuedPackets() {
UMA_HISTOGRAM_COUNTS_1000("Net.QuicSession.NumQueuedPacketsBeforeWrite",
queued_packets_.size());
- QueuedPacketList::iterator packet_iterator = queued_packets_.begin();
- while (packet_iterator != queued_packets_.end() &&
- WritePacket(&(*packet_iterator))) {
- delete[] packet_iterator->encrypted_buffer;
- ClearSerializedPacket(&(*packet_iterator));
- packet_iterator = queued_packets_.erase(packet_iterator);
+ if (GetQuicReloadableFlag(quic_fix_write_out_of_order_queued_packet_crash)) {
+ while (!queued_packets_.empty()) {
+ QUIC_FLAG_COUNT(
+ quic_reloadable_flag_quic_fix_write_out_of_order_queued_packet_crash);
+ // WritePacket() can potentially clear all queued packets, so we need to
+ // save the first queued packet to a local variable before calling it.
+ SerializedPacket packet(std::move(queued_packets_.front()));
+ queued_packets_.pop_front();
+
+ const bool write_result = WritePacket(&packet);
+
+ if (connected_ && !write_result) {
+ // Write failed but connection is open, re-insert |packet| into the
+ // front of the queue, it will be retried later.
+ queued_packets_.emplace_front(std::move(packet));
+ break;
+ }
+
+ delete[] packet.encrypted_buffer;
+ ClearSerializedPacket(&packet);
+ if (!connected_) {
+ DCHECK(queued_packets_.empty()) << "Queued packets should have been "
+ "cleared while closing connection";
+ break;
+ }
+
+ // Continue to send the next packet in queue.
+ }
+ } else {
+ QueuedPacketList::iterator packet_iterator = queued_packets_.begin();
+ while (packet_iterator != queued_packets_.end() &&
+ WritePacket(&(*packet_iterator))) {
+ delete[] packet_iterator->encrypted_buffer;
+ ClearSerializedPacket(&(*packet_iterator));
+ packet_iterator = queued_packets_.erase(packet_iterator);
+ }
}
}
@@ -1771,19 +1979,23 @@ bool QuicConnection::CanWrite(HasRetransmittableData retransmittable) {
}
bool QuicConnection::WritePacket(SerializedPacket* packet) {
+ if (always_discard_packets_after_close_ && ShouldDiscardPacket(*packet)) {
+ QUIC_FLAG_COUNT_N(
+ quic_reloadable_flag_quic_always_discard_packets_after_close, 1, 2);
+ ++stats_.packets_discarded;
+ return true;
+ }
if (packet->packet_number < sent_packet_manager_.GetLargestSentPacket()) {
QUIC_BUG << "Attempt to write packet:" << packet->packet_number
<< " after:" << sent_packet_manager_.GetLargestSentPacket();
- CloseConnection(QUIC_INTERNAL_ERROR, "Packet written out of order.",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-
UMA_HISTOGRAM_COUNTS_1000("Net.QuicSession.NumQueuedPacketsAtOutOfOrder",
queued_packets_.size());
-
- RecordInternalErrorLocation(QUIC_CONNECTION_4);
+ CloseConnection(QUIC_INTERNAL_ERROR, "Packet written out of order.",
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ RecordInternalErrorLocation(QUIC_CONNECTION_WRITE_PACKET);
return true;
}
- if (ShouldDiscardPacket(*packet)) {
+ if (!always_discard_packets_after_close_ && ShouldDiscardPacket(*packet)) {
++stats_.packets_discarded;
return true;
}
@@ -1805,8 +2017,8 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) {
}
// Copy the buffer so it's owned in the future.
char* buffer_copy = CopyBuffer(*packet);
- termination_packets_->push_back(std::unique_ptr<QuicEncryptedPacket>(
- new QuicEncryptedPacket(buffer_copy, encrypted_length, true)));
+ termination_packets_->emplace_back(
+ new QuicEncryptedPacket(buffer_copy, encrypted_length, true));
// This assures we won't try to write *forced* packets when blocked.
// Return true to stop processing.
if (writer_->IsWriteBlocked()) {
@@ -1855,9 +2067,7 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) {
// In some cases, an MTU probe can cause EMSGSIZE. This indicates that the
// MTU discovery is permanently unsuccessful.
- if (result.status == WRITE_STATUS_ERROR &&
- result.error_code == kMessageTooBigErrorCode &&
- packet->retransmittable_frames.empty() &&
+ if (IsMsgTooBig(result) && packet->retransmittable_frames.empty() &&
packet->encrypted_length > long_term_mtu_) {
mtu_discovery_target_ = 0;
mtu_discovery_alarm_->Cancel();
@@ -1865,7 +2075,7 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) {
return true;
}
- if (result.status == WRITE_STATUS_ERROR) {
+ if (IsWriteError(result.status)) {
OnWriteError(result.error_code);
QUIC_LOG_FIRST_N(ERROR, 10)
<< ENDPOINT << "failed writing " << encrypted_length
@@ -1875,18 +2085,30 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) {
return false;
}
- if (result.status != WRITE_STATUS_ERROR && debug_visitor_ != nullptr) {
+ if (debug_visitor_ != nullptr) {
// Pass the write result to the visitor.
debug_visitor_->OnPacketSent(*packet, packet->original_packet_number,
packet->transmission_type, packet_send_time);
}
- // Only adjust the last sent time (for the purpose of tracking the idle
- // timeout) if this is the first retransmittable packet sent after a
- // packet is received. If it were updated on every sent packet, then
- // sending into a black hole might never timeout.
- if (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA &&
- last_send_for_timeout_ <= time_of_last_received_packet_) {
- last_send_for_timeout_ = packet_send_time;
+ if (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA) {
+ // A retransmittable packet has been put on the wire, so no need for the
+ // |retransmittable_on_wire_alarm_| to possibly send a PING.
+ retransmittable_on_wire_alarm_->Cancel();
+ if (use_path_degrading_alarm_) {
+ if (!path_degrading_alarm_->IsSet()) {
+ // This is the first retransmittable packet on the wire after having
+ // none on the wire. Start the path degrading alarm.
+ SetPathDegradingAlarm();
+ }
+ }
+
+ // Only adjust the last sent time (for the purpose of tracking the idle
+ // timeout) if this is the first retransmittable packet sent after a
+ // packet is received. If it were updated on every sent packet, then
+ // sending into a black hole might never timeout.
+ if (last_send_for_timeout_ <= time_of_last_received_packet_) {
+ last_send_for_timeout_ = packet_send_time;
+ }
}
SetPingAlarm();
MaybeSetMtuAlarm(packet_number);
@@ -1917,6 +2139,12 @@ bool QuicConnection::WritePacket(SerializedPacket* packet) {
return true;
}
+bool QuicConnection::IsMsgTooBig(const WriteResult& result) {
+ return (result.status == WRITE_STATUS_MSG_TOO_BIG) ||
+ (IsWriteError(result.status) &&
+ result.error_code == kMessageTooBigErrorCode);
+}
+
bool QuicConnection::ShouldDiscardPacket(const SerializedPacket& packet) {
if (!connected_) {
QUIC_DLOG(INFO) << ENDPOINT
@@ -2010,7 +2238,10 @@ void QuicConnection::OnCongestionChange() {
}
}
+// TODO(b/77267845): remove this method once
+// FLAGS_quic_reloadable_flag_quic_path_degrading_alarm is deprecated.
void QuicConnection::OnPathDegrading() {
+ DCHECK(!use_path_degrading_alarm_);
visitor_->OnPathDegrading();
}
@@ -2050,23 +2281,7 @@ void QuicConnection::SendOrQueuePacket(SerializedPacket* packet) {
void QuicConnection::OnPingTimeout() {
if (!retransmission_alarm_->IsSet()) {
- if (use_control_frame_manager_) {
- visitor_->SendPing();
- } else {
- SendPing();
- }
- }
-}
-
-void QuicConnection::SendPing() {
- DCHECK(!use_control_frame_manager_);
- ScopedPacketFlusher flusher(this, SEND_ACK_IF_QUEUED);
- packet_generator_.AddControlFrame(
- QuicFrame(QuicPingFrame(++last_control_frame_id_)));
- // Send PING frame immediately, without checking for congestion window bounds.
- packet_generator_.FlushAllQueuedFrames();
- if (debug_visitor_ != nullptr) {
- debug_visitor_->OnPingSent();
+ visitor_->SendPing();
}
}
@@ -2090,13 +2305,11 @@ void QuicConnection::SendAck() {
}
visitor_->OnAckNeedsRetransmittableFrame();
- if (!use_control_frame_manager_) {
- if (!packet_generator_.HasRetransmittableFrames()) {
- // Visitor did not add a retransmittable frame, add a ping frame.
- packet_generator_.AddControlFrame(
- QuicFrame(QuicPingFrame(++last_control_frame_id_)));
- }
- }
+}
+
+void QuicConnection::OnPathDegradingTimeout() {
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_path_degrading_alarm, 2, 4);
+ visitor_->OnPathDegrading();
}
void QuicConnection::OnRetransmissionTimeout() {
@@ -2144,8 +2357,8 @@ void QuicConnection::OnRetransmissionTimeout() {
}
void QuicConnection::SetEncrypter(EncryptionLevel level,
- QuicEncrypter* encrypter) {
- packet_generator_.SetEncrypter(level, encrypter);
+ std::unique_ptr<QuicEncrypter> encrypter) {
+ packet_generator_.SetEncrypter(level, std::move(encrypter));
}
void QuicConnection::SetDiversificationNonce(
@@ -2165,14 +2378,15 @@ void QuicConnection::SetDefaultEncryptionLevel(EncryptionLevel level) {
}
void QuicConnection::SetDecrypter(EncryptionLevel level,
- QuicDecrypter* decrypter) {
- framer_.SetDecrypter(level, decrypter);
+ std::unique_ptr<QuicDecrypter> decrypter) {
+ framer_.SetDecrypter(level, std::move(decrypter));
}
-void QuicConnection::SetAlternativeDecrypter(EncryptionLevel level,
- QuicDecrypter* decrypter,
- bool latch_once_used) {
- framer_.SetAlternativeDecrypter(level, decrypter, latch_once_used);
+void QuicConnection::SetAlternativeDecrypter(
+ EncryptionLevel level,
+ std::unique_ptr<QuicDecrypter> decrypter,
+ bool latch_once_used) {
+ framer_.SetAlternativeDecrypter(level, std::move(decrypter), latch_once_used);
}
const QuicDecrypter* QuicConnection::decrypter() const {
@@ -2297,19 +2511,11 @@ void QuicConnection::CancelAllAlarms() {
send_alarm_->Cancel();
timeout_alarm_->Cancel();
mtu_discovery_alarm_->Cancel();
-}
-
-void QuicConnection::SendGoAway(QuicErrorCode error,
- QuicStreamId last_good_stream_id,
- const QuicString& reason) {
- DCHECK(!use_control_frame_manager_);
- QUIC_DLOG(INFO) << ENDPOINT << "Going away with error "
- << QuicErrorCodeToString(error) << " (" << error << ")";
-
- // Opportunistically bundle an ack with this outgoing packet.
- ScopedPacketFlusher flusher(this, SEND_ACK_IF_PENDING);
- packet_generator_.AddControlFrame(QuicFrame(new QuicGoAwayFrame(
- ++last_control_frame_id_, error, last_good_stream_id, reason)));
+ retransmittable_on_wire_alarm_->Cancel();
+ if (use_path_degrading_alarm_) {
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_path_degrading_alarm, 4, 4);
+ path_degrading_alarm_->Cancel();
+ }
}
QuicByteCount QuicConnection::max_packet_length() const {
@@ -2449,6 +2655,14 @@ void QuicConnection::SetRetransmissionAlarm() {
QuicTime::Delta::FromMilliseconds(1));
}
+void QuicConnection::SetPathDegradingAlarm() {
+ DCHECK(use_path_degrading_alarm_);
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_path_degrading_alarm, 1, 4);
+ const QuicTime::Delta delay = sent_packet_manager_.GetPathDegradingDelay();
+ path_degrading_alarm_->Update(clock_->ApproximateNow() + delay,
+ QuicTime::Delta::FromMilliseconds(1));
+}
+
void QuicConnection::MaybeSetMtuAlarm(QuicPacketNumber sent_packet_number) {
// Do not set the alarm if the target size is less than the current size.
// This covers the case when |mtu_discovery_target_| is at its default value,
@@ -2637,9 +2851,13 @@ bool QuicConnection::SendConnectivityProbingPacket(
QuicPacketWriter* probing_writer,
const QuicSocketAddress& peer_address) {
DCHECK(peer_address.IsInitialized());
- // TODO(zhongyi): remove this histogram once the cause of the INTERNAL_ERROR
- // increase is determined.
- UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.SentConnectivityProbe", true);
+ if (always_discard_packets_after_close_ && !connected_) {
+ QUIC_FLAG_COUNT_N(
+ quic_reloadable_flag_quic_always_discard_packets_after_close, 2, 2);
+ QUIC_BUG << "Not sending connectivity probing packet as connection is "
+ << "disconnected.";
+ return false;
+ }
if (perspective_ == Perspective::IS_SERVER && probing_writer == nullptr) {
// Server can use default packet writer to write probing packet.
probing_writer = writer_;
@@ -2647,10 +2865,31 @@ bool QuicConnection::SendConnectivityProbingPacket(
DCHECK(probing_writer);
if (probing_writer->IsWriteBlocked()) {
- QUIC_DLOG(INFO) << "Writer blocked when send connectivity probing packet";
+ QUIC_DLOG(INFO) << ENDPOINT
+ << "Writer blocked when send connectivity probing packet.";
+ if (!handle_write_results_for_connectivity_probe_) {
+ visitor_->OnWriteBlocked();
+ } else {
+ QUIC_FLAG_COUNT_N(
+ quic_reloadable_flag_quic_handle_write_results_for_connectivity_probe,
+ 1, 3);
+ if (probing_writer == writer_) {
+ // Visitor should not be write blocked if the probing writer is not the
+ // default packet writer.
+ visitor_->OnWriteBlocked();
+ }
+ }
return true;
}
+ if (GetQuicReloadableFlag(quic_fix_write_out_of_order_queued_packet_crash) &&
+ GetQuicReloadableFlag(
+ quic_clear_queued_packets_before_sending_connectivity_probing)) {
+ QUIC_FLAG_COUNT(
+ quic_reloadable_flag_quic_clear_queued_packets_before_sending_connectivity_probing); // NOLINT
+ ClearQueuedPackets();
+ }
+
QUIC_DLOG(INFO) << ENDPOINT << "Sending connectivity probing packet for "
<< "connection_id = " << connection_id_;
@@ -2663,23 +2902,42 @@ bool QuicConnection::SendConnectivityProbingPacket(
probing_packet->encrypted_buffer, probing_packet->encrypted_length,
self_address().host(), peer_address, per_packet_options_);
- if (result.status == WRITE_STATUS_ERROR) {
- QUIC_DLOG(INFO) << "Write probing packet not finished with error = "
+ if (IsWriteError(result.status)) {
+ if (!handle_write_results_for_connectivity_probe_) {
+ OnWriteError(result.error_code);
+ } else {
+ QUIC_FLAG_COUNT_N(
+ quic_reloadable_flag_quic_handle_write_results_for_connectivity_probe,
+ 2, 3);
+ // Write error for any connectivity probe should not affect the connection
+ // as it is sent on a different path.
+ }
+ QUIC_DLOG(INFO) << ENDPOINT << "Write probing packet failed with error = "
<< result.error_code;
return false;
}
- // Call OnPacketSent regardless of the write result. This treats a blocked
- // write the same as a packet loss.
+ // Call OnPacketSent regardless of the write result.
sent_packet_manager_.OnPacketSent(
probing_packet.get(), probing_packet->original_packet_number,
packet_send_time, probing_packet->transmission_type,
NO_RETRANSMITTABLE_DATA);
if (result.status == WRITE_STATUS_BLOCKED) {
- visitor_->OnWriteBlocked();
+ if (!handle_write_results_for_connectivity_probe_) {
+ visitor_->OnWriteBlocked();
+ } else {
+ QUIC_FLAG_COUNT_N(
+ quic_reloadable_flag_quic_handle_write_results_for_connectivity_probe,
+ 3, 3);
+ if (probing_writer == writer_) {
+ // Visitor should not be write blocked if the probing writer is not the
+ // default packet writer.
+ visitor_->OnWriteBlocked();
+ }
+ }
if (probing_writer->IsWriteBlockedDataBuffered()) {
- QUIC_BUG << "Write probing packet blocked";
+ QUIC_DLOG(INFO) << ENDPOINT << "Write probing packet blocked";
}
}
@@ -2710,6 +2968,7 @@ void QuicConnection::DiscoverMtu() {
}
void QuicConnection::OnPeerMigrationValidated() {
+ DCHECK(!enable_server_proxy_);
if (active_peer_migration_type_ == NO_CHANGE) {
QUIC_BUG << "No migration underway.";
return;
@@ -2723,6 +2982,7 @@ void QuicConnection::OnPeerMigrationValidated() {
// migration. This should happen even if a migration is underway, since the
// most recent migration is the one that we should pay attention to.
void QuicConnection::StartPeerMigration(AddressChangeType peer_migration_type) {
+ DCHECK(!enable_server_proxy_);
// TODO(fayang): Currently, all peer address change type are allowed. Need to
// add a method ShouldAllowPeerAddressChange(PeerAddressChangeType type) to
// determine whether |type| is allowed.
@@ -2746,12 +3006,55 @@ void QuicConnection::StartPeerMigration(AddressChangeType peer_migration_type) {
OnConnectionMigration(peer_migration_type);
}
+void QuicConnection::OnEffectivePeerMigrationValidated() {
+ DCHECK(enable_server_proxy_);
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_enable_server_proxy, 3, 3);
+ if (active_effective_peer_migration_type_ == NO_CHANGE) {
+ QUIC_BUG << "No migration underway.";
+ return;
+ }
+ highest_packet_sent_before_effective_peer_migration_ = 0;
+ active_effective_peer_migration_type_ = NO_CHANGE;
+}
+
+// TODO(wub): Modify method to start migration whenever a new IP address is seen
+// from a packet with sequence number > the one that triggered the previous
+// migration. This should happen even if a migration is underway, since the
+// most recent migration is the one that we should pay attention to.
+void QuicConnection::StartEffectivePeerMigration(AddressChangeType type) {
+ DCHECK(enable_server_proxy_);
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_enable_server_proxy, 2, 3);
+ // TODO(fayang): Currently, all peer address change type are allowed. Need to
+ // add a method ShouldAllowPeerAddressChange(PeerAddressChangeType type) to
+ // determine whether |type| is allowed.
+ if (active_effective_peer_migration_type_ != NO_CHANGE || type == NO_CHANGE) {
+ QUIC_BUG << "Migration underway or no new migration started.";
+ return;
+ }
+ QUIC_DLOG(INFO) << ENDPOINT << "Effective peer's ip:port changed from "
+ << effective_peer_address_.ToString() << " to "
+ << GetEffectivePeerAddressFromCurrentPacket().ToString()
+ << ", migrating connection.";
+
+ highest_packet_sent_before_effective_peer_migration_ =
+ sent_packet_manager_.GetLargestSentPacket();
+ effective_peer_address_ = GetEffectivePeerAddressFromCurrentPacket();
+ active_effective_peer_migration_type_ = type;
+
+ // TODO(wub): Move these calls to OnEffectivePeerMigrationValidated.
+ OnConnectionMigration(type);
+}
+
void QuicConnection::OnConnectionMigration(AddressChangeType addr_change_type) {
visitor_->OnConnectionMigration(addr_change_type);
sent_packet_manager_.OnConnectionMigration(addr_change_type);
}
bool QuicConnection::IsCurrentPacketConnectivityProbing() const {
+ if (enable_server_proxy_) {
+ return is_current_packet_connectivity_probing_;
+ }
+
if (current_packet_content_ != SECOND_FRAME_IS_PADDING) {
return false;
}
@@ -2798,7 +3101,8 @@ bool QuicConnection::MaybeConsiderAsMemoryCorruption(
void QuicConnection::MaybeSendProbingRetransmissions() {
DCHECK(fill_up_link_during_probing_);
- if (!sent_packet_manager_.handshake_confirmed()) {
+ if (!sent_packet_manager_.handshake_confirmed() ||
+ sent_packet_manager().HasUnackedCryptoPackets()) {
return;
}
@@ -2863,35 +3167,59 @@ void QuicConnection::UpdatePacketContent(PacketContent type) {
if (type == SECOND_FRAME_IS_PADDING) {
if (current_packet_content_ == FIRST_FRAME_IS_PING) {
current_packet_content_ = SECOND_FRAME_IS_PADDING;
+ if (enable_server_proxy_) {
+ if (perspective_ == Perspective::IS_SERVER) {
+ is_current_packet_connectivity_probing_ =
+ current_effective_peer_migration_type_ != NO_CHANGE;
+ } else {
+ is_current_packet_connectivity_probing_ =
+ (last_packet_source_address_ != peer_address_) ||
+ (last_packet_destination_address_ != self_address_);
+ }
+ }
return;
}
}
current_packet_content_ = NOT_PADDED_PING;
- if (current_peer_migration_type_ == NO_CHANGE) {
- return;
- }
+ if (!enable_server_proxy_) {
+ if (current_peer_migration_type_ == NO_CHANGE) {
+ return;
+ }
+
+ // Start peer migration immediately when the current packet is confirmed not
+ // a connectivity probing packet.
+ StartPeerMigration(current_peer_migration_type_);
+ current_peer_migration_type_ = NO_CHANGE;
+ } else {
+ if (last_header_.packet_number ==
+ received_packet_manager_.GetLargestObserved()) {
+ direct_peer_address_ = last_packet_source_address_;
+ }
+ if (current_effective_peer_migration_type_ == NO_CHANGE) {
+ return;
+ }
- // Start peer migration immediately when the current packet is confirmed not
- // a connectivity probing packet.
- StartPeerMigration(current_peer_migration_type_);
- current_peer_migration_type_ = NO_CHANGE;
+ // Start effective peer migration immediately when the current packet is
+ // confirmed not a connectivity probing packet.
+ StartEffectivePeerMigration(current_effective_peer_migration_type_);
+ current_effective_peer_migration_type_ = NO_CHANGE;
+ }
}
void QuicConnection::MaybeEnableSessionDecidesWhatToWrite() {
// Only enable session decides what to write code path for version 42+,
// because it needs the receiver to allow receiving overlapping stream data.
const bool enable_session_decides_what_to_write =
- transport_version() > QUIC_VERSION_41 &&
- GetQuicReloadableFlag(quic_streams_unblocked_by_session2) &&
- use_control_frame_manager_;
+ transport_version() > QUIC_VERSION_41;
sent_packet_manager_.SetSessionDecideWhatToWrite(
enable_session_decides_what_to_write);
packet_generator_.SetCanSetTransmissionType(
enable_session_decides_what_to_write);
}
-void QuicConnection::PostProcessAfterAckFrame(bool send_stop_waiting) {
+void QuicConnection::PostProcessAfterAckFrame(bool send_stop_waiting,
+ bool acked_new_packet) {
if (no_stop_waiting_frames_) {
received_packet_manager_.DontWaitForPacketsBefore(
sent_packet_manager_.largest_packet_peer_knows_is_acked());
@@ -2900,6 +3228,26 @@ void QuicConnection::PostProcessAfterAckFrame(bool send_stop_waiting) {
// have a better estimate of the current rtt than when it was set.
SetRetransmissionAlarm();
+ if (!sent_packet_manager_.HasUnackedPackets()) {
+ // There are no retransmittable packets on the wire, so it may be
+ // necessary to send a PING to keep a retransmittable packet on the wire.
+ if (!retransmittable_on_wire_alarm_->IsSet()) {
+ SetRetransmittableOnWireAlarm();
+ }
+ // There are no retransmittable packets on the wire, so it's impossible to
+ // say if the connection has degraded.
+ if (use_path_degrading_alarm_) {
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_path_degrading_alarm, 3, 4);
+ path_degrading_alarm_->Cancel();
+ }
+ } else if (acked_new_packet) {
+ // A previously-unacked packet has been acked, which means forward progress
+ // has been made. Push back the path degrading alarm.
+ if (use_path_degrading_alarm_) {
+ SetPathDegradingAlarm();
+ }
+ }
+
if (send_stop_waiting) {
++stop_waiting_count_;
} else {
@@ -2925,4 +3273,22 @@ bool QuicConnection::session_decides_what_to_write() const {
return sent_packet_manager_.session_decides_what_to_write();
}
+void QuicConnection::SetRetransmittableOnWireAlarm() {
+ if (perspective_ == Perspective::IS_SERVER) {
+ // Only clients send pings.
+ return;
+ }
+ if (retransmittable_on_wire_timeout_.IsInfinite()) {
+ return;
+ }
+ if (!visitor_->HasOpenDynamicStreams()) {
+ retransmittable_on_wire_alarm_->Cancel();
+ // Don't send a ping unless there are open streams.
+ return;
+ }
+ retransmittable_on_wire_alarm_->Update(
+ clock_->ApproximateNow() + retransmittable_on_wire_timeout_,
+ QuicTime::Delta::Zero());
+}
+
} // namespace net
diff --git a/chromium/net/quic/core/quic_connection.h b/chromium/net/quic/core/quic_connection.h
index c07480af19c..e62454ee720 100644
--- a/chromium/net/quic/core/quic_connection.h
+++ b/chromium/net/quic/core/quic_connection.h
@@ -25,6 +25,7 @@
#include "base/macros.h"
#include "net/quic/core/crypto/quic_decrypter.h"
+#include "net/quic/core/crypto/quic_encrypter.h"
#include "net/quic/core/proto/cached_network_parameters.pb.h"
#include "net/quic/core/quic_alarm.h"
#include "net/quic/core/quic_alarm_factory.h"
@@ -51,8 +52,6 @@ namespace net {
class QuicClock;
class QuicConfig;
class QuicConnection;
-class QuicDecrypter;
-class QuicEncrypter;
class QuicRandom;
namespace test {
@@ -172,6 +171,10 @@ class QUIC_EXPORT_PRIVATE QuicConnectionVisitorInterface {
// Called when a self address change is observed. Returns true if self address
// change is allowed.
virtual bool AllowSelfAddressChange() const = 0;
+
+ // Called when an ACK is received with a larger |largest_acked| than
+ // previously observed.
+ virtual void OnForwardProgressConfirmed() = 0;
};
// Interface which gets callbacks from the QuicConnection at interesting
@@ -262,7 +265,7 @@ class QUIC_EXPORT_PRIVATE QuicConnectionDebugVisitor
// Called when the version negotiation is successful.
virtual void OnSuccessfulVersionNegotiation(
- const QuicTransportVersion& version) {}
+ const ParsedQuicVersion& version) {}
// Called when a CachedNetworkParameters is sent to the client.
virtual void OnSendConnectionState(
@@ -356,7 +359,7 @@ class QUIC_EXPORT_PRIVATE QuicConnection
void AdjustNetworkParameters(QuicBandwidth bandwidth, QuicTime::Delta rtt);
// Returns the max pacing rate for the connection.
- QuicBandwidth MaxPacingRate() const;
+ virtual QuicBandwidth MaxPacingRate() const;
// Sets the number of active streams on the connection for congestion control.
void SetNumOpenStreams(size_t num_streams);
@@ -375,20 +378,9 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// otherwise.
virtual bool SendControlFrame(const QuicFrame& frame);
- // Send a RST_STREAM frame to the peer.
- virtual void SendRstStream(QuicStreamId id,
- QuicRstStreamErrorCode error,
- QuicStreamOffset bytes_written);
-
// Called when stream |id| is reset because of |error|.
virtual void OnStreamReset(QuicStreamId id, QuicRstStreamErrorCode error);
- // Send a BLOCKED frame to the peer.
- virtual void SendBlocked(QuicStreamId id);
-
- // Send a WINDOW_UPDATE frame to the peer.
- virtual void SendWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset);
-
// Closes the connection.
// |connection_close_behavior| determines whether or not a connection close
// packet is sent to the peer.
@@ -397,11 +389,6 @@ class QUIC_EXPORT_PRIVATE QuicConnection
const QuicString& details,
ConnectionCloseBehavior connection_close_behavior);
- // Sends a GOAWAY frame.
- virtual void SendGoAway(QuicErrorCode error,
- QuicStreamId last_good_stream_id,
- const QuicString& reason);
-
// Returns statistics tracked for this connection.
const QuicConnectionStats& GetStats();
@@ -425,6 +412,9 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// network.
void OnWriteError(int error_code);
+ // Whether |result| represents a MSG TOO BIG write error.
+ bool IsMsgTooBig(const WriteResult& result);
+
// If the socket is not blocked, writes queued packets.
void WriteIfNotBlocked();
@@ -484,6 +474,9 @@ class QUIC_EXPORT_PRIVATE QuicConnection
bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
void OnPacketComplete() override;
+ bool IsValidStatelessResetToken(uint128 token) const override;
+ void OnAuthenticatedIetfStatelessResetPacket(
+ const QuicIetfStatelessResetPacket& packet) override;
// QuicConnectionCloseDelegateInterface
void OnUnrecoverableError(QuicErrorCode error,
@@ -501,6 +494,8 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// QuicSentPacketManager::NetworkChangeVisitor
void OnCongestionChange() override;
+ // TODO(b/76462614): remove OnPathDegrading() once
+ // FLAGS_quic_reloadable_flag_quic_path_degrading_alarm is deprecated.
void OnPathDegrading() override;
void OnPathMtuIncreased(QuicPacketLength packet_size) override;
@@ -525,11 +520,34 @@ class QUIC_EXPORT_PRIVATE QuicConnection
}
const QuicTime::Delta ping_timeout() { return ping_timeout_; }
// Used in Chromium, but not internally.
+ // Must only be called before retransmittable_on_wire_alarm_ is set.
+ void set_retransmittable_on_wire_timeout(
+ QuicTime::Delta retransmittable_on_wire_timeout) {
+ DCHECK(!retransmittable_on_wire_alarm_->IsSet());
+ retransmittable_on_wire_timeout_ = retransmittable_on_wire_timeout;
+ }
+ const QuicTime::Delta retransmittable_on_wire_timeout() {
+ return retransmittable_on_wire_timeout_;
+ }
+ // Used in Chromium, but not internally.
void set_creator_debug_delegate(QuicPacketCreator::DebugDelegate* visitor) {
packet_generator_.set_debug_delegate(visitor);
}
const QuicSocketAddress& self_address() const { return self_address_; }
- const QuicSocketAddress& peer_address() const { return peer_address_; }
+ const QuicSocketAddress& peer_address() const {
+ if (enable_server_proxy_) {
+ return direct_peer_address_;
+ }
+ return peer_address_;
+ }
+ const QuicSocketAddress& effective_peer_address() const {
+ if (enable_server_proxy_) {
+ return effective_peer_address_;
+ }
+ QUIC_BUG << "effective_peer_address() should only be called when "
+ "enable_server_proxy_ is true.";
+ return peer_address_;
+ }
QuicConnectionId connection_id() const { return connection_id_; }
const QuicClock* clock() const { return clock_; }
QuicRandom* random_generator() const { return random_generator_; }
@@ -573,12 +591,12 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// if the retransmission alarm is not running.
void OnPingTimeout();
- // Sends a ping frame.
- void SendPing();
-
// Sets up a packet with an QuicAckFrame and sends it out.
void SendAck();
+ // Called when the path degrading alarm fires.
+ void OnPathDegradingTimeout();
+
// Called when an RTO fires. Resets the retransmission alarm if there are
// remaining unacked packets.
void OnRetransmissionTimeout();
@@ -594,9 +612,9 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// connection becomes forward secure and hasn't received acks for all packets.
void NeuterUnencryptedPackets();
- // Changes the encrypter used for level |level| to |encrypter|. The function
- // takes ownership of |encrypter|.
- void SetEncrypter(EncryptionLevel level, QuicEncrypter* encrypter);
+ // Changes the encrypter used for level |level| to |encrypter|.
+ void SetEncrypter(EncryptionLevel level,
+ std::unique_ptr<QuicEncrypter> encrypter);
// SetNonceForPublicHeader sets the nonce that will be transmitted in the
// header of each packet encrypted at the initial encryption level decrypted.
@@ -607,21 +625,22 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// to new packets.
void SetDefaultEncryptionLevel(EncryptionLevel level);
- // SetDecrypter sets the primary decrypter, replacing any that already exists,
- // and takes ownership. If an alternative decrypter is in place then the
- // function DCHECKs. This is intended for cases where one knows that future
- // packets will be using the new decrypter and the previous decrypter is now
- // obsolete. |level| indicates the encryption level of the new decrypter.
- void SetDecrypter(EncryptionLevel level, QuicDecrypter* decrypter);
+ // SetDecrypter sets the primary decrypter, replacing any that already exists.
+ // If an alternative decrypter is in place then the function DCHECKs. This is
+ // intended for cases where one knows that future packets will be using the
+ // new decrypter and the previous decrypter is now obsolete. |level| indicates
+ // the encryption level of the new decrypter.
+ void SetDecrypter(EncryptionLevel level,
+ std::unique_ptr<QuicDecrypter> decrypter);
// SetAlternativeDecrypter sets a decrypter that may be used to decrypt
- // future packets and takes ownership of it. |level| indicates the encryption
- // level of the decrypter. If |latch_once_used| is true, then the first time
- // that the decrypter is successful it will replace the primary decrypter.
- // Otherwise both decrypters will remain active and the primary decrypter
- // will be the one last used.
+ // future packets. |level| indicates the encryption level of the decrypter. If
+ // |latch_once_used| is true, then the first time that the decrypter is
+ // successful it will replace the primary decrypter. Otherwise both
+ // decrypters will remain active and the primary decrypter will be the one
+ // last used.
void SetAlternativeDecrypter(EncryptionLevel level,
- QuicDecrypter* decrypter,
+ std::unique_ptr<QuicDecrypter> decrypter,
bool latch_once_used);
const QuicDecrypter* decrypter() const;
@@ -748,10 +767,19 @@ class QUIC_EXPORT_PRIVATE QuicConnection
defer_send_in_response_to_packets_ = defer;
}
- bool use_control_frame_manager() const { return use_control_frame_manager_; }
-
bool session_decides_what_to_write() const;
+ void SetRetransmittableOnWireAlarm();
+
+ // Sets the current per-packet options for the connection. The QuicConnection
+ // does not take ownership of |options|; |options| must live for as long as
+ // the QuicConnection is in use.
+ void set_per_packet_options(PerPacketOptions* options) {
+ per_packet_options_ = options;
+ }
+
+ bool IsServerProxyEnabled() const { return enable_server_proxy_; }
+
protected:
// Calls cancel() on all the alarms owned by this connection.
void CancelAllAlarms();
@@ -767,6 +795,33 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// Called when a peer address migration is validated.
virtual void OnPeerMigrationValidated();
+ // Called after a packet is received from a new effective peer address and is
+ // decrypted. Starts validation of effective peer's address change. Calls
+ // OnConnectionMigration as soon as the address changed.
+ void StartEffectivePeerMigration(AddressChangeType type);
+
+ // Called when a effective peer address migration is validated.
+ virtual void OnEffectivePeerMigrationValidated();
+
+ // Get the effective peer address from the packet being processed. For proxied
+ // connections, effective peer address is the address of the endpoint behind
+ // the proxy. For non-proxied connections, effective peer address is the same
+ // as peer address.
+ //
+ // Notes for implementations in subclasses:
+ // - If the connection is not proxied, the overridden method should use the
+ // base implementation:
+ //
+ // return QuicConnection::GetEffectivePeerAddressFromCurrentPacket();
+ //
+ // - If the connection is proxied, the overridden method may return either of
+ // the following:
+ // a) The address of the endpoint behind the proxy. The address is used to
+ // drive effective peer migration.
+ // b) An uninitialized address, meaning the effective peer address does not
+ // change.
+ virtual QuicSocketAddress GetEffectivePeerAddressFromCurrentPacket() const;
+
// Selects and updates the version of the protocol being used by selecting a
// version from |available_versions| which is also supported. Returns true if
// such a version exists, false otherwise.
@@ -774,17 +829,15 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// Returns the current per-packet options for the connection.
PerPacketOptions* per_packet_options() { return per_packet_options_; }
- // Sets the current per-packet options for the connection. The QuicConnection
- // does not take ownership of |options|; |options| must live for as long as
- // the QuicConnection is in use.
- void set_per_packet_options(PerPacketOptions* options) {
- per_packet_options_ = options;
- }
AddressChangeType active_peer_migration_type() {
return active_peer_migration_type_;
}
+ AddressChangeType active_effective_peer_migration_type() const {
+ return active_effective_peer_migration_type_;
+ }
+
// Sends the connection close packet to the peer. |ack_mode| determines
// whether ack frame will be bundled with the connection close packet.
virtual void SendConnectionClosePacket(QuicErrorCode error,
@@ -803,7 +856,7 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// Notify various components(SendPacketManager, Session etc.) that this
// connection has been migrated.
- void OnConnectionMigration(AddressChangeType addr_change_type);
+ virtual void OnConnectionMigration(AddressChangeType addr_change_type);
// Return whether the packet being processed is a connectivity probing.
// A packet is a connectivity probing if it is a padded ping packet with self
@@ -894,6 +947,9 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// Sets the retransmission alarm based on SentPacketManager.
void SetRetransmissionAlarm();
+ // Sets the path degrading alarm.
+ void SetPathDegradingAlarm();
+
// Sets the MTU discovery alarm if necessary.
// |sent_packet_number| is the recently sent packet number.
void MaybeSetMtuAlarm(QuicPacketNumber sent_packet_number);
@@ -922,8 +978,9 @@ class QUIC_EXPORT_PRIVATE QuicConnection
void CheckIfApplicationLimited();
// Sets |current_packet_content_| to |type| if applicable. And
- // starts peer miration if current packet is confirmed not a connectivity
- // probe and |current_peer_migration_type_| indicates peer address change.
+ // starts effective peer miration if current packet is confirmed not a
+ // connectivity probe and |current_effective_peer_migration_type_| indicates
+ // effective peer address change.
void UpdatePacketContent(PacketContent type);
// Enables session decide what to write based on version and flags.
@@ -931,17 +988,29 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// Called when last received ack frame has been processed.
// |send_stop_waiting| indicates whether a stop waiting needs to be sent.
- void PostProcessAfterAckFrame(bool send_stop_waiting);
+ // |acked_new_packet| is true if a previously-unacked packet was acked.
+ void PostProcessAfterAckFrame(bool send_stop_waiting, bool acked_new_packet);
QuicFramer framer_;
// Contents received in the current packet, especially used to identify
// whether the current packet is a padded PING packet.
PacketContent current_packet_content_;
+ // True if the packet currently being processed is a connectivity probing
+ // packet. Is set to false when a new packet is received, and will be set to
+ // true as soon as |current_packet_content_| is set to
+ // SECOND_FRAME_IS_PADDING.
+ bool is_current_packet_connectivity_probing_;
// Caches the current peer migration type if a peer migration might be
// initiated. As soon as the current packet is confirmed not a connectivity
// probe, peer migration will start.
+ // TODO(wub): Remove once quic_reloadable_flag_quic_enable_server_proxy is
+ // deprecated.
AddressChangeType current_peer_migration_type_;
+ // Caches the current effective peer migration type if a effective peer
+ // migration might be initiated. As soon as the current packet is confirmed
+ // not a connectivity probe, effective peer migration will start.
+ AddressChangeType current_effective_peer_migration_type_;
QuicConnectionHelperInterface* helper_; // Not owned.
QuicAlarmFactory* alarm_factory_; // Not owned.
PerPacketOptions* per_packet_options_; // Not owned.
@@ -955,17 +1024,38 @@ class QUIC_EXPORT_PRIVATE QuicConnection
const QuicConnectionId connection_id_;
// Address on the last successfully processed packet received from the
- // client.
+ // direct peer.
QuicSocketAddress self_address_;
QuicSocketAddress peer_address_;
+ QuicSocketAddress direct_peer_address_;
+ // Address of the endpoint behind the proxy if the connection is proxied.
+ // Otherwise it is the same as |peer_address_|.
+ // NOTE: Currently |effective_peer_address_| and |peer_address_| are always
+ // the same(the address of the direct peer), but soon we'll change
+ // |effective_peer_address_| to be the address of the endpoint behind the
+ // proxy if the connection is proxied.
+ QuicSocketAddress effective_peer_address_;
+
// Records change type when the peer initiates migration to a new peer
// address. Reset to NO_CHANGE after peer migration is validated.
+ // TODO(wub): Remove once quic_reloadable_flag_quic_enable_server_proxy is
+ // deprecated.
AddressChangeType active_peer_migration_type_;
// Records highest sent packet number when peer migration is started.
+ // TODO(wub): Remove once quic_reloadable_flag_quic_enable_server_proxy is
+ // deprecated.
QuicPacketNumber highest_packet_sent_before_peer_migration_;
+ // Records change type when the effective peer initiates migration to a new
+ // address. Reset to NO_CHANGE after effective peer migration is validated.
+ AddressChangeType active_effective_peer_migration_type_;
+
+ // Records highest sent packet number when effective peer migration is
+ // started.
+ QuicPacketNumber highest_packet_sent_before_effective_peer_migration_;
+
// True if the last packet has gotten far enough in the framer to be
// decrypted.
bool last_packet_decrypted_;
@@ -1063,6 +1153,9 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// The timeout for PING.
QuicTime::Delta ping_timeout_;
+ // Timeout for how long the wire can have no retransmittable packets.
+ QuicTime::Delta retransmittable_on_wire_timeout_;
+
// Arena to store class implementations within the QuicConnection.
QuicConnectionArena arena_;
@@ -1084,6 +1177,11 @@ class QUIC_EXPORT_PRIVATE QuicConnection
QuicArenaScopedPtr<QuicAlarm> ping_alarm_;
// An alarm that fires when an MTU probe should be sent.
QuicArenaScopedPtr<QuicAlarm> mtu_discovery_alarm_;
+ // An alarm that fires when there have been no retransmittable packets on the
+ // wire for some period.
+ QuicArenaScopedPtr<QuicAlarm> retransmittable_on_wire_alarm_;
+ // An alarm that fires when this connection is considered degrading.
+ QuicArenaScopedPtr<QuicAlarm> path_degrading_alarm_;
// Neither visitor is owned by this class.
QuicConnectionVisitorInterface* visitor_;
@@ -1194,11 +1292,32 @@ class QUIC_EXPORT_PRIVATE QuicConnection
// retransmission code.
bool probing_retransmission_pending_;
+ // Indicates whether a stateless reset token has been received from peer.
+ bool stateless_reset_token_received_;
+ // Stores received stateless reset token from peer. Used to verify whether a
+ // packet is a stateless reset packet.
+ uint128 received_stateless_reset_token_;
+
// Id of latest sent control frame. 0 if no control frame has been sent.
QuicControlFrameId last_control_frame_id_;
- // Latched value of quic_reloadable_flag_quic_use_control_frame_manager.
- const bool use_control_frame_manager_;
+ // Latched value of
+ // quic_reloadable_flag_quic_server_early_version_negotiation.
+ const bool negotiate_version_early_;
+
+ // Latched value of
+ // quic_reloadable_flag_quic_always_discard_packets_after_close.
+ const bool always_discard_packets_after_close_;
+ // Latched valure of
+ // quic_reloadable_flag_quic_handle_write_results_for_connectivity_probe.
+ const bool handle_write_results_for_connectivity_probe_;
+
+ // Latched value of
+ // quic_reloadable_flag_quic_path_degrading_alarm
+ const bool use_path_degrading_alarm_;
+
+ // Latched value of quic_reloadable_flag_quic_enable_server_proxy.
+ const bool enable_server_proxy_;
DISALLOW_COPY_AND_ASSIGN(QuicConnection);
};
diff --git a/chromium/net/quic/core/quic_connection_test.cc b/chromium/net/quic/core/quic_connection_test.cc
index eb05baccaee..69430cb9d03 100644
--- a/chromium/net/quic/core/quic_connection_test.cc
+++ b/chromium/net/quic/core/quic_connection_test.cc
@@ -48,6 +48,7 @@ using testing::_;
using testing::AnyNumber;
using testing::AtLeast;
using testing::DoAll;
+using testing::Exactly;
using testing::Ge;
using testing::InSequence;
using testing::Invoke;
@@ -317,7 +318,8 @@ class TestPacketWriter : public QuicPacketWriter {
}
if (use_tagging_decrypter_) {
- framer_.framer()->SetDecrypter(ENCRYPTION_NONE, new TaggingDecrypter);
+ framer_.framer()->SetDecrypter(ENCRYPTION_NONE,
+ QuicMakeUnique<TaggingDecrypter>());
}
EXPECT_TRUE(framer_.ProcessPacket(packet));
if (block_on_next_write_) {
@@ -502,7 +504,8 @@ class TestConnection : public QuicConnection {
SupportedVersions(version)),
notifier_(nullptr) {
writer->set_perspective(perspective);
- SetEncrypter(ENCRYPTION_FORWARD_SECURE, new NullEncrypter(perspective));
+ SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<NullEncrypter>(perspective));
SetDataProducer(&producer_);
}
@@ -528,7 +531,7 @@ class TestConnection : public QuicConnection {
ENCRYPTION_NONE, packet_number, *packet, buffer, kMaxPacketSize);
delete packet;
SerializedPacket serialized_packet(
- packet_number, PACKET_6BYTE_PACKET_NUMBER, buffer, encrypted_length,
+ packet_number, PACKET_4BYTE_PACKET_NUMBER, buffer, encrypted_length,
has_ack, has_pending_frames);
if (retransmittable == HAS_RETRANSMITTABLE_DATA) {
serialized_packet.retransmittable_frames.push_back(
@@ -655,6 +658,16 @@ class TestConnection : public QuicConnection {
QuicConnectionPeer::GetMtuDiscoveryAlarm(this));
}
+ TestAlarmFactory::TestAlarm* GetRetransmittableOnWireAlarm() {
+ return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+ QuicConnectionPeer::GetRetransmittableOnWireAlarm(this));
+ }
+
+ TestAlarmFactory::TestAlarm* GetPathDegradingAlarm() {
+ return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
+ QuicConnectionPeer::GetPathDegradingAlarm(this));
+ }
+
void SetMaxTailLossProbes(size_t max_tail_loss_probes) {
QuicSentPacketManagerPeer::SetMaxTailLossProbes(
QuicConnectionPeer::GetSentPacketManager(this), max_tail_loss_probes);
@@ -667,10 +680,23 @@ class TestConnection : public QuicConnection {
void set_notifier(SimpleSessionNotifier* notifier) { notifier_ = notifier; }
+ void ReturnEffectivePeerAddressForNextPacket(const QuicSocketAddress& addr) {
+ next_effective_peer_addr_ = QuicMakeUnique<QuicSocketAddress>(addr);
+ }
+
+ using QuicConnection::IsCurrentPacketConnectivityProbing;
using QuicConnection::SelectMutualVersion;
using QuicConnection::SendProbingRetransmissions;
using QuicConnection::set_defer_send_in_response_to_packets;
+ protected:
+ QuicSocketAddress GetEffectivePeerAddressFromCurrentPacket() const override {
+ if (next_effective_peer_addr_) {
+ return *std::move(next_effective_peer_addr_);
+ }
+ return QuicConnection::GetEffectivePeerAddressFromCurrentPacket();
+ }
+
private:
TestPacketWriter* writer() {
return static_cast<TestPacketWriter*>(QuicConnection::writer());
@@ -680,6 +706,8 @@ class TestConnection : public QuicConnection {
SimpleSessionNotifier* notifier_;
+ std::unique_ptr<QuicSocketAddress> next_effective_peer_addr_;
+
DISALLOW_COPY_AND_ASSIGN(TestConnection);
};
@@ -709,6 +737,8 @@ struct TestParams {
// Constructs various test permutations.
std::vector<TestParams> GetTestParams() {
+ QuicFlagSaver flags;
+ SetQuicFlag(&FLAGS_quic_supports_tls_handshake, true);
std::vector<TestParams> params;
ParsedQuicVersionVector all_supported_versions = AllSupportedVersions();
for (size_t i = 0; i < all_supported_versions.size(); ++i) {
@@ -753,9 +783,12 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
manager_(QuicConnectionPeer::GetSentPacketManager(&connection_)),
frame1_(1, false, 0, QuicStringPiece(data1)),
frame2_(1, false, 3, QuicStringPiece(data2)),
- packet_number_length_(PACKET_6BYTE_PACKET_NUMBER),
+ packet_number_length_(PACKET_4BYTE_PACKET_NUMBER),
connection_id_length_(PACKET_8BYTE_CONNECTION_ID),
- notifier_(&connection_) {
+ notifier_(&connection_),
+ use_path_degrading_alarm_(
+ GetQuicReloadableFlag(quic_path_degrading_alarm)) {
+ SetQuicFlag(&FLAGS_quic_supports_tls_handshake, true);
connection_.set_defer_send_in_response_to_packets(GetParam().ack_response ==
AckResponse::kDefer);
QuicConnectionPeer::SetNoStopWaitingFrames(&connection_,
@@ -796,6 +829,7 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
.WillRepeatedly(Return(false));
EXPECT_CALL(visitor_, OnCongestionWindowChange(_)).Times(AnyNumber());
EXPECT_CALL(visitor_, OnConnectivityProbeReceived(_, _)).Times(AnyNumber());
+ EXPECT_CALL(visitor_, OnForwardProgressConfirmed()).Times(AnyNumber());
EXPECT_CALL(*loss_algorithm_, GetLossTimeout())
.WillRepeatedly(Return(QuicTime::Zero()));
@@ -981,16 +1015,12 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
connection_.OnStreamReset(id, error);
return;
}
- if (connection_.use_control_frame_manager()) {
- std::unique_ptr<QuicRstStreamFrame> rst_stream =
- QuicMakeUnique<QuicRstStreamFrame>(1, id, error, bytes_written);
- if (connection_.SendControlFrame(QuicFrame(rst_stream.get()))) {
- rst_stream.release();
- }
- connection_.OnStreamReset(id, error);
- return;
+ std::unique_ptr<QuicRstStreamFrame> rst_stream =
+ QuicMakeUnique<QuicRstStreamFrame>(1, id, error, bytes_written);
+ if (connection_.SendControlFrame(QuicFrame(rst_stream.get()))) {
+ rst_stream.release();
}
- connection_.SendRstStream(id, error, bytes_written);
+ connection_.OnStreamReset(id, error);
}
void ProcessAckPacket(QuicPacketNumber packet_number, QuicAckFrame* frame) {
@@ -1168,6 +1198,10 @@ class QuicConnectionTest : public QuicTestWithParam<TestParams> {
SimpleSessionNotifier notifier_;
+ // Latched value of
+ // quic_reloadable_flag_quic_path_degrading_alarm
+ bool use_path_degrading_alarm_;
+
private:
DISALLOW_COPY_AND_ASSIGN(QuicConnectionTest);
};
@@ -1255,8 +1289,17 @@ TEST_P(QuicConnectionTest, ClientAddressChangeAndPacketReordered) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
set_perspective(Perspective::IS_SERVER);
QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
- // Clear peer address.
- QuicConnectionPeer::SetPeerAddress(&connection_, QuicSocketAddress());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ // Clear direct_peer_address.
+ QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+ // Clear effective_peer_address, it is the same as direct_peer_address for
+ // this test.
+ QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+ QuicSocketAddress());
+ } else {
+ // Clear peer_address.
+ QuicConnectionPeer::SetPeerAddress(&connection_, QuicSocketAddress());
+ }
QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 5);
QuicStreamFrame stream_frame(1u, false, 0u, QuicStringPiece());
@@ -1266,6 +1309,10 @@ TEST_P(QuicConnectionTest, ClientAddressChangeAndPacketReordered) {
/*port=*/23456);
ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress,
kNewPeerAddress);
+ EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+ }
// Decrease packet number to simulate out-of-order packets.
QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 4);
@@ -1273,6 +1320,10 @@ TEST_P(QuicConnectionTest, ClientAddressChangeAndPacketReordered) {
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress,
kPeerAddress);
+ EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+ }
}
TEST_P(QuicConnectionTest, PeerAddressChangeAtServer) {
@@ -1281,15 +1332,28 @@ TEST_P(QuicConnectionTest, PeerAddressChangeAtServer) {
QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
- // Clear peer address.
- QuicConnectionPeer::SetPeerAddress(&connection_, QuicSocketAddress());
- EXPECT_FALSE(connection_.peer_address().IsInitialized());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ // Clear direct_peer_address.
+ QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+ // Clear effective_peer_address, it is the same as direct_peer_address for
+ // this test.
+ QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+ QuicSocketAddress());
+ EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+ } else {
+ // Clear peer_address.
+ QuicConnectionPeer::SetPeerAddress(&connection_, QuicSocketAddress());
+ EXPECT_FALSE(connection_.peer_address().IsInitialized());
+ }
QuicStreamFrame stream_frame(1u, false, 0u, QuicStringPiece());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress,
kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+ }
// Process another packet with a different peer address on server side will
// start connection migration.
@@ -1299,6 +1363,78 @@ TEST_P(QuicConnectionTest, PeerAddressChangeAtServer) {
ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress,
kNewPeerAddress);
EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+ }
+}
+
+TEST_P(QuicConnectionTest, EffectivePeerAddressChangeAtServer) {
+ if (!GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ return;
+ }
+
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ set_perspective(Perspective::IS_SERVER);
+ QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+ EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
+
+ // Clear direct_peer_address.
+ QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+ // Clear effective_peer_address, it is different from direct_peer_address for
+ // this test.
+ QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+ QuicSocketAddress());
+ const QuicSocketAddress kEffectivePeerAddress =
+ QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/43210);
+ connection_.ReturnEffectivePeerAddressForNextPacket(kEffectivePeerAddress);
+
+ QuicStreamFrame stream_frame(1u, false, 0u, QuicStringPiece());
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+ ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress,
+ kPeerAddress);
+ EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ EXPECT_EQ(kEffectivePeerAddress, connection_.effective_peer_address());
+
+ // Process another packet with the same direct peer address and different
+ // effective peer address on server side will start connection migration.
+ const QuicSocketAddress kNewEffectivePeerAddress =
+ QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/54321);
+ connection_.ReturnEffectivePeerAddressForNextPacket(kNewEffectivePeerAddress);
+ EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
+ ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress,
+ kPeerAddress);
+ EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ EXPECT_EQ(kNewEffectivePeerAddress, connection_.effective_peer_address());
+
+ // Process another packet with a different direct peer address and the same
+ // effective peer address on server side will not start connection migration.
+ const QuicSocketAddress kNewPeerAddress =
+ QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/23456);
+ connection_.ReturnEffectivePeerAddressForNextPacket(kNewEffectivePeerAddress);
+ EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
+ // ack_frame is used to complete the migration started by the last packet, it
+ // is required to complete the last migration such that the next migration can
+ // start.
+ QuicAckFrame ack_frame = InitAckFrame(1);
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _));
+ ProcessFramePacketWithAddresses(QuicFrame(&ack_frame), kSelfAddress,
+ kNewPeerAddress);
+ EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+ EXPECT_EQ(kNewEffectivePeerAddress, connection_.effective_peer_address());
+
+ // Process another packet with different direct peer address and different
+ // effective peer address on server side will start connection migration.
+ const QuicSocketAddress kFinalEffectivePeerAddress =
+ QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/65432);
+ const QuicSocketAddress kFinalPeerAddress =
+ QuicSocketAddress(QuicIpAddress::Loopback6(), /*port=*/34567);
+ connection_.ReturnEffectivePeerAddressForNextPacket(
+ kFinalEffectivePeerAddress);
+ EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(1);
+ ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress,
+ kFinalPeerAddress);
+ EXPECT_EQ(kFinalPeerAddress, connection_.peer_address());
+ EXPECT_EQ(kFinalEffectivePeerAddress, connection_.effective_peer_address());
}
TEST_P(QuicConnectionTest, ReceivePaddedPingAtServer) {
@@ -1307,15 +1443,28 @@ TEST_P(QuicConnectionTest, ReceivePaddedPingAtServer) {
QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
- // Clear peer address.
- QuicConnectionPeer::SetPeerAddress(&connection_, QuicSocketAddress());
- EXPECT_FALSE(connection_.peer_address().IsInitialized());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ // Clear direct_peer_address.
+ QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+ // Clear effective_peer_address, it is the same as direct_peer_address for
+ // this test.
+ QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+ QuicSocketAddress());
+ EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+ } else {
+ // Clear peer_address.
+ QuicConnectionPeer::SetPeerAddress(&connection_, QuicSocketAddress());
+ EXPECT_FALSE(connection_.peer_address().IsInitialized());
+ }
QuicStreamFrame stream_frame(1u, false, 0u, QuicStringPiece());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress,
kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+ }
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
EXPECT_CALL(visitor_, OnConnectivityProbeReceived(_, _)).Times(0);
@@ -1331,7 +1480,77 @@ TEST_P(QuicConnectionTest, ReceivePaddedPingAtServer) {
clock_.Now()));
ProcessReceivedPacket(kSelfAddress, kPeerAddress, *received);
+
+ EXPECT_FALSE(connection_.IsCurrentPacketConnectivityProbing());
EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+ }
+}
+
+TEST_P(QuicConnectionTest, WriteOutOfOrderQueuedPackets) {
+ // When the flag is false, this test will trigger a use-after-free, which
+ // often means crashes, but not always, i.e. it can't be reliably tested.
+ SetQuicReloadableFlag(quic_fix_write_out_of_order_queued_packet_crash, true);
+ set_perspective(Perspective::IS_CLIENT);
+
+ BlockOnNextWrite();
+
+ QuicStreamId stream_id = 2;
+ connection_.SendStreamDataWithString(stream_id, "foo", 0, NO_FIN);
+
+ EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+ writer_->SetWritable();
+ connection_.SendConnectivityProbingPacket(writer_.get(),
+ connection_.peer_address());
+
+ if (GetQuicReloadableFlag(
+ quic_clear_queued_packets_before_sending_connectivity_probing)) {
+ EXPECT_EQ(0u, connection_.NumQueuedPackets());
+ connection_.OnCanWrite();
+ EXPECT_TRUE(connection_.connected());
+ } else {
+ EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_INTERNAL_ERROR,
+ "Packet written out of order.",
+ ConnectionCloseSource::FROM_SELF));
+ EXPECT_QUIC_BUG(connection_.OnCanWrite(),
+ "Attempt to write packet:1 after:2");
+ EXPECT_FALSE(connection_.connected());
+ }
+}
+
+TEST_P(QuicConnectionTest, DiscardQueuedPacketsAfterConnectionClose) {
+ // Regression test for b/74073386.
+ // When the flag is false, this test will trigger a use-after-free, which
+ // often means crashes, but not always, i.e. it can't be reliably tested.
+ SetQuicReloadableFlag(quic_fix_write_out_of_order_queued_packet_crash, true);
+ {
+ InSequence seq;
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+ EXPECT_CALL(visitor_, OnConnectionClosed(_, _, _)).Times(1);
+ }
+
+ set_perspective(Perspective::IS_CLIENT);
+
+ writer_->SimulateNextPacketTooLarge();
+
+ // This packet write should fail, which should cause the connection to close
+ // after sending a connection close packet, then the failed packet should be
+ // queued.
+ connection_.SendStreamDataWithString(/*id=*/2, "foo", 0, NO_FIN);
+
+ EXPECT_FALSE(connection_.connected());
+ EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+ if (GetQuicReloadableFlag(quic_always_discard_packets_after_close)) {
+ EXPECT_EQ(0u, connection_.GetStats().packets_discarded);
+ connection_.OnCanWrite();
+ EXPECT_EQ(1u, connection_.GetStats().packets_discarded);
+ } else {
+ EXPECT_QUIC_BUG(connection_.OnCanWrite(),
+ "Attempt to write packet:1 after:2");
+ }
}
TEST_P(QuicConnectionTest, ReceiveConnectivityProbingAtServer) {
@@ -1340,15 +1559,28 @@ TEST_P(QuicConnectionTest, ReceiveConnectivityProbingAtServer) {
QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
- // Clear peer address.
- QuicConnectionPeer::SetPeerAddress(&connection_, QuicSocketAddress());
- EXPECT_FALSE(connection_.peer_address().IsInitialized());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ // Clear direct_peer_address.
+ QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+ // Clear effective_peer_address, it is the same as direct_peer_address for
+ // this test.
+ QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+ QuicSocketAddress());
+ EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+ } else {
+ // Clear peer_address.
+ QuicConnectionPeer::SetPeerAddress(&connection_, QuicSocketAddress());
+ EXPECT_FALSE(connection_.peer_address().IsInitialized());
+ }
QuicStreamFrame stream_frame(1u, false, 0u, QuicStringPiece());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress,
kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+ }
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
EXPECT_CALL(visitor_, OnConnectivityProbeReceived(_, _)).Times(1);
@@ -1367,13 +1599,22 @@ TEST_P(QuicConnectionTest, ReceiveConnectivityProbingAtServer) {
clock_.Now()));
ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
+
+ EXPECT_TRUE(connection_.IsCurrentPacketConnectivityProbing());
EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+ }
// Process another packet with the old peer address on server side will not
// start peer migration.
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress,
kPeerAddress);
+ EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+ }
}
TEST_P(QuicConnectionTest, MigrateAfterProbingAtServer) {
@@ -1382,15 +1623,28 @@ TEST_P(QuicConnectionTest, MigrateAfterProbingAtServer) {
QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
EXPECT_EQ(Perspective::IS_SERVER, connection_.perspective());
- // Clear peer address.
- QuicConnectionPeer::SetPeerAddress(&connection_, QuicSocketAddress());
- EXPECT_FALSE(connection_.peer_address().IsInitialized());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ // Clear direct_peer_address.
+ QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+ // Clear effective_peer_address, it is the same as direct_peer_address for
+ // this test.
+ QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+ QuicSocketAddress());
+ EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+ } else {
+ // Clear peer_address.
+ QuicConnectionPeer::SetPeerAddress(&connection_, QuicSocketAddress());
+ EXPECT_FALSE(connection_.peer_address().IsInitialized());
+ }
QuicStreamFrame stream_frame(1u, false, 0u, QuicStringPiece());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress,
kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+ }
EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0);
EXPECT_CALL(visitor_, OnConnectivityProbeReceived(_, _)).Times(1);
@@ -1409,6 +1663,9 @@ TEST_P(QuicConnectionTest, MigrateAfterProbingAtServer) {
clock_.Now()));
ProcessReceivedPacket(kSelfAddress, kNewPeerAddress, *received);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+ }
// Process another non-probing packet with the new peer address on server
// side will start peer migration.
@@ -1417,6 +1674,9 @@ TEST_P(QuicConnectionTest, MigrateAfterProbingAtServer) {
ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress,
kNewPeerAddress);
EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+ }
}
TEST_P(QuicConnectionTest, ReceivePaddedPingAtClient) {
@@ -1424,15 +1684,28 @@ TEST_P(QuicConnectionTest, ReceivePaddedPingAtClient) {
set_perspective(Perspective::IS_CLIENT);
EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
- // Clear peer address.
- QuicConnectionPeer::SetPeerAddress(&connection_, QuicSocketAddress());
- EXPECT_FALSE(connection_.peer_address().IsInitialized());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ // Clear direct_peer_address.
+ QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+ // Clear effective_peer_address, it is the same as direct_peer_address for
+ // this test.
+ QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+ QuicSocketAddress());
+ EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+ } else {
+ // Clear peer_address.
+ QuicConnectionPeer::SetPeerAddress(&connection_, QuicSocketAddress());
+ EXPECT_FALSE(connection_.peer_address().IsInitialized());
+ }
QuicStreamFrame stream_frame(1u, false, 0u, QuicStringPiece());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress,
kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+ }
// Client takes all padded PING packet as speculative connectivity
// probing packet, and reports to visitor.
@@ -1448,7 +1721,11 @@ TEST_P(QuicConnectionTest, ReceivePaddedPingAtClient) {
clock_.Now()));
ProcessReceivedPacket(kSelfAddress, kPeerAddress, *received);
+ EXPECT_FALSE(connection_.IsCurrentPacketConnectivityProbing());
EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+ }
}
TEST_P(QuicConnectionTest, ReceiveConnectivityProbingAtClient) {
@@ -1456,15 +1733,28 @@ TEST_P(QuicConnectionTest, ReceiveConnectivityProbingAtClient) {
set_perspective(Perspective::IS_CLIENT);
EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
- // Clear peer address.
- QuicConnectionPeer::SetPeerAddress(&connection_, QuicSocketAddress());
- EXPECT_FALSE(connection_.peer_address().IsInitialized());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ // Clear direct_peer_address.
+ QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+ // Clear effective_peer_address, it is the same as direct_peer_address for
+ // this test.
+ QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+ QuicSocketAddress());
+ EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+ } else {
+ // Clear peer_address.
+ QuicConnectionPeer::SetPeerAddress(&connection_, QuicSocketAddress());
+ EXPECT_FALSE(connection_.peer_address().IsInitialized());
+ }
QuicStreamFrame stream_frame(1u, false, 0u, QuicStringPiece());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress,
kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+ }
// Process a padded PING packet with a different self address on client side
// is effectively receiving a connectivity probing.
@@ -1483,7 +1773,11 @@ TEST_P(QuicConnectionTest, ReceiveConnectivityProbingAtClient) {
clock_.Now()));
ProcessReceivedPacket(kNewSelfAddress, kPeerAddress, *received);
+ EXPECT_TRUE(connection_.IsCurrentPacketConnectivityProbing());
EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+ }
}
TEST_P(QuicConnectionTest, PeerAddressChangeAtClient) {
@@ -1491,15 +1785,28 @@ TEST_P(QuicConnectionTest, PeerAddressChangeAtClient) {
set_perspective(Perspective::IS_CLIENT);
EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
- // Clear peer address.
- QuicConnectionPeer::SetPeerAddress(&connection_, QuicSocketAddress());
- EXPECT_FALSE(connection_.peer_address().IsInitialized());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ // Clear direct_peer_address.
+ QuicConnectionPeer::SetDirectPeerAddress(&connection_, QuicSocketAddress());
+ // Clear effective_peer_address, it is the same as direct_peer_address for
+ // this test.
+ QuicConnectionPeer::SetEffectivePeerAddress(&connection_,
+ QuicSocketAddress());
+ EXPECT_FALSE(connection_.effective_peer_address().IsInitialized());
+ } else {
+ // Clear peer_address.
+ QuicConnectionPeer::SetPeerAddress(&connection_, QuicSocketAddress());
+ EXPECT_FALSE(connection_.peer_address().IsInitialized());
+ }
QuicStreamFrame stream_frame(1u, false, 0u, QuicStringPiece());
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress,
kPeerAddress);
EXPECT_EQ(kPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kPeerAddress, connection_.effective_peer_address());
+ }
// Process another packet with a different peer address on client side will
// only update peer address.
@@ -1509,6 +1816,9 @@ TEST_P(QuicConnectionTest, PeerAddressChangeAtClient) {
ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress,
kNewPeerAddress);
EXPECT_EQ(kNewPeerAddress, connection_.peer_address());
+ if (GetQuicReloadableFlag(quic_enable_server_proxy)) {
+ EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
+ }
}
TEST_P(QuicConnectionTest, MaxPacketSize) {
@@ -1858,16 +2168,11 @@ TEST_P(QuicConnectionTest, AckNeedsRetransmittableFrames) {
}
// Receiving Packet 40 causes 20th ack to send. Session is informed and adds
// WINDOW_UPDATE.
- if (connection_.use_control_frame_manager()) {
- EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
- .WillOnce(Invoke([this]() {
- connection_.SendControlFrame(
- QuicFrame(new QuicWindowUpdateFrame(1, 0, 0)));
- }));
- } else {
- EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
- .WillOnce(Invoke([this]() { connection_.SendWindowUpdate(0, 0); }));
- }
+ EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
+ .WillOnce(Invoke([this]() {
+ connection_.SendControlFrame(
+ QuicFrame(new QuicWindowUpdateFrame(1, 0, 0)));
+ }));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
EXPECT_EQ(0u, writer_->window_update_frames().size());
ProcessDataPacket(40);
@@ -1888,14 +2193,10 @@ TEST_P(QuicConnectionTest, AckNeedsRetransmittableFrames) {
EXPECT_EQ(0u, writer_->window_update_frames().size());
}
// Session does not add a retransmittable frame.
- if (connection_.use_control_frame_manager()) {
- EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
- .WillOnce(Invoke([this]() {
- connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
- }));
- } else {
- EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(1);
- }
+ EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame())
+ .WillOnce(Invoke([this]() {
+ connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
+ }));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
EXPECT_EQ(0u, writer_->ping_frames().size());
ProcessDataPacket(99);
@@ -1940,8 +2241,6 @@ TEST_P(QuicConnectionTest, LeastUnackedLower) {
}
TEST_P(QuicConnectionTest, TooManySentPackets) {
- SetQuicReloadableFlag(quic_close_session_on_too_many_outstanding_sent_packets,
- true);
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
QuicPacketCount max_tracked_packets = 50;
@@ -2403,8 +2702,7 @@ TEST_P(QuicConnectionTest, DoNotSendQueuedPacketForResetStream) {
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
writer_->SetWritable();
connection_.OnCanWrite();
- if (connection_.use_control_frame_manager() &&
- !connection_.session_decides_what_to_write()) {
+ if (!connection_.session_decides_what_to_write()) {
// OnCanWrite will cause RST_STREAM be sent again.
connection_.SendControlFrame(QuicFrame(new QuicRstStreamFrame(
1, stream_id, QUIC_ERROR_PROCESSING_STREAM, 14)));
@@ -2428,8 +2726,7 @@ TEST_P(QuicConnectionTest, SendQueuedPacketForQuicRstStreamNoError) {
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(2));
writer_->SetWritable();
connection_.OnCanWrite();
- if (connection_.use_control_frame_manager() &&
- !connection_.session_decides_what_to_write()) {
+ if (!connection_.session_decides_what_to_write()) {
// OnCanWrite will cause RST_STREAM be sent again.
connection_.SendControlFrame(QuicFrame(
new QuicRstStreamFrame(1, stream_id, QUIC_STREAM_NO_ERROR, 14)));
@@ -2566,8 +2863,7 @@ TEST_P(QuicConnectionTest, DoNotSendPendingRetransmissionForResetStream) {
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
writer_->SetWritable();
connection_.OnCanWrite();
- if (connection_.use_control_frame_manager() &&
- !connection_.session_decides_what_to_write()) {
+ if (!connection_.session_decides_what_to_write()) {
// OnCanWrite will cause this RST_STREAM_FRAME be sent again.
connection_.SendControlFrame(QuicFrame(new QuicRstStreamFrame(
1, stream_id, QUIC_ERROR_PROCESSING_STREAM, 14)));
@@ -2603,17 +2899,12 @@ TEST_P(QuicConnectionTest, SendPendingRetransmissionForQuicRstStreamNoError) {
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AtLeast(2));
writer_->SetWritable();
connection_.OnCanWrite();
- if (connection_.use_control_frame_manager()) {
- // The RST_STREAM_FRAME is sent after queued packets and pending
- // retransmission.
- connection_.SendControlFrame(QuicFrame(
- new QuicRstStreamFrame(1, stream_id, QUIC_STREAM_NO_ERROR, 14)));
- EXPECT_EQ(1u, writer_->frame_count());
- EXPECT_EQ(1u, writer_->rst_stream_frames().size());
- } else {
- EXPECT_EQ(1u, writer_->frame_count());
- EXPECT_EQ(0u, writer_->rst_stream_frames().size());
- }
+ // The RST_STREAM_FRAME is sent after queued packets and pending
+ // retransmission.
+ connection_.SendControlFrame(QuicFrame(
+ new QuicRstStreamFrame(1, stream_id, QUIC_STREAM_NO_ERROR, 14)));
+ EXPECT_EQ(1u, writer_->frame_count());
+ EXPECT_EQ(1u, writer_->rst_stream_frames().size());
}
TEST_P(QuicConnectionTest, RetransmitAckedPacket) {
@@ -2640,6 +2931,9 @@ TEST_P(QuicConnectionTest, RetransmitAckedPacket) {
// Now, ack the previous transmission.
EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _));
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(false, _, _, _, _));
+ }
QuicAckFrame ack_all = InitAckFrame(3);
ProcessAckPacket(&ack_all);
@@ -2940,11 +3234,13 @@ TEST_P(QuicConnectionTest, RetransmitWithSameEncryptionLevel) {
// A TaggingEncrypter puts kTagSize copies of the given byte (0x01 here) at
// the end of the packet. We can test this to check which encrypter was used.
- connection_.SetEncrypter(ENCRYPTION_NONE, new TaggingEncrypter(0x01));
+ connection_.SetEncrypter(ENCRYPTION_NONE,
+ QuicMakeUnique<TaggingEncrypter>(0x01));
SendStreamDataToPeer(kCryptoStreamId, "foo", 0, NO_FIN, nullptr);
EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
- connection_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(0x02));
+ connection_.SetEncrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingEncrypter>(0x02));
connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet());
@@ -2969,7 +3265,8 @@ TEST_P(QuicConnectionTest, SendHandshakeMessages) {
use_tagging_decrypter();
// A TaggingEncrypter puts kTagSize copies of the given byte (0x01 here) at
// the end of the packet. We can test this to check which encrypter was used.
- connection_.SetEncrypter(ENCRYPTION_NONE, new TaggingEncrypter(0x01));
+ connection_.SetEncrypter(ENCRYPTION_NONE,
+ QuicMakeUnique<TaggingEncrypter>(0x01));
// Attempt to send a handshake message and have the socket block.
EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
@@ -2979,7 +3276,8 @@ TEST_P(QuicConnectionTest, SendHandshakeMessages) {
EXPECT_EQ(1u, connection_.NumQueuedPackets());
// Switch to the new encrypter.
- connection_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(0x02));
+ connection_.SetEncrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingEncrypter>(0x02));
connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
// Now become writeable and flush the packets.
@@ -2995,7 +3293,8 @@ TEST_P(QuicConnectionTest, SendHandshakeMessages) {
TEST_P(QuicConnectionTest,
DropRetransmitsForNullEncryptedPacketAfterForwardSecure) {
use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_NONE, new TaggingEncrypter(0x01));
+ connection_.SetEncrypter(ENCRYPTION_NONE,
+ QuicMakeUnique<TaggingEncrypter>(0x01));
QuicPacketNumber packet_number;
SendStreamDataToPeer(kCryptoStreamId, "foo", 0, NO_FIN, &packet_number);
@@ -3006,7 +3305,7 @@ TEST_P(QuicConnectionTest,
// Go forward secure.
connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- new TaggingEncrypter(0x02));
+ QuicMakeUnique<TaggingEncrypter>(0x02));
connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
notifier_.NeuterUnencryptedData();
connection_.NeuterUnencryptedPackets();
@@ -3020,12 +3319,14 @@ TEST_P(QuicConnectionTest,
TEST_P(QuicConnectionTest, RetransmitPacketsWithInitialEncryption) {
use_tagging_decrypter();
- connection_.SetEncrypter(ENCRYPTION_NONE, new TaggingEncrypter(0x01));
+ connection_.SetEncrypter(ENCRYPTION_NONE,
+ QuicMakeUnique<TaggingEncrypter>(0x01));
connection_.SetDefaultEncryptionLevel(ENCRYPTION_NONE);
SendStreamDataToPeer(1, "foo", 0, NO_FIN, nullptr);
- connection_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(0x02));
+ connection_.SetEncrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingEncrypter>(0x02));
connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
SendStreamDataToPeer(2, "bar", 0, NO_FIN, nullptr);
@@ -3043,7 +3344,8 @@ TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) {
use_tagging_decrypter();
const uint8_t tag = 0x07;
- peer_framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+ peer_framer_.SetEncrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingEncrypter>(tag));
// Process an encrypted packet which can not yet be decrypted which should
// result in the packet being buffered.
@@ -3051,9 +3353,11 @@ TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) {
// Transition to the new encryption state and process another encrypted packet
// which should result in the original packet being processed.
- connection_.SetDecrypter(ENCRYPTION_INITIAL, new StrictTaggingDecrypter(tag));
+ connection_.SetDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- connection_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+ connection_.SetEncrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingEncrypter>(tag));
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(2);
ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_INITIAL);
@@ -3073,7 +3377,8 @@ TEST_P(QuicConnectionTest, Buffer100NonDecryptablePackets) {
use_tagging_decrypter();
const uint8_t tag = 0x07;
- peer_framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+ peer_framer_.SetEncrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingEncrypter>(tag));
// Process an encrypted packet which can not yet be decrypted which should
// result in the packet being buffered.
@@ -3083,9 +3388,11 @@ TEST_P(QuicConnectionTest, Buffer100NonDecryptablePackets) {
// Transition to the new encryption state and process another encrypted packet
// which should result in the original packets being processed.
- connection_.SetDecrypter(ENCRYPTION_INITIAL, new StrictTaggingDecrypter(tag));
+ connection_.SetDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
- connection_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+ connection_.SetEncrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingEncrypter>(tag));
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(101);
ProcessDataPacketAtLevel(101, !kHasStopWaiting, ENCRYPTION_INITIAL);
@@ -3121,7 +3428,9 @@ TEST_P(QuicConnectionTest, TestRetransmitOrder) {
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(20));
{
InSequence s;
- EXPECT_CALL(visitor_, OnPathDegrading());
+ if (!use_path_degrading_alarm_) {
+ EXPECT_CALL(visitor_, OnPathDegrading());
+ }
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, first_packet_size, _));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, second_packet_size, _));
}
@@ -3227,6 +3536,7 @@ TEST_P(QuicConnectionTest, InitialTimeout) {
EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
+ EXPECT_FALSE(connection_.GetRetransmittableOnWireAlarm()->IsSet());
}
TEST_P(QuicConnectionTest, HandshakeTimeout) {
@@ -3285,7 +3595,7 @@ TEST_P(QuicConnectionTest, PingAfterSend) {
EXPECT_EQ(clock_.ApproximateNow() + QuicTime::Delta::FromSeconds(15),
connection_.GetPingAlarm()->deadline());
- // Now recevie and ACK of the previous packet, which will move the
+ // Now recevie an ACK of the previous packet, which will move the
// ping alarm forward.
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
QuicAckFrame frame = InitAckFrame(1);
@@ -3301,11 +3611,9 @@ TEST_P(QuicConnectionTest, PingAfterSend) {
writer_->Reset();
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
- if (connection_.use_control_frame_manager()) {
- EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
- connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
- }));
- }
+ EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+ connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
+ }));
connection_.GetPingAlarm()->Fire();
EXPECT_EQ(1u, writer_->frame_count());
ASSERT_EQ(1u, writer_->ping_frames().size());
@@ -3335,7 +3643,7 @@ TEST_P(QuicConnectionTest, ReducedPingTimeout) {
EXPECT_EQ(clock_.ApproximateNow() + QuicTime::Delta::FromSeconds(10),
connection_.GetPingAlarm()->deadline());
- // Now recevie and ACK of the previous packet, which will move the
+ // Now recevie an ACK of the previous packet, which will move the
// ping alarm forward.
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
QuicAckFrame frame = InitAckFrame(1);
@@ -3351,11 +3659,9 @@ TEST_P(QuicConnectionTest, ReducedPingTimeout) {
writer_->Reset();
clock_.AdvanceTime(QuicTime::Delta::FromSeconds(10));
- if (connection_.use_control_frame_manager()) {
- EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
- connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
- }));
- }
+ EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+ connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
+ }));
connection_.GetPingAlarm()->Fire();
EXPECT_EQ(1u, writer_->frame_count());
ASSERT_EQ(1u, writer_->ping_frames().size());
@@ -4067,7 +4373,9 @@ TEST_P(QuicConnectionTest, TimeoutAfter5ClientRTOs) {
// Send stream data.
SendStreamDataToPeer(kClientDataStreamId1, "foo", 0, FIN, nullptr);
- EXPECT_CALL(visitor_, OnPathDegrading());
+ if (!use_path_degrading_alarm_) {
+ EXPECT_CALL(visitor_, OnPathDegrading());
+ }
// Fire the retransmission alarm 6 times, twice for TLP and 4 times for RTO.
for (int i = 0; i < 6; ++i) {
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
@@ -4101,7 +4409,9 @@ TEST_P(QuicConnectionTest, TimeoutAfter3ClientRTOs) {
// Send stream data.
SendStreamDataToPeer(kClientDataStreamId1, "foo", 0, FIN, nullptr);
- EXPECT_CALL(visitor_, OnPathDegrading());
+ if (!use_path_degrading_alarm_) {
+ EXPECT_CALL(visitor_, OnPathDegrading());
+ }
// Fire the retransmission alarm 4 times, twice for TLP and 2 times for RTO.
for (int i = 0; i < 4; ++i) {
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
@@ -4224,8 +4534,10 @@ TEST_P(QuicConnectionTest, SendDelayedAck) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_INITIAL, new StrictTaggingDecrypter(tag));
- peer_framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+ connection_.SetDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ peer_framer_.SetEncrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
frame1_.stream_id = 3;
@@ -4266,8 +4578,10 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimation) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_INITIAL, new StrictTaggingDecrypter(tag));
- peer_framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+ connection_.SetDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ peer_framer_.SetEncrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
frame1_.stream_id = 3;
@@ -4329,8 +4643,10 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationUnlimitedAggregation) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_INITIAL, new StrictTaggingDecrypter(tag));
- peer_framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+ connection_.SetDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ peer_framer_.SetEncrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
frame1_.stream_id = 3;
@@ -4380,8 +4696,10 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationEighthRtt) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_INITIAL, new StrictTaggingDecrypter(tag));
- peer_framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+ connection_.SetDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ peer_framer_.SetEncrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
frame1_.stream_id = 3;
@@ -4437,8 +4755,10 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithReordering) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_INITIAL, new StrictTaggingDecrypter(tag));
- peer_framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+ connection_.SetDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ peer_framer_.SetEncrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
frame1_.stream_id = 3;
@@ -4502,8 +4822,10 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithLargeReordering) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_INITIAL, new StrictTaggingDecrypter(tag));
- peer_framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+ connection_.SetDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ peer_framer_.SetEncrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
frame1_.stream_id = 3;
@@ -4585,8 +4907,10 @@ TEST_P(QuicConnectionTest, SendDelayedAckDecimationWithReorderingEighthRtt) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_INITIAL, new StrictTaggingDecrypter(tag));
- peer_framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+ connection_.SetDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ peer_framer_.SetEncrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
frame1_.stream_id = 3;
@@ -4652,8 +4976,10 @@ TEST_P(QuicConnectionTest,
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_INITIAL, new StrictTaggingDecrypter(tag));
- peer_framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
+ connection_.SetDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ peer_framer_.SetEncrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
frame1_.stream_id = 3;
@@ -4954,6 +5280,102 @@ TEST_P(QuicConnectionTest, SendWhenDisconnected) {
false, false);
}
+TEST_P(QuicConnectionTest, SendConnectivityProbingWhenDisconnected) {
+ EXPECT_TRUE(connection_.connected());
+ EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_PEER_GOING_AWAY, _,
+ ConnectionCloseSource::FROM_SELF));
+ connection_.CloseConnection(QUIC_PEER_GOING_AWAY, "no reason",
+ ConnectionCloseBehavior::SILENT_CLOSE);
+ EXPECT_FALSE(connection_.connected());
+ EXPECT_FALSE(connection_.CanWriteStreamData());
+
+ int num_packets_sent =
+ GetQuicReloadableFlag(quic_always_discard_packets_after_close) ? 0 : 1;
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _))
+ .Times(num_packets_sent);
+
+ if (GetQuicReloadableFlag(quic_always_discard_packets_after_close)) {
+ EXPECT_QUIC_BUG(connection_.SendConnectivityProbingPacket(
+ writer_.get(), connection_.peer_address()),
+ "Not sending connectivity probing packet as connection is "
+ "disconnected.");
+ } else {
+ connection_.SendConnectivityProbingPacket(writer_.get(),
+ connection_.peer_address());
+ }
+}
+
+TEST_P(QuicConnectionTest, WriteBlockedAfterClientSendsConnectivityProbe) {
+ EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+ TestPacketWriter probing_writer(version(), &clock_);
+ // Block next write so that sending connectivity probe will encounter a
+ // blocked write when send a connectivity probe to the peer.
+ probing_writer.BlockOnNextWrite();
+ if (GetQuicReloadableFlag(quic_handle_write_results_for_connectivity_probe)) {
+ // Connection will not be marked as write blocked as connectivity probe only
+ // affects the probing_writer which is not the default.
+ EXPECT_CALL(visitor_, OnWriteBlocked()).Times(0);
+ } else {
+ EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
+ }
+
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(1);
+ connection_.SendConnectivityProbingPacket(&probing_writer,
+ connection_.peer_address());
+}
+
+TEST_P(QuicConnectionTest, WriterBlockedAfterServerSendsConnectivityProbe) {
+ set_perspective(Perspective::IS_SERVER);
+ QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+
+ // Block next write so that sending connectivity probe will encounter a
+ // blocked write when send a connectivity probe to the peer.
+ writer_->BlockOnNextWrite();
+ // Connection will be marked as write blocked as server uses the default
+ // writer to send connectivity probes.
+ EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
+
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(1);
+ connection_.SendConnectivityProbingPacket(writer_.get(),
+ connection_.peer_address());
+}
+
+TEST_P(QuicConnectionTest, WriterErrorWhenClientSendsConnectivityProbe) {
+ EXPECT_EQ(Perspective::IS_CLIENT, connection_.perspective());
+ TestPacketWriter probing_writer(version(), &clock_);
+ probing_writer.SetShouldWriteFail();
+
+ if (GetQuicReloadableFlag(quic_handle_write_results_for_connectivity_probe)) {
+ // Connection should not be closed if a connectivity probe is failed to be
+ // sent.
+ EXPECT_CALL(visitor_, OnConnectionClosed(_, _, _)).Times(0);
+ } else {
+ EXPECT_CALL(visitor_, OnConnectionClosed(_, _, _)).Times(1);
+ }
+
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
+ connection_.SendConnectivityProbingPacket(&probing_writer,
+ connection_.peer_address());
+}
+
+TEST_P(QuicConnectionTest, WriterErrorWhenServerSendsConnectivityProbe) {
+ set_perspective(Perspective::IS_SERVER);
+ QuicPacketCreatorPeer::SetSendVersionInPacket(creator_, false);
+
+ writer_->SetShouldWriteFail();
+ if (GetQuicReloadableFlag(quic_handle_write_results_for_connectivity_probe)) {
+ // Connection should not be closed if a connectivity probe is failed to be
+ // sent.
+ EXPECT_CALL(visitor_, OnConnectionClosed(_, _, _)).Times(0);
+ } else {
+ EXPECT_CALL(visitor_, OnConnectionClosed(_, _, _)).Times(1);
+ }
+
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
+ connection_.SendConnectivityProbingPacket(writer_.get(),
+ connection_.peer_address());
+}
+
TEST_P(QuicConnectionTest, PublicReset) {
QuicPublicResetPacket header;
// Public reset packet in only built by server.
@@ -5131,7 +5553,7 @@ TEST_P(QuicConnectionTest, ClientHandlesVersionNegotiation) {
// Send a version negotiation packet.
std::unique_ptr<QuicEncryptedPacket> encrypted(
- peer_framer_.BuildVersionNegotiationPacket(connection_id_,
+ peer_framer_.BuildVersionNegotiationPacket(connection_id_, false,
AllSupportedVersions()));
std::unique_ptr<QuicReceivedPacket> received(
ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
@@ -5166,7 +5588,7 @@ TEST_P(QuicConnectionTest, BadVersionNegotiation) {
OnConnectionClosed(QUIC_INVALID_VERSION_NEGOTIATION_PACKET, _,
ConnectionCloseSource::FROM_SELF));
std::unique_ptr<QuicEncryptedPacket> encrypted(
- framer_.BuildVersionNegotiationPacket(connection_id_,
+ framer_.BuildVersionNegotiationPacket(connection_id_, false,
AllSupportedVersions()));
std::unique_ptr<QuicReceivedPacket> received(
ConstructReceivedPacket(*encrypted, QuicTime::Zero()));
@@ -5415,11 +5837,7 @@ TEST_P(QuicConnectionTest, SendPingImmediately) {
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _)).Times(1);
EXPECT_CALL(debug_visitor, OnPingSent()).Times(1);
- if (connection_.use_control_frame_manager()) {
- connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
- } else {
- connection_.SendPing();
- }
+ connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
EXPECT_FALSE(connection_.HasQueuedData());
}
@@ -5430,11 +5848,7 @@ TEST_P(QuicConnectionTest, SendBlockedImmediately) {
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _)).Times(1);
EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
- if (connection_.use_control_frame_manager()) {
- connection_.SendControlFrame(QuicFrame(new QuicBlockedFrame(1, 3)));
- } else {
- connection_.SendBlocked(3);
- }
+ connection_.SendControlFrame(QuicFrame(new QuicBlockedFrame(1, 3)));
EXPECT_EQ(1u, connection_.GetStats().blocked_frames_sent);
EXPECT_FALSE(connection_.HasQueuedData());
}
@@ -5451,6 +5865,10 @@ TEST_P(QuicConnectionTest, SendingUnencryptedStreamDataFails) {
}
TEST_P(QuicConnectionTest, OnPathDegrading) {
+ if (use_path_degrading_alarm_) {
+ return;
+ }
+
QuicByteCount packet_size;
const size_t kMinTimeoutsBeforePathDegrading = 2;
@@ -5478,6 +5896,140 @@ TEST_P(QuicConnectionTest, OnPathDegrading) {
connection_.GetRetransmissionAlarm()->Fire();
}
+// Includes regression test for https://b.corp.google.com/issues/69979024.
+TEST_P(QuicConnectionTest, PathDegradingAlarm) {
+ if (!use_path_degrading_alarm_) {
+ return;
+ }
+
+ EXPECT_TRUE(connection_.connected());
+ EXPECT_FALSE(connection_.GetPathDegradingAlarm()->IsSet());
+
+ const char data[] = "data";
+ size_t data_size = strlen(data);
+ QuicStreamOffset offset = 0;
+
+ for (int i = 0; i < 2; ++i) {
+ // Send a packet. Now there's a retransmittable packet on the wire, so the
+ // path degrading alarm should be set.
+ connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+ offset += data_size;
+ EXPECT_TRUE(connection_.GetPathDegradingAlarm()->IsSet());
+ // Check the deadline of the path degrading alarm.
+ QuicTime::Delta delay =
+ QuicConnectionPeer::GetSentPacketManager(&connection_)
+ ->GetPathDegradingDelay();
+ EXPECT_EQ(clock_.ApproximateNow() + delay,
+ connection_.GetPathDegradingAlarm()->deadline());
+
+ // Send a second packet. The path degrading alarm's deadline should remain
+ // the same.
+ // Regression test for https://b.corp.google.com/issues/69979024.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ QuicTime prev_deadline = connection_.GetPathDegradingAlarm()->deadline();
+ connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+ offset += data_size;
+ EXPECT_TRUE(connection_.GetPathDegradingAlarm()->IsSet());
+ EXPECT_EQ(prev_deadline, connection_.GetPathDegradingAlarm()->deadline());
+
+ // Now receive an ACK of the first packet. This should advance the path
+ // degrading alarm's deadline since forward progress has been made.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ if (i == 0) {
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ }
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+ QuicAckFrame frame = InitAckFrame({{1u + 2u * i, 2u + 2u * i}});
+ ProcessAckPacket(&frame);
+ EXPECT_TRUE(connection_.GetPathDegradingAlarm()->IsSet());
+ // Check the deadline of the path degrading alarm.
+ delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+ ->GetPathDegradingDelay();
+ EXPECT_EQ(clock_.ApproximateNow() + delay,
+ connection_.GetPathDegradingAlarm()->deadline());
+
+ if (i == 0) {
+ // Now receive an ACK of the second packet. Since there are no more
+ // retransmittable packets on the wire, this should cancel the path
+ // degrading alarm.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+ frame = InitAckFrame({{2, 3}});
+ ProcessAckPacket(&frame);
+ EXPECT_FALSE(connection_.GetPathDegradingAlarm()->IsSet());
+ } else {
+ // Advance time to the path degrading alarm's deadline and simulate
+ // firing the alarm.
+ clock_.AdvanceTime(delay);
+ EXPECT_CALL(visitor_, OnPathDegrading());
+ connection_.GetPathDegradingAlarm()->Fire();
+ EXPECT_FALSE(connection_.GetPathDegradingAlarm()->IsSet());
+ }
+ }
+}
+
+TEST_P(QuicConnectionTest, RetransmittableOnWireSetsPathDegradingAlarm) {
+ if (!use_path_degrading_alarm_) {
+ return;
+ }
+ const QuicTime::Delta retransmittable_on_wire_timeout =
+ QuicTime::Delta::FromMilliseconds(50);
+ connection_.set_retransmittable_on_wire_timeout(
+ retransmittable_on_wire_timeout);
+
+ EXPECT_TRUE(connection_.connected());
+ EXPECT_CALL(visitor_, HasOpenDynamicStreams()).WillRepeatedly(Return(true));
+
+ EXPECT_FALSE(connection_.GetPathDegradingAlarm()->IsSet());
+ EXPECT_FALSE(connection_.GetRetransmittableOnWireAlarm()->IsSet());
+
+ const char data[] = "data";
+ size_t data_size = strlen(data);
+ QuicStreamOffset offset = 0;
+
+ // Send a packet.
+ connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+ offset += data_size;
+ // Now there's a retransmittable packet on the wire, so the path degrading
+ // alarm should be set.
+ // The retransmittable-on-wire alarm should not be set.
+ EXPECT_TRUE(connection_.GetPathDegradingAlarm()->IsSet());
+ QuicTime::Delta delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+ ->GetPathDegradingDelay();
+ EXPECT_EQ(clock_.ApproximateNow() + delay,
+ connection_.GetPathDegradingAlarm()->deadline());
+ EXPECT_FALSE(connection_.GetRetransmittableOnWireAlarm()->IsSet());
+
+ // Now receive an ACK of the packet.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+ QuicAckFrame frame = InitAckFrame({{1, 2}});
+ ProcessAckPacket(&frame);
+ // No more retransmittable packets on the wire, so the path degrading alarm
+ // should be cancelled, and the retransmittable-on-wire alarm should be set
+ // since a PING might be needed.
+ EXPECT_FALSE(connection_.GetPathDegradingAlarm()->IsSet());
+ EXPECT_TRUE(connection_.GetRetransmittableOnWireAlarm()->IsSet());
+ EXPECT_EQ(clock_.ApproximateNow() + retransmittable_on_wire_timeout,
+ connection_.GetRetransmittableOnWireAlarm()->deadline());
+
+ // Simulate firing the retransmittable-on-wire alarm and sending a PING.
+ clock_.AdvanceTime(retransmittable_on_wire_timeout);
+ EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+ connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
+ }));
+ connection_.GetRetransmittableOnWireAlarm()->Fire();
+
+ // Now there's a retransmittable packet (PING) on the wire, so the path
+ // degrading alarm should be set.
+ EXPECT_TRUE(connection_.GetPathDegradingAlarm()->IsSet());
+ delay = QuicConnectionPeer::GetSentPacketManager(&connection_)
+ ->GetPathDegradingDelay();
+ EXPECT_EQ(clock_.ApproximateNow() + delay,
+ connection_.GetPathDegradingAlarm()->deadline());
+}
+
TEST_P(QuicConnectionTest, MultipleCallsToCloseConnection) {
// Verifies that multiple calls to CloseConnection do not
// result in multiple attempts to close the connection - it will be marked as
@@ -5741,53 +6293,195 @@ TEST_P(QuicConnectionTest,
connection_.SendProbingRetransmissions();
}
-TEST_P(QuicConnectionTest, HasPendingControlFramesWhenRetransmittingPackets) {
- if (connection_.use_control_frame_manager()) {
- // When use_control_frame_manager is true, the control frame will be
- // buffered in the control frame manager.
- return;
- }
- // This test mimics this scenario: writer get blocked when generator tries to
- // add a control frame, which will be pending. When writer get unblocked, this
- // pending control frame is sent in a packet before retransmissions.
+TEST_P(QuicConnectionTest, PingAfterLastRetransmittablePacketAcked) {
+ const QuicTime::Delta retransmittable_on_wire_timeout =
+ QuicTime::Delta::FromMilliseconds(50);
+ connection_.set_retransmittable_on_wire_timeout(
+ retransmittable_on_wire_timeout);
+
+ EXPECT_TRUE(connection_.connected());
+ EXPECT_CALL(visitor_, HasOpenDynamicStreams()).WillRepeatedly(Return(true));
+
+ const char data[] = "data";
+ size_t data_size = strlen(data);
+ QuicStreamOffset offset = 0;
+
+ // Advance 5ms, send a retransmittable packet to the peer.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ EXPECT_FALSE(connection_.GetRetransmittableOnWireAlarm()->IsSet());
+ connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+ offset += data_size;
+ EXPECT_FALSE(connection_.GetRetransmittableOnWireAlarm()->IsSet());
+
+ // Advance 5ms, send a second retransmittable packet to the peer.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ EXPECT_FALSE(connection_.GetRetransmittableOnWireAlarm()->IsSet());
+ connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+ offset += data_size;
+ EXPECT_FALSE(connection_.GetRetransmittableOnWireAlarm()->IsSet());
+
+ // Now receive an ACK of the first packet. This should not set the
+ // retransmittable-on-wire alarm since packet 2 is still on the wire.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- QuicPacketNumber last_packet;
- SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet); // Packet 1
- SendStreamDataToPeer(1, "foos", 3, NO_FIN, &last_packet); // Packet 2
- SendStreamDataToPeer(1, "foos", 7, NO_FIN, &last_packet); // Packet 3
- SendStreamDataToPeer(1, "foos", 11, NO_FIN, &last_packet); // Packet 4
- BlockOnNextWrite();
- connection_.SendStreamDataWithString(1, "foos", 15, NO_FIN); // Packet 5
- EXPECT_EQ(1u, connection_.NumQueuedPackets());
- EXPECT_TRUE(connection_.HasQueuedData());
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+ QuicAckFrame frame = InitAckFrame({{1, 2}});
+ ProcessAckPacket(&frame);
+ EXPECT_FALSE(connection_.GetRetransmittableOnWireAlarm()->IsSet());
- // This window update frame will be pending in the generator as writer is
- // blocked.
- connection_.SendWindowUpdate(1, 100);
- // Ack 4, nack 1-3.
- QuicAckFrame nack = InitAckFrame({{4, 5}});
- // 3 packets have been NACK'd and lost.
- LostPacketVector lost_packets;
- lost_packets.push_back(LostPacket(1, kMaxPacketSize));
- lost_packets.push_back(LostPacket(2, kMaxPacketSize));
- lost_packets.push_back(LostPacket(3, kMaxPacketSize));
+ // Now receive an ACK of the second packet. This should set the
+ // retransmittable-on-wire alarm now that no retransmittable packets are on
+ // the wire.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+ frame = InitAckFrame({{2, 3}});
+ ProcessAckPacket(&frame);
+ EXPECT_TRUE(connection_.GetRetransmittableOnWireAlarm()->IsSet());
+ EXPECT_EQ(clock_.ApproximateNow() + retransmittable_on_wire_timeout,
+ connection_.GetRetransmittableOnWireAlarm()->deadline());
+
+ // Now receive a duplicate ACK of the second packet. This should not update
+ // the retransmittable-on-wire alarm.
+ QuicTime prev_deadline =
+ connection_.GetRetransmittableOnWireAlarm()->deadline();
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ frame = InitAckFrame({{2, 3}});
+ ProcessAckPacket(&frame);
+ EXPECT_TRUE(connection_.GetRetransmittableOnWireAlarm()->IsSet());
+ EXPECT_EQ(prev_deadline,
+ connection_.GetRetransmittableOnWireAlarm()->deadline());
- EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _))
- .WillOnce(SetArgPointee<4>(lost_packets));
+ // Simulate the alarm firing and check that a PING is sent.
+ EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+ connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
+ }));
+ connection_.GetRetransmittableOnWireAlarm()->Fire();
+ if (GetParam().no_stop_waiting) {
+ EXPECT_EQ(2u, writer_->frame_count());
+ } else {
+ EXPECT_EQ(3u, writer_->frame_count());
+ }
+ ASSERT_EQ(1u, writer_->ping_frames().size());
+}
+
+TEST_P(QuicConnectionTest, NoPingIfRetransmittablePacketSent) {
+ const QuicTime::Delta retransmittable_on_wire_timeout =
+ QuicTime::Delta::FromMilliseconds(50);
+ connection_.set_retransmittable_on_wire_timeout(
+ retransmittable_on_wire_timeout);
+
+ EXPECT_TRUE(connection_.connected());
+ EXPECT_CALL(visitor_, HasOpenDynamicStreams()).WillRepeatedly(Return(true));
+
+ const char data[] = "data";
+ size_t data_size = strlen(data);
+ QuicStreamOffset offset = 0;
+
+ // Advance 5ms, send a retransmittable packet to the peer.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ EXPECT_FALSE(connection_.GetRetransmittableOnWireAlarm()->IsSet());
+ connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+ offset += data_size;
+ EXPECT_FALSE(connection_.GetRetransmittableOnWireAlarm()->IsSet());
+
+ // Now receive an ACK of the first packet. This should set the
+ // retransmittable-on-wire alarm now that no retransmittable packets are on
+ // the wire.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
- ProcessAckPacket(&nack);
+ QuicAckFrame frame = InitAckFrame({{1, 2}});
+ ProcessAckPacket(&frame);
+ EXPECT_TRUE(connection_.GetRetransmittableOnWireAlarm()->IsSet());
+ EXPECT_EQ(clock_.ApproximateNow() + retransmittable_on_wire_timeout,
+ connection_.GetRetransmittableOnWireAlarm()->deadline());
+
+ // Before the alarm fires, send another retransmittable packet. This should
+ // cancel the retransmittable-on-wire alarm since now there's a
+ // retransmittable packet on the wire.
+ connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+ offset += data_size;
+ EXPECT_FALSE(connection_.GetRetransmittableOnWireAlarm()->IsSet());
+
+ // Now receive an ACK of the second packet. This should set the
+ // retransmittable-on-wire alarm now that no retransmittable packets are on
+ // the wire.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+ frame = InitAckFrame({{2, 3}});
+ ProcessAckPacket(&frame);
+ EXPECT_TRUE(connection_.GetRetransmittableOnWireAlarm()->IsSet());
+ EXPECT_EQ(clock_.ApproximateNow() + retransmittable_on_wire_timeout,
+ connection_.GetRetransmittableOnWireAlarm()->deadline());
- // Unblock the writer, packet 5 will be sent first, then the window update
- // frame is flushed in a single packet. Finally, packets 1 - 3 are
- // retransmitted.
- writer_->SetWritable();
- if (connection_.session_decides_what_to_write()) {
- // Stream frames 1, 2 and 3 are retransmitted in the same packet.
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
+ // Simulate the alarm firing and check that a PING is sent.
+ writer_->Reset();
+ EXPECT_CALL(visitor_, SendPing()).WillOnce(Invoke([this]() {
+ connection_.SendControlFrame(QuicFrame(QuicPingFrame(1)));
+ }));
+ connection_.GetRetransmittableOnWireAlarm()->Fire();
+ if (GetParam().no_stop_waiting) {
+ EXPECT_EQ(2u, writer_->frame_count());
} else {
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(5);
+ EXPECT_EQ(3u, writer_->frame_count());
}
- connection_.OnCanWrite();
+ ASSERT_EQ(1u, writer_->ping_frames().size());
+}
+
+TEST_P(QuicConnectionTest, OnForwardProgressConfirmed) {
+ EXPECT_CALL(visitor_, OnForwardProgressConfirmed()).Times(Exactly(0));
+ EXPECT_TRUE(connection_.connected());
+
+ const char data[] = "data";
+ size_t data_size = strlen(data);
+ QuicStreamOffset offset = 0;
+
+ // Send two packets.
+ connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+ offset += data_size;
+ connection_.SendStreamDataWithString(1, data, offset, NO_FIN);
+ offset += data_size;
+
+ // Ack packet 1. This increases the largest_acked to 1, so
+ // OnForwardProgressConfirmed() should be called
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+ EXPECT_CALL(visitor_, OnForwardProgressConfirmed());
+ QuicAckFrame frame = InitAckFrame({{1, 2}});
+ ProcessAckPacket(&frame);
+
+ // Ack packet 1 again. largest_acked remains at 1, so
+ // OnForwardProgressConfirmed() should not be called.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ frame = InitAckFrame({{1, 2}});
+ ProcessAckPacket(&frame);
+
+ // Ack packet 2. This increases the largest_acked to 2, so
+ // OnForwardProgressConfirmed() should be called.
+ clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
+ EXPECT_CALL(visitor_, OnForwardProgressConfirmed());
+ frame = InitAckFrame({{2, 3}});
+ ProcessAckPacket(&frame);
+}
+
+TEST_P(QuicConnectionTest, ValidStatelessResetToken) {
+ const uint128 kTestToken = 1010101;
+ const uint128 kWrongTestToken = 1010100;
+ QuicConfig config;
+ // No token has been received.
+ EXPECT_FALSE(connection_.IsValidStatelessResetToken(kTestToken));
+
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(2);
+ // Token is different from received token.
+ QuicConfigPeer::SetReceivedStatelessResetToken(&config, kTestToken);
+ connection_.SetFromConfig(config);
+ EXPECT_FALSE(connection_.IsValidStatelessResetToken(kWrongTestToken));
+
+ QuicConfigPeer::SetReceivedStatelessResetToken(&config, kTestToken);
+ connection_.SetFromConfig(config);
+ EXPECT_TRUE(connection_.IsValidStatelessResetToken(kTestToken));
}
} // namespace
diff --git a/chromium/net/quic/core/quic_constants.h b/chromium/net/quic/core/quic_constants.h
index 4de2bd66b45..e61b4d3d729 100644
--- a/chromium/net/quic/core/quic_constants.h
+++ b/chromium/net/quic/core/quic_constants.h
@@ -115,14 +115,6 @@ const int64_t kMaximumIdleTimeoutSecs = 60 * 10; // 10 minutes.
// The default timeout for a connection until the crypto handshake succeeds.
const int64_t kMaxTimeForCryptoHandshakeSecs = 10; // 10 secs.
-// The default maximum time QUIC session could be on non-default network before
-// migrate back to default network.
-const int64_t kMaxTimeOnNonDefaultNetworkSecs = 128;
-
-// The default maximum number of migrations to non default network on path
-// degrading per network.
-const int64_t kMaxMigrationsToNonDefaultNetworkOnPathDegrading = 5;
-
// Default limit on the number of undecryptable packets the connection buffers
// before the CHLO/SHLO arrive.
const size_t kDefaultMaxUndecryptablePackets = 10;
@@ -213,6 +205,10 @@ const QuicByteCount kMaxStreamLength = (UINT64_C(1) << 62) - 1;
// The max value that can be encoded using IETF Var Ints.
const uint64_t kMaxIetfVarInt = UINT64_C(0x3fffffffffffffff);
+
+// The maximum stream id value that is supported - (2^32)-1
+const QuicStreamId kMaxQuicStreamId = 0xffffffff;
+
} // namespace net
#endif // NET_QUIC_CORE_QUIC_CONSTANTS_H_
diff --git a/chromium/net/quic/core/quic_control_frame_manager.cc b/chromium/net/quic/core/quic_control_frame_manager.cc
index c94d7f75624..a8897fe439c 100644
--- a/chromium/net/quic/core/quic_control_frame_manager.cc
+++ b/chromium/net/quic/core/quic_control_frame_manager.cc
@@ -108,7 +108,7 @@ void QuicControlFrameManager::OnControlFrameSent(const QuicFrame& frame) {
session_->connection()->CloseConnection(
QUIC_INTERNAL_ERROR, "Try to send control frames out of order",
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- RecordInternalErrorLocation(QUIC_CONTROL_FRAME_MANAGER_1);
+ RecordInternalErrorLocation(QUIC_CONTROL_FRAME_MANAGER_CONTROL_FRAME_SENT);
return;
}
++least_unsent_;
@@ -125,7 +125,7 @@ bool QuicControlFrameManager::OnControlFrameAcked(const QuicFrame& frame) {
session_->connection()->CloseConnection(
QUIC_INTERNAL_ERROR, "Try to ack unsent control frame",
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- RecordInternalErrorLocation(QUIC_CONTROL_FRAME_MANAGER_2);
+ RecordInternalErrorLocation(QUIC_CONTROL_FRAME_MANAGER_CONTROL_FRAME_ACKED);
return false;
}
if (id < least_unacked_ ||
@@ -161,7 +161,7 @@ void QuicControlFrameManager::OnControlFrameLost(const QuicFrame& frame) {
session_->connection()->CloseConnection(
QUIC_INTERNAL_ERROR, "Try to mark unsent control frame as lost",
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- RecordInternalErrorLocation(QUIC_CONTROL_FRAME_MANAGER_3);
+ RecordInternalErrorLocation(QUIC_CONTROL_FRAME_MANAGER_CONTROL_FRAME_LOST);
return;
}
if (id < least_unacked_ ||
@@ -225,7 +225,8 @@ bool QuicControlFrameManager::RetransmitControlFrame(const QuicFrame& frame) {
session_->connection()->CloseConnection(
QUIC_INTERNAL_ERROR, "Try to retransmit unsent control frame",
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- RecordInternalErrorLocation(QUIC_CONTROL_FRAME_MANAGER_4);
+ RecordInternalErrorLocation(
+ QUIC_CONTROL_FRAME_MANAGER_RETRANSMIT_CONTROL_FRAME);
return false;
}
if (id < least_unacked_ ||
diff --git a/chromium/net/quic/core/quic_control_frame_manager_test.cc b/chromium/net/quic/core/quic_control_frame_manager_test.cc
index bc2cc32f5a2..51a415b9f44 100644
--- a/chromium/net/quic/core/quic_control_frame_manager_test.cc
+++ b/chromium/net/quic/core/quic_control_frame_manager_test.cc
@@ -37,7 +37,6 @@ class QuicControlFrameManagerTest : public QuicTest {
protected:
void Initialize() {
- SetQuicReloadableFlag(quic_use_control_frame_manager, true);
connection_ = new MockQuicConnection(&helper_, &alarm_factory_,
Perspective::IS_SERVER);
session_ = QuicMakeUnique<StrictMock<MockQuicSession>>(connection_);
diff --git a/chromium/net/quic/core/quic_crypto_client_handshaker.cc b/chromium/net/quic/core/quic_crypto_client_handshaker.cc
index b6f57e4006f..0fe6c37bf80 100644
--- a/chromium/net/quic/core/quic_crypto_client_handshaker.cc
+++ b/chromium/net/quic/core/quic_crypto_client_handshaker.cc
@@ -328,14 +328,14 @@ void QuicCryptoClientHandshaker::DoSendCHLO(
if (max_packet_size <= kFramingOverhead) {
QUIC_DLOG(DFATAL) << "max_packet_length (" << max_packet_size
<< ") has no room for framing overhead.";
- RecordInternalErrorLocation(QUIC_CRYPTO_CLIENT_HANDSHAKER_1);
+ RecordInternalErrorLocation(QUIC_CRYPTO_CLIENT_HANDSHAKER_MAX_PACKET);
stream_->CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
"max_packet_size too smalll");
return;
}
if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) {
QUIC_DLOG(DFATAL) << "Client hello won't fit in a single packet.";
- RecordInternalErrorLocation(QUIC_CRYPTO_CLIENT_HANDSHAKER_2);
+ RecordInternalErrorLocation(QUIC_CRYPTO_CLIENT_HANDSHAKER_CHLO);
stream_->CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
"CHLO too large");
return;
@@ -384,13 +384,13 @@ void QuicCryptoClientHandshaker::DoSendCHLO(
// Be prepared to decrypt with the new server write key.
session()->connection()->SetAlternativeDecrypter(
ENCRYPTION_INITIAL,
- crypto_negotiated_params_->initial_crypters.decrypter.release(),
+ std::move(crypto_negotiated_params_->initial_crypters.decrypter),
true /* latch once used */);
// Send subsequent packets under encryption on the assumption that the
// server will accept the handshake.
session()->connection()->SetEncrypter(
ENCRYPTION_INITIAL,
- crypto_negotiated_params_->initial_crypters.encrypter.release());
+ std::move(crypto_negotiated_params_->initial_crypters.encrypter));
session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
// TODO(ianswett): Merge ENCRYPTION_REESTABLISHED and
@@ -644,10 +644,10 @@ void QuicCryptoClientHandshaker::DoReceiveSHLO(
// with the FORWARD_SECURE key until it receives a FORWARD_SECURE
// packet from the client.
session()->connection()->SetAlternativeDecrypter(
- ENCRYPTION_FORWARD_SECURE, crypters->decrypter.release(),
+ ENCRYPTION_FORWARD_SECURE, std::move(crypters->decrypter),
false /* don't latch */);
session()->connection()->SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- crypters->encrypter.release());
+ std::move(crypters->encrypter));
session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
handshake_confirmed_ = true;
diff --git a/chromium/net/quic/core/quic_crypto_client_stream_test.cc b/chromium/net/quic/core/quic_crypto_client_stream_test.cc
index c62d7528a7e..5ee199732e6 100644
--- a/chromium/net/quic/core/quic_crypto_client_stream_test.cc
+++ b/chromium/net/quic/core/quic_crypto_client_stream_test.cc
@@ -98,6 +98,7 @@ TEST_F(QuicCryptoClientStreamTest, ConnectedAfterSHLO) {
TEST_F(QuicCryptoClientStreamTest, ConnectedAfterTlsHandshake) {
FLAGS_quic_supports_tls_handshake = true;
+ SetQuicReloadableFlag(delay_quic_server_handshaker_construction, true);
supported_versions_.clear();
for (QuicTransportVersion transport_version :
AllSupportedTransportVersions()) {
diff --git a/chromium/net/quic/core/quic_crypto_server_handshaker.cc b/chromium/net/quic/core/quic_crypto_server_handshaker.cc
index f80a1c91ada..351609377ec 100644
--- a/chromium/net/quic/core/quic_crypto_server_handshaker.cc
+++ b/chromium/net/quic/core/quic_crypto_server_handshaker.cc
@@ -225,25 +225,25 @@ void QuicCryptoServerHandshaker::
// NOTE: the SHLO will be encrypted with the new server write key.
session()->connection()->SetEncrypter(
ENCRYPTION_INITIAL,
- crypto_negotiated_params_->initial_crypters.encrypter.release());
+ std::move(crypto_negotiated_params_->initial_crypters.encrypter));
session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
// Set the decrypter immediately so that we no longer accept unencrypted
// packets.
session()->connection()->SetDecrypter(
ENCRYPTION_INITIAL,
- crypto_negotiated_params_->initial_crypters.decrypter.release());
+ std::move(crypto_negotiated_params_->initial_crypters.decrypter));
session()->connection()->SetDiversificationNonce(*diversification_nonce);
SendHandshakeMessage(*reply);
session()->connection()->SetEncrypter(
ENCRYPTION_FORWARD_SECURE,
- crypto_negotiated_params_->forward_secure_crypters.encrypter.release());
+ std::move(crypto_negotiated_params_->forward_secure_crypters.encrypter));
session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
session()->connection()->SetAlternativeDecrypter(
ENCRYPTION_FORWARD_SECURE,
- crypto_negotiated_params_->forward_secure_crypters.decrypter.release(),
+ std::move(crypto_negotiated_params_->forward_secure_crypters.decrypter),
false /* don't latch */);
encryption_established_ = true;
diff --git a/chromium/net/quic/core/quic_crypto_server_stream.cc b/chromium/net/quic/core/quic_crypto_server_stream.cc
index 1dff1316a09..001d4ba6135 100644
--- a/chromium/net/quic/core/quic_crypto_server_stream.cc
+++ b/chromium/net/quic/core/quic_crypto_server_stream.cc
@@ -16,6 +16,7 @@
#include "net/quic/core/quic_packets.h"
#include "net/quic/core/quic_session.h"
#include "net/quic/core/tls_server_handshaker.h"
+#include "net/quic/platform/api/quic_flag_utils.h"
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_logging.h"
#include "net/quic/platform/api/quic_ptr_util.h"
@@ -171,6 +172,8 @@ void QuicCryptoServerStream::OnSuccessfulVersionNegotiation(
if (!delay_handshaker_construction_) {
return;
}
+ QUIC_FLAG_COUNT(
+ quic_reloadable_flag_delay_quic_server_handshaker_construction);
CHECK(!handshaker_);
switch (session()->connection()->version().handshake_protocol) {
case PROTOCOL_QUIC_CRYPTO:
diff --git a/chromium/net/quic/core/quic_crypto_stream.cc b/chromium/net/quic/core/quic_crypto_stream.cc
index 00c3e33d5f5..2b2e70fc893 100644
--- a/chromium/net/quic/core/quic_crypto_stream.cc
+++ b/chromium/net/quic/core/quic_crypto_stream.cc
@@ -23,7 +23,7 @@ namespace net {
" ")
QuicCryptoStream::QuicCryptoStream(QuicSession* session)
- : QuicStream(kCryptoStreamId, session) {
+ : QuicStream(kCryptoStreamId, session, /*is_static=*/true) {
// The crypto stream is exempt from connection level flow control.
DisableConnectionFlowControlForThisStream();
}
diff --git a/chromium/net/quic/core/quic_crypto_stream_test.cc b/chromium/net/quic/core/quic_crypto_stream_test.cc
index 26429163155..01dcc63aabc 100644
--- a/chromium/net/quic/core/quic_crypto_stream_test.cc
+++ b/chromium/net/quic/core/quic_crypto_stream_test.cc
@@ -68,8 +68,10 @@ class QuicCryptoStreamTest : public QuicTest {
: connection_(new MockQuicConnection(&helper_,
&alarm_factory_,
Perspective::IS_CLIENT)),
- session_(connection_),
- stream_(&session_) {
+ session_(connection_, /*create_mock_crypto_stream=*/false) {
+ stream_ = new MockQuicCryptoStream(&session_);
+ session_.SetCryptoStream(stream_);
+ session_.Initialize();
message_.set_tag(kSHLO);
message_.SetStringPiece(1, "abc");
message_.SetStringPiece(2, "def");
@@ -87,7 +89,7 @@ class QuicCryptoStreamTest : public QuicTest {
MockAlarmFactory alarm_factory_;
MockQuicConnection* connection_;
MockQuicSpdySession session_;
- MockQuicCryptoStream stream_;
+ MockQuicCryptoStream* stream_;
CryptoHandshakeMessage message_;
std::unique_ptr<QuicData> message_data_;
@@ -96,16 +98,16 @@ class QuicCryptoStreamTest : public QuicTest {
};
TEST_F(QuicCryptoStreamTest, NotInitiallyConected) {
- EXPECT_FALSE(stream_.encryption_established());
- EXPECT_FALSE(stream_.handshake_confirmed());
+ EXPECT_FALSE(stream_->encryption_established());
+ EXPECT_FALSE(stream_->handshake_confirmed());
}
TEST_F(QuicCryptoStreamTest, ProcessRawData) {
- stream_.OnStreamFrame(QuicStreamFrame(kCryptoStreamId, /*fin=*/false,
- /*offset=*/0,
- message_data_->AsStringPiece()));
- ASSERT_EQ(1u, stream_.messages()->size());
- const CryptoHandshakeMessage& message = (*stream_.messages())[0];
+ stream_->OnStreamFrame(QuicStreamFrame(kCryptoStreamId, /*fin=*/false,
+ /*offset=*/0,
+ message_data_->AsStringPiece()));
+ ASSERT_EQ(1u, stream_->messages()->size());
+ const CryptoHandshakeMessage& message = (*stream_->messages())[0];
EXPECT_EQ(kSHLO, message.tag());
EXPECT_EQ(2u, message.tag_value_map().size());
EXPECT_EQ("abc", crypto_test_utils::GetValueForTag(message, 1));
@@ -122,13 +124,13 @@ TEST_F(QuicCryptoStreamTest, ProcessBadData) {
EXPECT_CALL(*connection_, CloseConnection(QUIC_CRYPTO_TAGS_OUT_OF_ORDER,
testing::_, testing::_));
- stream_.OnStreamFrame(
+ stream_->OnStreamFrame(
QuicStreamFrame(kCryptoStreamId, /*fin=*/false, /*offset=*/0, bad));
}
TEST_F(QuicCryptoStreamTest, NoConnectionLevelFlowControl) {
EXPECT_FALSE(
- QuicStreamPeer::StreamContributesToConnectionFlowControl(&stream_));
+ QuicStreamPeer::StreamContributesToConnectionFlowControl(stream_));
}
TEST_F(QuicCryptoStreamTest, RetransmitCryptoData) {
@@ -138,21 +140,21 @@ TEST_F(QuicCryptoStreamTest, RetransmitCryptoData) {
QuicString data(1350, 'a');
EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 1350, 0, _))
.WillOnce(Invoke(MockQuicSession::ConsumeData));
- stream_.WriteOrBufferData(data, false, nullptr);
+ stream_->WriteOrBufferData(data, false, nullptr);
// Send [1350, 2700) in ENCRYPTION_INITIAL.
connection_->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 1350, 1350, _))
.WillOnce(Invoke(MockQuicSession::ConsumeData));
- stream_.WriteOrBufferData(data, false, nullptr);
+ stream_->WriteOrBufferData(data, false, nullptr);
connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
// Lost [0, 1000).
- stream_.OnStreamFrameLost(0, 1000, false);
- EXPECT_TRUE(stream_.HasPendingRetransmission());
+ stream_->OnStreamFrameLost(0, 1000, false);
+ EXPECT_TRUE(stream_->HasPendingRetransmission());
// Lost [1200, 2000).
- stream_.OnStreamFrameLost(1200, 800, false);
+ stream_->OnStreamFrameLost(1200, 800, false);
EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 1000, 0, _))
.WillOnce(Invoke(MockQuicSession::ConsumeData));
// Verify [1200, 2000) are sent in [1200, 1350) and [1350, 2000) because of
@@ -161,8 +163,8 @@ TEST_F(QuicCryptoStreamTest, RetransmitCryptoData) {
.WillOnce(Invoke(MockQuicSession::ConsumeData));
EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 650, 1350, _))
.WillOnce(Invoke(MockQuicSession::ConsumeData));
- stream_.OnCanWrite();
- EXPECT_FALSE(stream_.HasPendingRetransmission());
+ stream_->OnCanWrite();
+ EXPECT_FALSE(stream_->HasPendingRetransmission());
// Verify connection's encryption level has restored.
EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
}
@@ -173,29 +175,29 @@ TEST_F(QuicCryptoStreamTest, NeuterUnencryptedStreamData) {
QuicString data(1350, 'a');
EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 1350, 0, _))
.WillOnce(Invoke(MockQuicSession::ConsumeData));
- stream_.WriteOrBufferData(data, false, nullptr);
+ stream_->WriteOrBufferData(data, false, nullptr);
// Send [1350, 2700) in ENCRYPTION_INITIAL.
connection_->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 1350, 1350, _))
.WillOnce(Invoke(MockQuicSession::ConsumeData));
- stream_.WriteOrBufferData(data, false, nullptr);
+ stream_->WriteOrBufferData(data, false, nullptr);
// Lost [0, 1350).
- stream_.OnStreamFrameLost(0, 1350, false);
- EXPECT_TRUE(stream_.HasPendingRetransmission());
+ stream_->OnStreamFrameLost(0, 1350, false);
+ EXPECT_TRUE(stream_->HasPendingRetransmission());
// Neuters [0, 1350).
- stream_.NeuterUnencryptedStreamData();
- EXPECT_FALSE(stream_.HasPendingRetransmission());
+ stream_->NeuterUnencryptedStreamData();
+ EXPECT_FALSE(stream_->HasPendingRetransmission());
// Lost [0, 1350) again.
- stream_.OnStreamFrameLost(0, 1350, false);
- EXPECT_FALSE(stream_.HasPendingRetransmission());
+ stream_->OnStreamFrameLost(0, 1350, false);
+ EXPECT_FALSE(stream_->HasPendingRetransmission());
// Lost [1350, 2000).
- stream_.OnStreamFrameLost(1350, 650, false);
- EXPECT_TRUE(stream_.HasPendingRetransmission());
- stream_.NeuterUnencryptedStreamData();
- EXPECT_TRUE(stream_.HasPendingRetransmission());
+ stream_->OnStreamFrameLost(1350, 650, false);
+ EXPECT_TRUE(stream_->HasPendingRetransmission());
+ stream_->NeuterUnencryptedStreamData();
+ EXPECT_TRUE(stream_->HasPendingRetransmission());
}
TEST_F(QuicCryptoStreamTest, RetransmitStreamData) {
@@ -205,27 +207,27 @@ TEST_F(QuicCryptoStreamTest, RetransmitStreamData) {
QuicString data(1350, 'a');
EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 1350, 0, _))
.WillOnce(Invoke(MockQuicSession::ConsumeData));
- stream_.WriteOrBufferData(data, false, nullptr);
+ stream_->WriteOrBufferData(data, false, nullptr);
// Send [1350, 2700) in ENCRYPTION_INITIAL.
connection_->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 1350, 1350, _))
.WillOnce(Invoke(MockQuicSession::ConsumeData));
- stream_.WriteOrBufferData(data, false, nullptr);
+ stream_->WriteOrBufferData(data, false, nullptr);
connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
// Ack [2000, 2500).
- stream_.OnStreamFrameAcked(2000, 500, false, QuicTime::Delta::Zero());
+ stream_->OnStreamFrameAcked(2000, 500, false, QuicTime::Delta::Zero());
// Force crypto stream to send [1350, 2700) and only [1350, 1500) is consumed.
EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 650, 1350, _))
.WillOnce(InvokeWithoutArgs([this]() {
- return MockQuicSession::ConsumeData(&stream_, kCryptoStreamId, 150,
- 1350, NO_FIN);
+ return MockQuicSession::ConsumeData(stream_, kCryptoStreamId, 150, 1350,
+ NO_FIN);
}));
- EXPECT_FALSE(stream_.RetransmitStreamData(1350, 1350, false));
+ EXPECT_FALSE(stream_->RetransmitStreamData(1350, 1350, false));
// Verify connection's encryption level has restored.
EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
@@ -234,13 +236,13 @@ TEST_F(QuicCryptoStreamTest, RetransmitStreamData) {
.WillOnce(Invoke(MockQuicSession::ConsumeData));
EXPECT_CALL(session_, WritevData(_, kCryptoStreamId, 200, 2500, _))
.WillOnce(Invoke(MockQuicSession::ConsumeData));
- EXPECT_TRUE(stream_.RetransmitStreamData(1350, 1350, false));
+ EXPECT_TRUE(stream_->RetransmitStreamData(1350, 1350, false));
// Verify connection's encryption level has restored.
EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
EXPECT_CALL(session_, WritevData(_, _, _, _, _)).Times(0);
// Force to send an empty frame.
- EXPECT_TRUE(stream_.RetransmitStreamData(0, 0, false));
+ EXPECT_TRUE(stream_->RetransmitStreamData(0, 0, false));
}
} // namespace
diff --git a/chromium/net/quic/core/quic_data_reader.cc b/chromium/net/quic/core/quic_data_reader.cc
index 913d3749217..e6c07e8d206 100644
--- a/chromium/net/quic/core/quic_data_reader.cc
+++ b/chromium/net/quic/core/quic_data_reader.cc
@@ -4,7 +4,6 @@
#include "net/quic/core/quic_data_reader.h"
-#include "net/base/int128.h"
#include "net/quic/core/quic_packets.h"
#include "net/quic/core/quic_utils.h"
#include "net/quic/platform/api/quic_bug_tracker.h"
@@ -267,4 +266,17 @@ bool QuicDataReader::ReadVarInt62(uint64_t* result) {
return false;
}
+bool QuicDataReader::ReadVarIntStreamId(QuicStreamId* result) {
+ uint64_t temp_uint64;
+ // TODO(fkastenholz): We should disambiguate read-errors from
+ // value errors.
+ if (!this->ReadVarInt62(&temp_uint64)) {
+ return false;
+ }
+ if (temp_uint64 > kMaxQuicStreamId) {
+ return false;
+ }
+ *result = static_cast<QuicStreamId>(temp_uint64);
+ return true;
+}
} // namespace net
diff --git a/chromium/net/quic/core/quic_data_reader.h b/chromium/net/quic/core/quic_data_reader.h
index cbd23ba8530..f59e5496864 100644
--- a/chromium/net/quic/core/quic_data_reader.h
+++ b/chromium/net/quic/core/quic_data_reader.h
@@ -9,7 +9,6 @@
#include <cstdint>
#include "base/macros.h"
-#include "net/base/int128.h"
#include "net/quic/core/quic_types.h"
#include "net/quic/platform/api/quic_endian.h"
#include "net/quic/platform/api/quic_export.h"
@@ -131,10 +130,16 @@ class QUIC_EXPORT_PRIVATE QuicDataReader {
// Returns true if it works, false if not. The only error is that
// there is not enough in the buffer to read the number.
// If there is an error, |*result| is not altered.
- // Numbers are encoded per the rules in draft-ietf-quic-transport-08.txt
+ // Numbers are encoded per the rules in draft-ietf-quic-transport-10.txt
// and that the integers in the range 0 ... (2^62)-1.
bool ReadVarInt62(uint64_t* result);
+ // Convenience method that reads a StreamId.
+ // Atempts to read a Stream ID into |result| using ReadVarInt62 and
+ // returns false if there is a read error or if the value is
+ // greater than (2^32)-1.
+ bool ReadVarIntStreamId(QuicStreamId* result);
+
private:
// Returns true if the underlying buffer has enough room to read the given
// amount of bytes.
diff --git a/chromium/net/quic/core/quic_data_writer.h b/chromium/net/quic/core/quic_data_writer.h
index b87d151267c..79d05e74c4a 100644
--- a/chromium/net/quic/core/quic_data_writer.h
+++ b/chromium/net/quic/core/quic_data_writer.h
@@ -9,7 +9,6 @@
#include <cstdint>
#include "base/macros.h"
-#include "net/base/int128.h"
#include "net/quic/core/quic_packets.h"
#include "net/quic/platform/api/quic_endian.h"
#include "net/quic/platform/api/quic_export.h"
diff --git a/chromium/net/quic/core/quic_data_writer_test.cc b/chromium/net/quic/core/quic_data_writer_test.cc
index 3e8540c2dfc..f2d8b2d7088 100644
--- a/chromium/net/quic/core/quic_data_writer_test.cc
+++ b/chromium/net/quic/core/quic_data_writer_test.cc
@@ -916,6 +916,49 @@ TEST_P(QuicDataWriterTest, MultiVarInt1) {
EXPECT_FALSE(reader.ReadVarInt62(&test_val));
}
+// Test encoding/decoding stream-id values.
+void EncodeDecodeStreamId(uint64_t value_in, bool expected_decode_result) {
+ char buffer[1 * kMultiVarCount];
+ memset(buffer, 0, sizeof(buffer));
+
+ // Encode the given Stream ID.
+ QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+ Endianness::NETWORK_BYTE_ORDER);
+ EXPECT_TRUE(writer.WriteVarInt62(value_in));
+
+ QuicDataReader reader(buffer, sizeof(buffer), Endianness::NETWORK_BYTE_ORDER);
+ QuicStreamId received_stream_id;
+ bool read_result = reader.ReadVarIntStreamId(&received_stream_id);
+ EXPECT_EQ(expected_decode_result, read_result);
+ if (read_result) {
+ EXPECT_EQ(value_in, received_stream_id);
+ }
+}
+
+// Test writing & reading stream-ids of various value.
+TEST_P(QuicDataWriterTest, StreamId1) {
+ // Check a 1-byte QuicStreamId, should work
+ EncodeDecodeStreamId(UINT64_C(0x15), true);
+
+ // Check a 2-byte QuicStream ID. It should work.
+ EncodeDecodeStreamId(UINT64_C(0x1567), true);
+
+ // Check a QuicStreamId that requires 4 bytes of encoding
+ // This should work.
+ EncodeDecodeStreamId(UINT64_C(0x34567890), true);
+
+ // Check a QuicStreamId that requires 8 bytes of encoding
+ // but whose value is in the acceptable range.
+ // This should work.
+ EncodeDecodeStreamId(UINT64_C(0xf4567890), true);
+
+ // Check QuicStreamIds that require 8 bytes of encoding
+ // and whose value is not acceptable.
+ // This should fail.
+ EncodeDecodeStreamId(UINT64_C(0x100000000), false);
+ EncodeDecodeStreamId(UINT64_C(0x3fffffffffffffff), false);
+}
+
} // namespace
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/core/quic_error_codes.h b/chromium/net/quic/core/quic_error_codes.h
index d79970d811c..88fcca8f2f4 100644
--- a/chromium/net/quic/core/quic_error_codes.h
+++ b/chromium/net/quic/core/quic_error_codes.h
@@ -295,34 +295,35 @@ QUIC_EXPORT_PRIVATE const char* QuicRstStreamErrorCodeToString(
QuicRstStreamErrorCode error);
// Returns the name of the QuicErrorCode as a char*
-QUIC_EXPORT_PRIVATE const char* QuicErrorCodeToString(QuicErrorCode error);
+QUIC_EXPORT const char* QuicErrorCodeToString(QuicErrorCode error);
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
// TODO(rch): Remove this once the cause of the INTERNAL_ERROR increase is
// determined.
enum QuicInternalErrorLocation {
- QUIC_CHROMIUM_CLIENT_SESSION = 0,
- QUIC_CONNECTION_1 = 1,
- QUIC_CONNECTION_2 = 2,
- QUIC_CONNECTION_3 = 3,
- QUIC_CONNECTION_4 = 4,
- QUIC_CONTROL_FRAME_MANAGER_1 = 5,
- QUIC_CONTROL_FRAME_MANAGER_2 = 6,
- QUIC_CONTROL_FRAME_MANAGER_3 = 7,
- QUIC_CONTROL_FRAME_MANAGER_4 = 8,
- QUIC_CRYPTO_CLIENT_HANDSHAKER_1 = 9,
- QUIC_CRYPTO_CLIENT_HANDSHAKER_2 = 10,
+ QUIC_CHROMIUM_CLIENT_SESSION_DESTRUCTOR = 0,
+ QUIC_CONNECTION_PROTOCOL_VERSION_MISMATCH = 1,
+ QUIC_CONNECTION_VERSION_NEGOTIATION_PACKET = 2,
+ QUIC_CONNECTION_UNAUTHENTICATED_HEADER = 3,
+ QUIC_CONNECTION_WRITE_PACKET = 4,
+ QUIC_CONTROL_FRAME_MANAGER_CONTROL_FRAME_SENT = 5,
+ QUIC_CONTROL_FRAME_MANAGER_CONTROL_FRAME_ACKED = 6,
+ QUIC_CONTROL_FRAME_MANAGER_CONTROL_FRAME_LOST = 7,
+ QUIC_CONTROL_FRAME_MANAGER_RETRANSMIT_CONTROL_FRAME = 8,
+ QUIC_CRYPTO_CLIENT_HANDSHAKER_MAX_PACKET = 9,
+ QUIC_CRYPTO_CLIENT_HANDSHAKER_CHLO = 10,
QUIC_ERROR_CODES = 11,
QUIC_FRAMER = 12,
QUIC_HEADERS_STREAM = 13,
- QUIC_SESSION_1 = 14,
- QUIC_SESSION_2 = 15,
- QUIC_SESSION_3 = 16,
+ QUIC_SESSION_ON_CAN_WRITE = 14,
+ QUIC_SESSION_WRITEV_DATA = 15,
+ QUIC_SESSION_STREAM_FRAME_RETRANSMITTED = 16,
QUIC_SPDY_SESSION = 17,
- QUIC_STREAM_1 = 18,
- QUIC_STREAM_2 = 19,
+ QUIC_STREAM_ACKED_UNSENT_DATA = 18,
+ QUIC_STREAM_ACKED_UNSENT_FIN = 19,
QUIC_STREAM_SEQUENCER_BUFFER = 20,
+ QUIC_CHROMIUM_CLIENT_SESSION_CLOSE_SESSION_ON_ERROR = 21,
INTERNAL_ERROR_LOCATION_MAX
};
diff --git a/chromium/net/quic/core/quic_flags_list.h b/chromium/net/quic/core/quic_flags_list.h
index 53c55c2f8df..25235a77f14 100644
--- a/chromium/net/quic/core/quic_flags_list.h
+++ b/chromium/net/quic/core/quic_flags_list.h
@@ -3,7 +3,9 @@
// found in the LICENSE file.
// This file intentionally does not have header guards, it's included
-// inside a macro to generate values.
+// inside a macro to generate values. The following line silences a
+// presubmit warning that would otherwise be triggered by this:
+// no-include-guard-because-multiply-included
// This file contains the list of QUIC protocol flags.
@@ -96,10 +98,6 @@ QUIC_FLAG(uint32_t, FLAGS_quic_send_buffer_max_data_slice_size, 4096u)
// protocol.
QUIC_FLAG(bool, FLAGS_quic_supports_tls_handshake, false)
-// If true, QUIC can take ownership of data provided in a reference counted
-// memory to avoid data copy.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_use_mem_slices, false)
-
// Allow QUIC to accept initial packet numbers that are random, not 1.
QUIC_FLAG(bool, FLAGS_quic_restart_flag_quic_enable_accept_random_ipn, false)
@@ -116,65 +114,133 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_stream_too_long, false)
// TLP instead of 2.
QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_one_tlp, false)
-// If true, QuicStreamSendBuffer keeps track of the slice which next write
-// should get data from if writing new data.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_use_write_index, true)
-
-// If true, when WINDOW_UPDATE is received, add stream to session's write
-// blocked list and let session unblock it later.
-QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_streams_unblocked_by_session2,
- false)
-
-// If true, inspects CHLO packets for indicator tags to allow early session
-// creation.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_inspect_chlo_tags, true)
-
-// When true, ignore the specified ack delay if it causes the RTT sample to be
-// less than min_rtt.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_min_rtt_ack_delay, true)
-
-// If true, plugin control frame manager to QuicSession, and let it manage sent
-// control frames.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_use_control_frame_manager, true)
// When true, allows two connection options to run experiments with using max
// ack delay as described in QUIC IETF.
QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_max_ack_delay, false)
-// If ture, sender will close connection when there are too many outstanding
-// sent packets
-QUIC_FLAG(
- bool,
- FLAGS_quic_reloadable_flag_quic_close_session_on_too_many_outstanding_sent_packets,
- false)
-
// If true, enable QUIC v99.
QUIC_FLAG(bool, FLAGS_quic_enable_version_99, false)
// If true, enable QUIC version 42.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_42_2, false)
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_42_2, true)
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_37, false)
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_38, false)
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_37, true)
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_38, true)
QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_41, false)
// Delays construction of QuicCryptoServerStream::HandshakerDelegate
// until QuicCryptoServerStream::OnSuccessfulVersionNegotiation is called
QUIC_FLAG(bool,
FLAGS_quic_reloadable_flag_delay_quic_server_handshaker_construction,
- false)
+ true)
// Controls whether QuicConnection::OnProtocolVersionMismatch calls
// QuicFramer::set_version before or after calling
// OnSuccessfulVersionNegotiation.
QUIC_FLAG(bool,
FLAGS_quic_reloadable_flag_quic_store_version_before_signalling,
- false)
+ true)
// When true, enable connection options to have no min TLP and RTO,
// and also allow IETF style TLP.
QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_max_ack_delay2, false)
+// If true, MemSlices in the send buffer is freed out of order.
+QUIC_FLAG(bool,
+ FLAGS_quic_reloadable_flag_quic_free_mem_slice_out_of_order,
+ false)
+
// If true, framer will process and report ack frame incrementally.
QUIC_FLAG(bool,
- FLAGS_quic_reloadable_flag_quic_use_incremental_ack_processing,
- false) \ No newline at end of file
+ FLAGS_quic_reloadable_flag_quic_use_incremental_ack_processing3,
+ false)
+
+// If true, Http2FrameDecoderAdapter will pass decoded HTTP/2 SETTINGS through
+// the SpdyFramerVisitorInterface callback OnSetting(), which will also accept
+// unknown SETTINGS IDs.
+QUIC_FLAG(bool, FLAGS_quic_restart_flag_http2_propagate_unknown_settings, true)
+
+// If true, enable fast path in QuicStream::OnStreamDataAcked.
+QUIC_FLAG(bool,
+ FLAGS_quic_reloadable_flag_quic_fast_path_on_stream_data_acked,
+ false)
+
+// If true, fix a use-after-free bug caused by writing an out-of-order queued
+// packet.
+QUIC_FLAG(
+ bool,
+ FLAGS_quic_reloadable_flag_quic_fix_write_out_of_order_queued_packet_crash,
+ true)
+
+// If true, QUIC streams are registered in the QuicStream constructor instead
+// of in the QuicSpdyStream constructor.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_register_streams_early2, true)
+
+// If this flag and
+// FLAGS_quic_reloadable_flag_quic_fix_write_out_of_order_queued_packet_crash
+// are both ture, QUIC will clear queued packets before sending connectivity
+// probing packets.
+QUIC_FLAG(
+ bool,
+ FLAGS_quic_reloadable_flag_quic_clear_queued_packets_before_sending_connectivity_probing,
+ false)
+
+// When true, this flag has QuicConnection call
+// QuicConnectionVisitorInterface::OnSuccessfulVersionNegotiation earlier when
+// processing the packet header.
+QUIC_FLAG(bool,
+ FLAGS_quic_reloadable_flag_quic_server_early_version_negotiation,
+ false)
+
+// If true, QUIC will always discard outgoing packets after connection close.
+// Currently out-of-order outgoing packets are not discarded
+QUIC_FLAG(bool,
+ FLAGS_quic_reloadable_flag_quic_always_discard_packets_after_close,
+ false)
+
+// If true, stop sending a redundant PING every 20 acks.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_remove_redundant_ping, true)
+
+// If true, when a stream is reset by peer with error, it should not be added to
+// zombie streams.
+QUIC_FLAG(bool,
+ FLAGS_quic_reloadable_flag_quic_reset_stream_is_not_zombie,
+ true)
+
+// If true, when a packet write for connectivity probe does not complete
+// successfully synchronously, connection will not be affected, i.e., blocked or
+// closed, if the probing packet writer is not the default writer.
+QUIC_FLAG(
+ bool,
+ FLAGS_quic_reloadable_flag_quic_handle_write_results_for_connectivity_probe,
+ true)
+
+// If true, a separate QuicAlarm in QuicConnection is used to trigger
+// OnPathDegrading() instead of using retransmission_alarm_.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_path_degrading_alarm, true)
+
+// Remove special logic for headers stream from QuicWriteBlockedList and
+// replace it with a static streams map.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_register_static_streams, false)
+
+// Base the QUIC crypto retransmission timer on the last sent crypto packet.
+QUIC_FLAG(bool,
+ FLAGS_quic_reloadable_flag_quic_better_crypto_retransmission,
+ false)
+
+// If true, enable server proxy support in QUIC.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_server_proxy, false)
+
+// If true, compare offset with last byte acked to determine whether it is
+// disjoint before calling IntervalSet::IsDisjoint.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fast_is_disjoint, false)
+
+// If true, enable fast path in QuicStreamSequencerBuffer::OnStreamData.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fast_path_on_stream_data, false)
+
+// When true, set the initial congestion control window from connection options
+// in QuicSentPacketManager rather than TcpCubicSenderBytes.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_unified_iw_options, false)
+
+// If true, check again that the writer isn\'t blocked before calling
+// QuicConnection::OnCanWrite from WriteAndBundleAcksIfNotBlocked
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_is_write_blocked, true)
diff --git a/chromium/net/quic/core/quic_flow_controller.cc b/chromium/net/quic/core/quic_flow_controller.cc
index 91f0c9f2889..a5e18a6faea 100644
--- a/chromium/net/quic/core/quic_flow_controller.cc
+++ b/chromium/net/quic/core/quic_flow_controller.cc
@@ -231,11 +231,7 @@ void QuicFlowController::MaybeSendBlocked() {
<< ", send limit: " << send_window_offset_;
// The entire send_window has been consumed, we are now flow control
// blocked.
- if (session_->use_control_frame_manager()) {
- session_->SendBlocked(id_);
- } else {
- connection_->SendBlocked(id_);
- }
+ session_->SendBlocked(id_);
// Keep track of when we last sent a BLOCKED frame so that we only send one
// at a given send offset.
@@ -298,11 +294,7 @@ void QuicFlowController::UpdateReceiveWindowSize(QuicStreamOffset size) {
}
void QuicFlowController::SendWindowUpdate() {
- if (session_->use_control_frame_manager()) {
- session_->SendWindowUpdate(id_, receive_window_offset_);
- return;
- }
- connection_->SendWindowUpdate(id_, receive_window_offset_);
+ session_->SendWindowUpdate(id_, receive_window_offset_);
}
} // namespace net
diff --git a/chromium/net/quic/core/quic_flow_controller_test.cc b/chromium/net/quic/core/quic_flow_controller_test.cc
index e50281707d4..aedc076f016 100644
--- a/chromium/net/quic/core/quic_flow_controller_test.cc
+++ b/chromium/net/quic/core/quic_flow_controller_test.cc
@@ -81,11 +81,7 @@ TEST_F(QuicFlowControllerTest, SendingBytes) {
EXPECT_EQ(0u, flow_controller_->SendWindowSize());
// BLOCKED frame should get sent.
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
- } else {
- EXPECT_CALL(*connection_, SendBlocked(stream_id_)).Times(1);
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
flow_controller_->MaybeSendBlocked();
// Update the send window, and verify this has unblocked.
@@ -124,12 +120,7 @@ TEST_F(QuicFlowControllerTest, ReceivingBytes) {
QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get()));
// Consume enough bytes to send a WINDOW_UPDATE frame.
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
- } else {
- EXPECT_CALL(*connection_, SendWindowUpdate(stream_id_, ::testing::_))
- .Times(1);
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
flow_controller_->AddBytesConsumed(1 + receive_window_ / 2);
@@ -154,14 +145,9 @@ TEST_F(QuicFlowControllerTest, OnlySendBlockedFrameOncePerOffset) {
EXPECT_EQ(0u, flow_controller_->SendWindowSize());
// Expect that 2 BLOCKED frames should get sent in total.
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(2)
- .WillRepeatedly(
- Invoke(this, &QuicFlowControllerTest::ClearControlFrame));
- } else {
- EXPECT_CALL(*connection_, SendBlocked(stream_id_)).Times(2);
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(this, &QuicFlowControllerTest::ClearControlFrame));
// BLOCKED frame should get sent.
flow_controller_->MaybeSendBlocked();
@@ -189,12 +175,7 @@ TEST_F(QuicFlowControllerTest, ReceivingBytesFastIncreasesFlowWindow) {
should_auto_tune_receive_window_ = true;
Initialize();
// This test will generate two WINDOW_UPDATE frames.
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
- } else {
- EXPECT_CALL(*connection_, SendWindowUpdate(stream_id_, ::testing::_))
- .Times(1);
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
EXPECT_TRUE(flow_controller_->auto_tune_receive_window());
// Make sure clock is inititialized.
@@ -246,15 +227,9 @@ TEST_F(QuicFlowControllerTest, ReceivingBytesFastIncreasesFlowWindow) {
TEST_F(QuicFlowControllerTest, ReceivingBytesFastNoAutoTune) {
Initialize();
// This test will generate two WINDOW_UPDATE frames.
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(2)
- .WillRepeatedly(
- Invoke(this, &QuicFlowControllerTest::ClearControlFrame));
- } else {
- EXPECT_CALL(*connection_, SendWindowUpdate(stream_id_, ::testing::_))
- .Times(2);
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(this, &QuicFlowControllerTest::ClearControlFrame));
EXPECT_FALSE(flow_controller_->auto_tune_receive_window());
// Make sure clock is inititialized.
@@ -307,12 +282,7 @@ TEST_F(QuicFlowControllerTest, ReceivingBytesNormalStableFlowWindow) {
should_auto_tune_receive_window_ = true;
Initialize();
// This test will generate two WINDOW_UPDATE frames.
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
- } else {
- EXPECT_CALL(*connection_, SendWindowUpdate(stream_id_, ::testing::_))
- .Times(1);
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
EXPECT_TRUE(flow_controller_->auto_tune_receive_window());
// Make sure clock is inititialized.
@@ -367,15 +337,9 @@ TEST_F(QuicFlowControllerTest, ReceivingBytesNormalStableFlowWindow) {
TEST_F(QuicFlowControllerTest, ReceivingBytesNormalNoAutoTune) {
Initialize();
// This test will generate two WINDOW_UPDATE frames.
- if (connection_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(2)
- .WillRepeatedly(
- Invoke(this, &QuicFlowControllerTest::ClearControlFrame));
- } else {
- EXPECT_CALL(*connection_, SendWindowUpdate(stream_id_, ::testing::_))
- .Times(2);
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(this, &QuicFlowControllerTest::ClearControlFrame));
EXPECT_FALSE(flow_controller_->auto_tune_receive_window());
// Make sure clock is inititialized.
diff --git a/chromium/net/quic/core/quic_framer.cc b/chromium/net/quic/core/quic_framer.cc
index 45e6035beb8..7c0a19a3ff1 100644
--- a/chromium/net/quic/core/quic_framer.cc
+++ b/chromium/net/quic/core/quic_framer.cc
@@ -32,6 +32,7 @@
#include "net/quic/platform/api/quic_string.h"
#include "net/quic/platform/api/quic_text_utils.h"
+using std::string;
namespace net {
@@ -172,6 +173,7 @@ QuicFramer::QuicFramer(const ParsedQuicVersionVector& supported_versions,
largest_packet_number_(0),
last_serialized_connection_id_(0),
last_version_label_(0),
+ last_packet_is_ietf_quic_(false),
version_(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED),
supported_versions_(supported_versions),
decrypter_level_(ENCRYPTION_NONE),
@@ -183,9 +185,9 @@ QuicFramer::QuicFramer(const ParsedQuicVersionVector& supported_versions,
last_timestamp_(QuicTime::Delta::Zero()),
data_producer_(nullptr),
use_incremental_ack_processing_(
- GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
+ GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
if (use_incremental_ack_processing_) {
- QUIC_FLAG_COUNT(quic_reloadable_flag_quic_use_incremental_ack_processing);
+ QUIC_FLAG_COUNT(quic_reloadable_flag_quic_use_incremental_ack_processing3);
}
DCHECK(!supported_versions.empty());
version_ = supported_versions_[0];
@@ -557,6 +559,7 @@ std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildPublicResetPacket(
// static
std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildVersionNegotiationPacket(
QuicConnectionId connection_id,
+ bool ietf_quic,
const ParsedQuicVersionVector& versions) {
DCHECK(!versions.empty());
size_t len = GetVersionNegotiationPacketSize(versions.size());
@@ -592,6 +595,7 @@ std::unique_ptr<QuicEncryptedPacket> QuicFramer::BuildVersionNegotiationPacket(
bool QuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) {
QuicDataReader reader(packet.data(), packet.length(), endianness());
+ last_packet_is_ietf_quic_ = false;
visitor_->OnPacket();
QuicPacketHeader header;
@@ -1091,7 +1095,7 @@ bool QuicFramer::ProcessFrameData(QuicDataReader* reader,
((frame_type & kQuicFrameTypeSpecialMask) ==
kQuicFrameTypeAckMask))) {
// TODO(fayang): Remove frame when deprecating
- // quic_reloadable_flag_quic_use_incremental_ack_processing.
+ // quic_reloadable_flag_quic_use_incremental_ack_processing3.
QuicAckFrame frame;
if (!ProcessAckFrame(reader, frame_type, &frame)) {
return RaiseError(QUIC_INVALID_ACK_DATA);
@@ -1341,25 +1345,17 @@ bool QuicFramer::ProcessIetfStreamFrame(QuicDataReader* reader,
uint8_t frame_type,
QuicStreamFrame* frame) {
// Read stream id from the frame. It's always present.
- QuicIetfStreamId streamid;
- if (!reader->ReadVarInt62(&streamid)) {
+ if (!reader->ReadVarIntStreamId(&frame->stream_id)) {
set_detailed_error("Unable to read stream_id.");
return false;
}
- if (streamid > 0xffffffff) {
- set_detailed_error("stream_id is too large.");
- return false;
- }
- frame->stream_id = static_cast<QuicStreamId>(streamid);
// If we have a data offset, read it. If not, set to 0.
if (frame_type & IETF_STREAM_FRAME_OFF_BIT) {
- QuicStreamOffset offset;
- if (!reader->ReadVarInt62(&offset)) {
+ if (!reader->ReadVarInt62(&frame->offset)) {
set_detailed_error("Unable to read stream data offset.");
return false;
}
- frame->offset = offset;
} else {
// no offset in the frame, ensure it's 0 in the Frame.
frame->offset = 0;
@@ -1373,7 +1369,7 @@ bool QuicFramer::ProcessIetfStreamFrame(QuicDataReader* reader,
return false;
}
if (length > 0xffff) {
- set_detailed_error("stream data offset is too large.");
+ set_detailed_error("Stream data length is too large.");
return false;
}
frame->data_length = length;
@@ -1593,8 +1589,8 @@ bool QuicFramer::ProcessTimestampsInAckFrame(uint8_t num_received_packets,
last_timestamp_ = CalculateTimestampFromWire(time_delta_us);
ack_frame->received_packet_times.reserve(num_received_packets);
- ack_frame->received_packet_times.push_back(
- std::make_pair(seq_num, creation_time_ + last_timestamp_));
+ ack_frame->received_packet_times.emplace_back(
+ seq_num, creation_time_ + last_timestamp_);
for (uint8_t i = 1; i < num_received_packets; ++i) {
if (!reader->ReadUInt8(&delta_from_largest_observed)) {
@@ -1614,8 +1610,8 @@ bool QuicFramer::ProcessTimestampsInAckFrame(uint8_t num_received_packets,
last_timestamp_ = last_timestamp_ + QuicTime::Delta::FromMicroseconds(
incremental_time_delta_us);
- ack_frame->received_packet_times.push_back(
- std::make_pair(seq_num, creation_time_ + last_timestamp_));
+ ack_frame->received_packet_times.emplace_back(
+ seq_num, creation_time_ + last_timestamp_);
}
}
return true;
@@ -1771,7 +1767,7 @@ bool QuicFramer::ProcessConnectionCloseFrame(QuicDataReader* reader,
set_detailed_error("Unable to read connection close error details.");
return false;
}
- frame->error_details = error_details.as_string();
+ frame->error_details = string(error_details);
return true;
}
@@ -1802,7 +1798,7 @@ bool QuicFramer::ProcessGoAwayFrame(QuicDataReader* reader,
set_detailed_error("Unable to read goaway reason.");
return false;
}
- frame->reason_phrase = reason_phrase.as_string();
+ frame->reason_phrase = string(reason_phrase);
return true;
}
@@ -1865,17 +1861,19 @@ QuicStringPiece QuicFramer::GetAssociatedDataFromEncryptedPacket(
packet_number_length));
}
-void QuicFramer::SetDecrypter(EncryptionLevel level, QuicDecrypter* decrypter) {
+void QuicFramer::SetDecrypter(EncryptionLevel level,
+ std::unique_ptr<QuicDecrypter> decrypter) {
DCHECK(alternative_decrypter_ == nullptr);
DCHECK_GE(level, decrypter_level_);
- decrypter_.reset(decrypter);
+ decrypter_ = std::move(decrypter);
decrypter_level_ = level;
}
-void QuicFramer::SetAlternativeDecrypter(EncryptionLevel level,
- QuicDecrypter* decrypter,
- bool latch_once_used) {
- alternative_decrypter_.reset(decrypter);
+void QuicFramer::SetAlternativeDecrypter(
+ EncryptionLevel level,
+ std::unique_ptr<QuicDecrypter> decrypter,
+ bool latch_once_used) {
+ alternative_decrypter_ = std::move(decrypter);
alternative_decrypter_level_ = level;
alternative_decrypter_latch_ = latch_once_used;
}
@@ -1888,10 +1886,11 @@ const QuicDecrypter* QuicFramer::alternative_decrypter() const {
return alternative_decrypter_.get();
}
-void QuicFramer::SetEncrypter(EncryptionLevel level, QuicEncrypter* encrypter) {
+void QuicFramer::SetEncrypter(EncryptionLevel level,
+ std::unique_ptr<QuicEncrypter> encrypter) {
DCHECK_GE(level, 0);
DCHECK_LT(level, NUM_ENCRYPTION_LEVELS);
- encrypter_[level].reset(encrypter);
+ encrypter_[level] = std::move(encrypter);
}
size_t QuicFramer::EncryptInPlace(EncryptionLevel level,
@@ -2304,20 +2303,20 @@ bool QuicFramer::AppendIetfStreamFrame(const QuicStreamFrame& frame,
}
// Put the type-byte in the header.
- if (writer->WriteUInt8(frame_type) == false) {
+ if (!writer->WriteUInt8(frame_type)) {
set_detailed_error("Unable to write frame-type.");
return false;
}
// Stream ID always goes in the header...
- if (writer->WriteVarInt62(static_cast<uint64_t>(frame.stream_id)) == false) {
+ if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.stream_id))) {
set_detailed_error("Writing stream id failed.");
return false;
}
// Offset may go in the header...
if (frame_type & IETF_STREAM_FRAME_OFF_BIT) {
- if (writer->WriteVarInt62(static_cast<uint64_t>(frame.offset)) == false) {
+ if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.offset))) {
set_detailed_error("Writing data offset failed.");
return false;
}
@@ -2325,7 +2324,7 @@ bool QuicFramer::AppendIetfStreamFrame(const QuicStreamFrame& frame,
// Frame data length...
if (frame_type & IETF_STREAM_FRAME_LEN_BIT) {
- if (writer->WriteVarInt62(frame.data_length) == false) {
+ if (!writer->WriteVarInt62(frame.data_length)) {
set_detailed_error("Writing data length failed.");
return false;
}
@@ -2621,6 +2620,7 @@ bool QuicFramer::AppendStopWaitingFrame(const QuicPacketHeader& header,
return true;
}
+
// Append IETF Format Ack Frame. The IETF Ack Frame format is, basically,
// Largest Ack'ed
// ACK Delay
@@ -2633,8 +2633,8 @@ bool QuicFramer::AppendStopWaitingFrame(const QuicPacketHeader& header,
// 1-packet-acked, 1-packet-gap, 1-packet-acked & the first
// packet has seq# LargestAcked, the last one has seq# LargestAcked-4.
-bool QuicFramer::AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
- QuicDataWriter* writer) {
+bool QuicFramer::AppendIetfAckFrame(const QuicAckFrame& frame,
+ QuicDataWriter* writer) {
if (!writer->WriteUInt8(IETF_ACK)) {
set_detailed_error("No room for frame-type");
return false;
@@ -2654,40 +2654,33 @@ bool QuicFramer::AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
DCHECK_LE(0u, frame.ack_delay_time.ToMicroseconds());
ack_delay_time_us = frame.ack_delay_time.ToMicroseconds();
- // TODO(fkastenholz) when we get real IETF QUIC, need to get
- // the currect shift from the transport parameters.
+ // TODO(fkastenholz): Use the shift from TLS transport parameters.
ack_delay_time_us = ack_delay_time_us >> kIetfAckTimestampShift;
if (!writer->WriteVarInt62(ack_delay_time_us)) {
set_detailed_error("No room for ack-delay in ack frame");
return false;
}
- // Do the block-count
uint64_t ack_block_count = frame.packets.NumIntervals();
if (ack_block_count == 0) {
QUIC_BUG << "Trying to build an ack frame with no ack blocks";
return false;
}
- // Calculate the block count we will put into the frame.
- // ID says the value is "The number of Additional ACK Block (and
- // Gap) fields after the First ACK Block." We interpret this as
- // - n(==0) means just the First ACK Block
- // - n(>0) means a First Ack block followed by N pairs
- // of Gap/Ack. So if N is 1, there is a First,
- // a Gap, and a final Ack.
+ // Subtract 1 from the block count when writing because the specification
+ // does not allow for 0 blocks.
if (!writer->WriteVarInt62(ack_block_count - 1)) {
set_detailed_error("No room for ack block count in ack frame");
return false;
}
- auto itr = frame.packets.rbegin(); // first range
- // Do the first block.
+ auto itr = frame.packets.rbegin();
+ // Write the first block.
// The ranges in frame.packets are [low...high), so
- // a) we should never see 0 and
- // b) we need to subtract 1 when writing the value out.
+ // a) 0 is invalid
+ // b) Subtract 1 when writing the value out.
uint64_t block_length = itr->max() - itr->min();
if (block_length == 0) {
- QUIC_BUG << "Have a 0-length range in QuicAckFrame::packets";
+ QUIC_BUG << "0-length range in QuicAckFrame::packets";
return false;
}
@@ -2698,31 +2691,18 @@ bool QuicFramer::AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
size_t previous_ack_end = itr->min();
ack_block_count--;
- // TODO(fkastenholz) this loop adds all blocks to the frame,
- // failing if the frame buffer is not large enough. In the future,
- // we should put in as many as we can, adjusting the count to
- // indicate just what we put in. Or at least have an option to do this.
+ // TODO(fkastenholz): Allow this code to write fewer ack blocks when it runs
+ // out of space in the packet.
while (ack_block_count) {
- // Do the gap separating the two ack-blocks
- // Math note: value of the gap is nr of packets separating the two
- // acks. If we have two sets of ack'd packets, 1,2,3 and 7,8,...x
- // A) The gap size is 3 (the gap is packets 4,5,6), which is
- // encoded in the frame as 2.
- // B) The two frame.packets ranges are [1,4) and [7,x) so the
- // gap calculation is (7-4)-1 ==> (3)-1 ==> 2.
-
- // next range
+ // Determine the number of packets between ack-blocks.
itr++;
-
- // Mind the gap
size_t gap = previous_ack_end - itr->max() - 1;
-
if (!writer->WriteVarInt62(gap)) {
set_detailed_error("No room for gap block in ack frame");
return false;
}
- // Add the ack-block (itr already points to it)
+ // Add the ack-block.
block_length = itr->max() - itr->min();
if (block_length == 0) {
QUIC_BUG << "Have a 0-length range in QuicAckFrame::packets";
@@ -2880,14 +2860,6 @@ bool QuicFramer::AppendIetfConnectionCloseFrame(
frame.error_details, writer);
}
-bool QuicFramer::AppendIetfConnectionCloseFrame(
- const QuicIetfTransportErrorCodes code,
- const QuicString& phrase,
- QuicDataWriter* writer) {
- return AppendIetfCloseFrame(
- IETF_CONNECTION_CLOSE, static_cast<const uint16_t>(code), phrase, writer);
-}
-
bool QuicFramer::AppendIetfApplicationCloseFrame(
const QuicConnectionCloseFrame& frame,
QuicDataWriter* writer) {
@@ -2895,11 +2867,7 @@ bool QuicFramer::AppendIetfApplicationCloseFrame(
static_cast<const uint16_t>(frame.error_code),
frame.error_details, writer);
}
-bool QuicFramer::AppendIetfApplicationCloseFrame(const uint16_t code,
- const QuicString& phrase,
- QuicDataWriter* writer) {
- return AppendIetfCloseFrame(IETF_APPLICATION_CLOSE, code, phrase, writer);
-}
+
// Generate either an IETF-Connection- or IETF-Application-close frame.
// General format is
// type-byte
@@ -2945,18 +2913,20 @@ bool QuicFramer::ProcessIetfConnectionCloseFrame(
QuicConnectionCloseFrame* frame) {
return ProcessIetfCloseFrame(reader, frame_type, frame);
}
+
bool QuicFramer::ProcessIetfApplicationCloseFrame(
QuicDataReader* reader,
const uint8_t frame_type,
QuicConnectionCloseFrame* frame) {
return ProcessIetfCloseFrame(reader, frame_type, frame);
}
+
bool QuicFramer::ProcessIetfCloseFrame(QuicDataReader* reader,
const uint8_t frame_type,
QuicConnectionCloseFrame* frame) {
uint16_t code;
if (!reader->ReadUInt16(&code)) {
- set_detailed_error("Unable to read clode frame code.");
+ set_detailed_error("Unable to read close frame code.");
return false;
}
frame->error_code = static_cast<QuicErrorCode>(code);
@@ -2971,8 +2941,324 @@ bool QuicFramer::ProcessIetfCloseFrame(QuicDataReader* reader,
set_detailed_error("Can not read extended close information phrase");
return false;
}
- frame->error_details = phrase.as_string();
+ frame->error_details = string(phrase);
+
+ return true;
+}
+
+// IETF-format Padding frames.
+// Padding is just N bytes of 0x00. There is no varint62/etc
+// encoding required.
+bool QuicFramer::AppendIetfPaddingFrame(const QuicPaddingFrame& frame,
+ QuicDataWriter* writer) {
+ DCHECK_GT(version_.transport_version, QUIC_VERSION_37);
+ // The base AppendPaddingFrame assumes that the type byte has
+ // been written. It will actually write num_padding_bytes-1
+ // bytes. This takes care of that issue.
+ if (!writer->WriteUInt8(0)) {
+ set_detailed_error("Can not write close frame type byte");
+ return false;
+ }
+ return AppendPaddingFrame(frame, writer);
+}
+
+// Read the padding. Has to do it one byte at a time, stopping
+// when we either A) reach the end of the buffer or B) reach a
+// non-0x00 byte.
+void QuicFramer::ProcessIetfPaddingFrame(QuicDataReader* reader,
+ QuicPaddingFrame* frame) {
+ DCHECK_GT(version_.transport_version, QUIC_VERSION_37);
+ ProcessPaddingFrame(reader, frame);
+}
+
+// IETF Quic Path Challenge/Response frames.
+bool QuicFramer::ProcessIetfPathChallengeFrame(QuicDataReader* reader,
+ QuicPathChallengeFrame* frame) {
+ if (!reader->ReadBytes(frame->data_buffer.data(), kQuicPathFrameBufferSize)) {
+ set_detailed_error("Can not read path Challenge data");
+ return false;
+ }
+ return true;
+}
+
+bool QuicFramer::ProcessIetfPathResponseFrame(QuicDataReader* reader,
+ QuicPathResponseFrame* frame) {
+ if (!reader->ReadBytes(frame->data_buffer.data(), kQuicPathFrameBufferSize)) {
+ set_detailed_error("Can not read path Response data");
+ return false;
+ }
+ return true;
+}
+
+bool QuicFramer::AppendIetfPathChallengeFrame(
+ const QuicPathChallengeFrame& frame,
+ QuicDataWriter* writer) {
+ if (!writer->WriteUInt8(IETF_PATH_CHALLENGE)) {
+ set_detailed_error("Can not write Path Challenge frame type byte");
+ return false;
+ }
+
+ if (!writer->WriteBytes(frame.data_buffer.data(), kQuicPathFrameBufferSize)) {
+ set_detailed_error("Writing Path Challenge data failed.");
+ return false;
+ }
+ return true;
+}
+
+bool QuicFramer::AppendIetfPathResponseFrame(const QuicPathResponseFrame& frame,
+ QuicDataWriter* writer) {
+ if (!writer->WriteUInt8(IETF_PATH_RESPONSE)) {
+ set_detailed_error("Can not write Path Response frame type byte");
+ return false;
+ }
+
+ if (!writer->WriteBytes(frame.data_buffer.data(), kQuicPathFrameBufferSize)) {
+ set_detailed_error("Writing Path Response data failed.");
+ return false;
+ }
+ return true;
+}
+
+// Add a new ietf-format stream reset frame.
+// General format is
+// stream id
+// application error code
+// final offset
+bool QuicFramer::AppendIetfResetStreamFrame(const QuicRstStreamFrame& frame,
+ QuicDataWriter* writer) {
+ // Put the type-byte in the header.
+ if (!writer->WriteUInt8(QuicIetfFrameType::IETF_RST_STREAM)) {
+ set_detailed_error("Unable to write reset-stream frame-type.");
+ return false;
+ }
+ if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.stream_id))) {
+ set_detailed_error("Writing reset-stream stream id failed.");
+ return false;
+ }
+ if (!writer->WriteUInt16(static_cast<uint16_t>(frame.error_code))) {
+ set_detailed_error("Writing reset-stream error code failed.");
+ return false;
+ }
+ if (!writer->WriteVarInt62(static_cast<uint64_t>(frame.byte_offset))) {
+ set_detailed_error("Writing reset-stream final-offset failed.");
+ return false;
+ }
+ return true;
+}
+
+bool QuicFramer::ProcessIetfResetStreamFrame(QuicDataReader* reader,
+ QuicRstStreamFrame* frame) {
+ // Get Stream ID from frame. ReadVarIntStreamID returns false
+ // if either A) there is a read error or B) the resulting value of
+ // the Stream ID is larger than the maximum allowed value.
+ if (!reader->ReadVarIntStreamId(&frame->stream_id)) {
+ set_detailed_error("Reading reset-stream stream id failed.");
+ return false;
+ }
+
+ uint16_t temp_uint16;
+ if (!reader->ReadUInt16(&temp_uint16)) {
+ set_detailed_error("Reading reset-stream error code failed.");
+ return false;
+ }
+ frame->error_code = static_cast<QuicRstStreamErrorCode>(temp_uint16);
+ if (!reader->ReadVarInt62(&frame->byte_offset)) {
+ set_detailed_error("Reading reset-stream final-offset failed.");
+ return false;
+ }
+ return true;
+}
+
+bool QuicFramer::ProcessIetfStopSendingFrame(
+ QuicDataReader* reader,
+ QuicStopSendingFrame* stop_sending_frame) {
+ if (!reader->ReadVarIntStreamId(&stop_sending_frame->stream_id)) {
+ set_detailed_error("Unable to read stream id");
+ return false;
+ }
+
+ if (!reader->ReadUInt16(&stop_sending_frame->application_error_code)) {
+ set_detailed_error("Unable to read application error code.");
+ return false;
+ }
+ return true;
+}
+
+bool QuicFramer::AppendIetfStopSendingFrame(
+ const QuicStopSendingFrame& stop_sending_frame,
+ QuicDataWriter* writer) {
+ if (!writer->WriteUInt8(IETF_STOP_SENDING)) {
+ set_detailed_error("Can not write stop sending frame type byte");
+ return false;
+ }
+ if (!writer->WriteVarInt62(stop_sending_frame.stream_id)) {
+ set_detailed_error("Can not write stop sending stream id");
+ return false;
+ }
+ if (!writer->WriteUInt16(stop_sending_frame.application_error_code)) {
+ set_detailed_error("Can not write application error code");
+ return false;
+ }
+ return true;
+}
+
+// Append/process IETF-Format MAX_DATA Frame
+// MAX_DATA format is a single number, the maximum number of bytes
+// that can be accepted on the connection.
+bool QuicFramer::AppendIetfMaxDataFrame(const QuicWindowUpdateFrame& frame,
+ QuicDataWriter* writer) {
+ if (!writer->WriteUInt8(IETF_MAX_DATA)) {
+ set_detailed_error("Can not write IETF_MAX_DATA frame type byte");
+ return false;
+ }
+ if (!writer->WriteVarInt62(frame.byte_offset)) {
+ set_detailed_error("Can not write IETF_MAX_DATA byte-offset");
+ return false;
+ }
+ return true;
+}
+
+bool QuicFramer::ProcessIetfMaxDataFrame(QuicDataReader* reader,
+ QuicWindowUpdateFrame* frame) {
+ frame->stream_id = 0;
+ if (!reader->ReadVarInt62(&frame->byte_offset)) {
+ set_detailed_error("Can not read IETF_MAX_DATA byte-offset");
+ return false;
+ }
+ return true;
+}
+
+// Append/process IETF-Format MAX_STREAM_DATA Frame
+// MAX_STREAM_DATA is two numbers, stream ID and then max number of bytes.
+bool QuicFramer::AppendIetfMaxStreamDataFrame(
+ const QuicWindowUpdateFrame& frame,
+ QuicDataWriter* writer) {
+ if (!writer->WriteUInt8(IETF_MAX_STREAM_DATA)) {
+ set_detailed_error("Can not write IETF_MAX_STREAM_DATA frame type byte");
+ return false;
+ }
+ if (!writer->WriteVarInt62(frame.stream_id)) {
+ set_detailed_error("Can not write IETF_MAX_STREAM_DATA stream id");
+ return false;
+ }
+ if (!writer->WriteVarInt62(frame.byte_offset)) {
+ set_detailed_error("Can not write IETF_MAX_STREAM_DATA byte-offset");
+ return false;
+ }
+ return true;
+}
+
+bool QuicFramer::ProcessIetfMaxStreamDataFrame(QuicDataReader* reader,
+ QuicWindowUpdateFrame* frame) {
+ if (!reader->ReadVarIntStreamId(&frame->stream_id)) {
+ set_detailed_error("Can not read IETF_MAX_STREAM_DATA stream id");
+ return false;
+ }
+ if (!reader->ReadVarInt62(&frame->byte_offset)) {
+ set_detailed_error("Can not read IETF_MAX_STREAM_DATA byte-count");
+ return false;
+ }
+ return true;
+}
+
+bool QuicFramer::AppendIetfMaxStreamIdFrame(
+ const QuicIetfMaxStreamIdFrame& frame,
+ QuicDataWriter* writer) {
+ if (!writer->WriteUInt8(IETF_MAX_STREAM_ID)) {
+ set_detailed_error("Can not write IETF_MAX_STREAM_ID frame type byte");
+ return false;
+ }
+ if (!writer->WriteVarInt62(frame.max_stream_id)) {
+ set_detailed_error("Can not write IETF_MAX_STREAM_ID stream id");
+ return false;
+ }
+ return true;
+}
+
+bool QuicFramer::ProcessIetfMaxStreamIdFrame(QuicDataReader* reader,
+ QuicIetfMaxStreamIdFrame* frame) {
+ if (!reader->ReadVarIntStreamId(&frame->max_stream_id)) {
+ set_detailed_error("Can not read IETF_MAX_STREAM_ID stream id");
+ return false;
+ }
+ return true;
+}
+
+bool QuicFramer::AppendIetfBlockedFrame(const QuicIetfBlockedFrame& frame,
+ QuicDataWriter* writer) {
+ if (!writer->WriteUInt8(IETF_BLOCKED)) {
+ set_detailed_error("Can not write IETF_BLOCKED frame type byte");
+ return false;
+ }
+ if (!writer->WriteVarInt62(frame.offset)) {
+ set_detailed_error("Can not write IETF_BLOCKED offset");
+ return false;
+ }
+ return true;
+}
+
+bool QuicFramer::ProcessIetfBlockedFrame(QuicDataReader* reader,
+ QuicIetfBlockedFrame* frame) {
+ if (!reader->ReadVarInt62(&frame->offset)) {
+ set_detailed_error("Can not read IETF_BLOCKED offset");
+ return false;
+ }
+ return true;
+}
+
+bool QuicFramer::AppendIetfStreamBlockedFrame(
+ const QuicWindowUpdateFrame& frame,
+ QuicDataWriter* writer) {
+ if (!writer->WriteUInt8(IETF_STREAM_BLOCKED)) {
+ set_detailed_error("Can not write IETF_STREAM_BLOCKED frame type byte");
+ return false;
+ }
+ if (!writer->WriteVarInt62(frame.stream_id)) {
+ set_detailed_error("Can not write IETF_STREAM_BLOCKED stream id");
+ return false;
+ }
+ if (!writer->WriteVarInt62(frame.byte_offset)) {
+ set_detailed_error("Can not write IETF_STREAM_BLOCKED offset");
+ return false;
+ }
+ return true;
+}
+
+bool QuicFramer::ProcessIetfStreamBlockedFrame(QuicDataReader* reader,
+ QuicWindowUpdateFrame* frame) {
+ if (!reader->ReadVarIntStreamId(&frame->stream_id)) {
+ set_detailed_error("Can not read IETF_STREAM_BLOCKED stream id");
+ return false;
+ }
+ if (!reader->ReadVarInt62(&frame->byte_offset)) {
+ set_detailed_error("Can not read IETF_STREAM_BLOCKED offset");
+ return false;
+ }
+ return true;
+}
+
+bool QuicFramer::AppendIetfStreamIdBlockedFrame(
+ const QuicIetfStreamIdBlockedFrame& frame,
+ QuicDataWriter* writer) {
+ if (!writer->WriteUInt8(IETF_STREAM_ID_BLOCKED)) {
+ set_detailed_error("Can not write IETF_STREAM_ID_BLOCKED frame type byte");
+ return false;
+ }
+ if (!writer->WriteVarInt62(frame.stream_id)) {
+ set_detailed_error("Can not write IETF_STREAM_ID_BLOCKED stream id");
+ return false;
+ }
+ return true;
+}
+
+bool QuicFramer::ProcessIetfStreamIdBlockedFrame(
+ QuicDataReader* reader,
+ QuicIetfStreamIdBlockedFrame* frame) {
+ if (!reader->ReadVarIntStreamId(&frame->stream_id)) {
+ set_detailed_error("Can not read IETF_STREAM_ID_BLOCKED stream id");
+ return false;
+ }
return true;
}
diff --git a/chromium/net/quic/core/quic_framer.h b/chromium/net/quic/core/quic_framer.h
index c08750b2e63..589d77575fd 100644
--- a/chromium/net/quic/core/quic_framer.h
+++ b/chromium/net/quic/core/quic_framer.h
@@ -10,6 +10,8 @@
#include <memory>
#include "base/macros.h"
+#include "net/quic/core/crypto/quic_decrypter.h"
+#include "net/quic/core/crypto/quic_encrypter.h"
#include "net/quic/core/quic_packets.h"
#include "net/quic/platform/api/quic_endian.h"
#include "net/quic/platform/api/quic_export.h"
@@ -24,8 +26,6 @@ class QuicFramerPeer;
class QuicDataReader;
class QuicDataWriter;
-class QuicDecrypter;
-class QuicEncrypter;
class QuicFramer;
class QuicStreamFrameDataProducer;
@@ -149,6 +149,14 @@ class QUIC_EXPORT_PRIVATE QuicFramerVisitorInterface {
// Called when a packet has been completely processed.
virtual void OnPacketComplete() = 0;
+
+ // Called to check whether |token| is a valid stateless reset token.
+ virtual bool IsValidStatelessResetToken(uint128 token) const = 0;
+
+ // Called when an IETF stateless reset packet has been parsed and validated
+ // with the stateless reset token.
+ virtual void OnAuthenticatedIetfStatelessResetPacket(
+ const QuicIetfStatelessResetPacket& packet) = 0;
};
// Class for parsing and constructing QUIC packets. It has a
@@ -281,6 +289,7 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
// Returns a new version negotiation packet.
static std::unique_ptr<QuicEncryptedPacket> BuildVersionNegotiationPacket(
QuicConnectionId connection_id,
+ bool ietf_quic,
const ParsedQuicVersionVector& versions);
// If header.version_flag is set, the version in the
@@ -295,29 +304,30 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
bool last_frame_in_packet,
QuicDataWriter* writer);
- // SetDecrypter sets the primary decrypter, replacing any that already exists,
- // and takes ownership. If an alternative decrypter is in place then the
- // function DCHECKs. This is intended for cases where one knows that future
- // packets will be using the new decrypter and the previous decrypter is now
- // obsolete. |level| indicates the encryption level of the new decrypter.
- void SetDecrypter(EncryptionLevel level, QuicDecrypter* decrypter);
+ // SetDecrypter sets the primary decrypter, replacing any that already exists.
+ // If an alternative decrypter is in place then the function DCHECKs. This is
+ // intended for cases where one knows that future packets will be using the
+ // new decrypter and the previous decrypter is now obsolete. |level| indicates
+ // the encryption level of the new decrypter.
+ void SetDecrypter(EncryptionLevel level,
+ std::unique_ptr<QuicDecrypter> decrypter);
// SetAlternativeDecrypter sets a decrypter that may be used to decrypt
- // future packets and takes ownership of it. |level| indicates the encryption
- // level of the decrypter. If |latch_once_used| is true, then the first time
- // that the decrypter is successful it will replace the primary decrypter.
- // Otherwise both decrypters will remain active and the primary decrypter
- // will be the one last used.
+ // future packets. |level| indicates the encryption level of the decrypter. If
+ // |latch_once_used| is true, then the first time that the decrypter is
+ // successful it will replace the primary decrypter. Otherwise both
+ // decrypters will remain active and the primary decrypter will be the one
+ // last used.
void SetAlternativeDecrypter(EncryptionLevel level,
- QuicDecrypter* decrypter,
+ std::unique_ptr<QuicDecrypter> decrypter,
bool latch_once_used);
const QuicDecrypter* decrypter() const;
const QuicDecrypter* alternative_decrypter() const;
- // Changes the encrypter used for level |level| to |encrypter|. The function
- // takes ownership of |encrypter|.
- void SetEncrypter(EncryptionLevel level, QuicEncrypter* encrypter);
+ // Changes the encrypter used for level |level| to |encrypter|.
+ void SetEncrypter(EncryptionLevel level,
+ std::unique_ptr<QuicEncrypter> encrypter);
// Encrypts a payload in |buffer|. |ad_len| is the length of the associated
// data. |total_len| is the length of the associated data plus plaintext.
@@ -365,6 +375,8 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
QuicVersionLabel last_version_label() const { return last_version_label_; }
+ bool last_packet_is_ietf_quic() const { return last_packet_is_ietf_quic_; }
+
void set_data_producer(QuicStreamFrameDataProducer* data_producer) {
data_producer_ = data_producer;
}
@@ -514,30 +526,10 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
bool AppendPaddingFrame(const QuicPaddingFrame& frame,
QuicDataWriter* writer);
- // IETF defined frame append/process methods.
+ // IETF frame processing methods.
bool ProcessIetfStreamFrame(QuicDataReader* reader,
uint8_t frame_type,
QuicStreamFrame* frame);
- // Append a stream frame and data to the packet.
- bool AppendIetfStreamFrame(const QuicStreamFrame& frame,
- bool last_frame_in_packet,
- QuicDataWriter* writer);
-
- // Add/process an IETF-Formatted Connection and Application close frames.
- bool AppendIetfConnectionCloseFrame(const QuicConnectionCloseFrame& frame,
- QuicDataWriter* writer);
- bool AppendIetfConnectionCloseFrame(const QuicIetfTransportErrorCodes code,
- const QuicString& phrase,
- QuicDataWriter* writer);
- bool AppendIetfApplicationCloseFrame(const QuicConnectionCloseFrame& frame,
- QuicDataWriter* writer);
- bool AppendIetfApplicationCloseFrame(const uint16_t code,
- const QuicString& phrase,
- QuicDataWriter* writer);
- bool AppendIetfCloseFrame(const QuicIetfFrameType type,
- const uint16_t code,
- const QuicString& phrase,
- QuicDataWriter* writer);
bool ProcessIetfConnectionCloseFrame(QuicDataReader* reader,
const uint8_t frame_type,
QuicConnectionCloseFrame* frame);
@@ -547,14 +539,73 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
bool ProcessIetfCloseFrame(QuicDataReader* reader,
const uint8_t frame_type,
QuicConnectionCloseFrame* frame);
-
- // Parse an IETF-format Ack frame from the packet
bool ProcessIetfAckFrame(QuicDataReader* reader,
uint8_t frame_type,
QuicAckFrame* ack_frame);
- // Append an IETf-format Ack frame to the packet
- bool AppendIetfAckFrameAndTypeByte(const QuicAckFrame& frame,
- QuicDataWriter* writer);
+ void ProcessIetfPaddingFrame(QuicDataReader* reader, QuicPaddingFrame* frame);
+ bool ProcessIetfPathChallengeFrame(QuicDataReader* reader,
+ QuicPathChallengeFrame* frame);
+ bool ProcessIetfPathResponseFrame(QuicDataReader* reader,
+ QuicPathResponseFrame* frame);
+ bool ProcessIetfResetStreamFrame(QuicDataReader* reader,
+ QuicRstStreamFrame* frame);
+ bool ProcessIetfStopSendingFrame(QuicDataReader* reader,
+ QuicStopSendingFrame* stop_sending_frame);
+
+ // IETF frame appending methods. All methods append the type byte as well.
+ bool AppendIetfStreamFrame(const QuicStreamFrame& frame,
+ bool last_frame_in_packet,
+ QuicDataWriter* writer);
+ bool AppendIetfConnectionCloseFrame(const QuicConnectionCloseFrame& frame,
+ QuicDataWriter* writer);
+ bool AppendIetfApplicationCloseFrame(const QuicConnectionCloseFrame& frame,
+ QuicDataWriter* writer);
+ bool AppendIetfCloseFrame(const QuicIetfFrameType type,
+ const uint16_t code,
+ const QuicString& phrase,
+ QuicDataWriter* writer);
+ bool AppendIetfAckFrame(const QuicAckFrame& frame, QuicDataWriter* writer);
+ bool AppendIetfPaddingFrame(const QuicPaddingFrame& frame,
+ QuicDataWriter* writer);
+ bool AppendIetfPathChallengeFrame(const QuicPathChallengeFrame& frame,
+ QuicDataWriter* writer);
+ bool AppendIetfPathResponseFrame(const QuicPathResponseFrame& frame,
+ QuicDataWriter* writer);
+ bool AppendIetfResetStreamFrame(const QuicRstStreamFrame& frame,
+ QuicDataWriter* writer);
+ bool AppendIetfStopSendingFrame(
+ const QuicStopSendingFrame& stop_sending_frame,
+ QuicDataWriter* writer);
+
+ // Append/consume IETF-Format MAX_DATA and MAX_STREAM_DATA frames
+ bool AppendIetfMaxDataFrame(const QuicWindowUpdateFrame& frame,
+ QuicDataWriter* writer);
+ bool AppendIetfMaxStreamDataFrame(const QuicWindowUpdateFrame& frame,
+ QuicDataWriter* writer);
+ bool ProcessIetfMaxDataFrame(QuicDataReader* reader,
+ QuicWindowUpdateFrame* frame);
+ bool ProcessIetfMaxStreamDataFrame(QuicDataReader* reader,
+ QuicWindowUpdateFrame* frame);
+
+ bool AppendIetfMaxStreamIdFrame(const QuicIetfMaxStreamIdFrame& frame,
+ QuicDataWriter* writer);
+ bool ProcessIetfMaxStreamIdFrame(QuicDataReader* reader,
+ QuicIetfMaxStreamIdFrame* frame);
+
+ bool AppendIetfBlockedFrame(const QuicIetfBlockedFrame& frame,
+ QuicDataWriter* writer);
+ bool ProcessIetfBlockedFrame(QuicDataReader* reader,
+ QuicIetfBlockedFrame* frame);
+
+ bool AppendIetfStreamBlockedFrame(const QuicWindowUpdateFrame& frame,
+ QuicDataWriter* writer);
+ bool ProcessIetfStreamBlockedFrame(QuicDataReader* reader,
+ QuicWindowUpdateFrame* frame);
+
+ bool AppendIetfStreamIdBlockedFrame(const QuicIetfStreamIdBlockedFrame& frame,
+ QuicDataWriter* writer);
+ bool ProcessIetfStreamIdBlockedFrame(QuicDataReader* reader,
+ QuicIetfStreamIdBlockedFrame* frame);
bool RaiseError(QuicErrorCode error);
@@ -573,6 +624,8 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
QuicConnectionId last_serialized_connection_id_;
// The last QUIC version label received.
QuicVersionLabel last_version_label_;
+ // Whether last received packet is IETF QUIC packet.
+ bool last_packet_is_ietf_quic_;
// Version of the protocol being used.
ParsedQuicVersion version_;
// This vector contains QUIC versions which we currently support.
@@ -612,7 +665,7 @@ class QUIC_EXPORT_PRIVATE QuicFramer {
// owned. TODO(fayang): Consider add data producer to framer's constructor.
QuicStreamFrameDataProducer* data_producer_;
- // Latched value of quic_reloadable_flag_quic_use_incremental_ack_processing.
+ // Latched value of quic_reloadable_flag_quic_use_incremental_ack_processing3.
const bool use_incremental_ack_processing_;
DISALLOW_COPY_AND_ASSIGN(QuicFramer);
diff --git a/chromium/net/quic/core/quic_framer_test.cc b/chromium/net/quic/core/quic_framer_test.cc
index 05ff90c20fa..5bc570344de 100644
--- a/chromium/net/quic/core/quic_framer_test.cc
+++ b/chromium/net/quic/core/quic_framer_test.cc
@@ -26,6 +26,7 @@
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/quic/test_tools/simple_data_producer.h"
+using std::string;
using testing::_;
using testing::Return;
using testing::Truly;
@@ -34,16 +35,18 @@ namespace net {
namespace test {
namespace {
-const QuicPacketNumber kEpoch = UINT64_C(1) << 48;
+const QuicPacketNumber kEpoch = UINT64_C(1) << 32;
const QuicPacketNumber kMask = kEpoch - 1;
+const uint128 kTestStatelessResetToken = 1010101; // 0x0F69B5
+
// Use fields in which each byte is distinct to ensure that every byte is
// framed correctly. The values are otherwise arbitrary.
const QuicConnectionId kConnectionId = UINT64_C(0xFEDCBA9876543210);
-const QuicPacketNumber kPacketNumber = UINT64_C(0x123456789ABC);
+const QuicPacketNumber kPacketNumber = UINT64_C(0x12345678);
const QuicPacketNumber kSmallLargestObserved = UINT16_C(0x1234);
const QuicPacketNumber kSmallMissingPacket = UINT16_C(0x1233);
-const QuicPacketNumber kLeastUnacked = UINT64_C(0x0123456789AA0);
+const QuicPacketNumber kLeastUnacked = UINT64_C(0x012345670);
const QuicStreamId kStreamId = UINT64_C(0x01020304);
const QuicStreamOffset kStreamOffset = UINT64_C(0xBA98FEDC32107654);
const QuicPublicResetNonceProof kNonceProof = UINT64_C(0xABCDEF0123456789);
@@ -63,8 +66,8 @@ class TestEncrypter : public QuicEncrypter {
size_t max_output_length) override {
version_ = version;
packet_number_ = packet_number;
- associated_data_ = associated_data.as_string();
- plaintext_ = plaintext.as_string();
+ associated_data_ = string(associated_data);
+ plaintext_ = string(plaintext);
memcpy(output, plaintext.data(), plaintext.length());
*output_length = plaintext.length();
return true;
@@ -109,8 +112,8 @@ class TestDecrypter : public QuicDecrypter {
size_t max_output_length) override {
version_ = version;
packet_number_ = packet_number;
- associated_data_ = associated_data.as_string();
- ciphertext_ = ciphertext.as_string();
+ associated_data_ = string(associated_data);
+ ciphertext_ = string(ciphertext);
memcpy(output, ciphertext.data(), ciphertext.length());
*output_length = ciphertext.length();
return true;
@@ -260,6 +263,16 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
return true;
}
+ bool IsValidStatelessResetToken(uint128 token) const override {
+ return token == kTestStatelessResetToken;
+ }
+
+ void OnAuthenticatedIetfStatelessResetPacket(
+ const QuicIetfStatelessResetPacket& packet) override {
+ stateless_reset_packet_ =
+ QuicMakeUnique<QuicIetfStatelessResetPacket>(packet);
+ }
+
// Counters from the visitor_ callbacks.
int error_count_;
int version_mismatch_;
@@ -271,6 +284,7 @@ class TestQuicVisitor : public QuicFramerVisitorInterface {
std::unique_ptr<QuicPacketHeader> header_;
std::unique_ptr<QuicPublicResetPacket> public_reset_packet_;
+ std::unique_ptr<QuicIetfStatelessResetPacket> stateless_reset_packet_;
std::unique_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_;
std::vector<std::unique_ptr<QuicStreamFrame>> stream_frames_;
std::vector<std::unique_ptr<QuicAckFrame>> ack_frames_;
@@ -294,6 +308,12 @@ struct PacketFragment {
using PacketFragments = std::vector<struct PacketFragment>;
+ParsedQuicVersionVector AllSupportedVersionsIncludingTls() {
+ QuicFlagSaver flags;
+ SetQuicFlag(&FLAGS_quic_supports_tls_handshake, true);
+ return AllSupportedVersions();
+}
+
class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
public:
QuicFramerTest()
@@ -301,13 +321,25 @@ class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
decrypter_(new test::TestDecrypter()),
version_(GetParam()),
start_(QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(0x10)),
- framer_(AllSupportedVersions(), start_, Perspective::IS_SERVER) {
+ framer_(AllSupportedVersionsIncludingTls(),
+ start_,
+ Perspective::IS_SERVER) {
+ SetQuicFlag(&FLAGS_quic_supports_tls_handshake, true);
framer_.set_version(version_);
- framer_.SetDecrypter(ENCRYPTION_NONE, decrypter_);
- framer_.SetEncrypter(ENCRYPTION_NONE, encrypter_);
+ framer_.SetDecrypter(ENCRYPTION_NONE,
+ std::unique_ptr<QuicDecrypter>(decrypter_));
+ framer_.SetEncrypter(ENCRYPTION_NONE,
+ std::unique_ptr<QuicEncrypter>(encrypter_));
+
framer_.set_visitor(&visitor_);
}
+ // Helper function to get unsigned char representation of the handshake
+ // protocol byte of the current QUIC version number.
+ unsigned char GetQuicVersionProtocolByte() {
+ return (CreateQuicVersionLabel(version_) >> 24) & 0xff;
+ }
+
// Helper function to get unsigned char representation of digit in the
// units place of the current QUIC version number.
unsigned char GetQuicVersionDigitOnes() {
@@ -358,13 +390,13 @@ class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
if (QuicFramer::GetAssociatedDataFromEncryptedPacket(
framer_.transport_version(), encrypted, PACKET_8BYTE_CONNECTION_ID,
includes_version, includes_diversification_nonce,
- PACKET_6BYTE_PACKET_NUMBER) != decrypter_->associated_data_) {
+ PACKET_4BYTE_PACKET_NUMBER) != decrypter_->associated_data_) {
QUIC_LOG(ERROR) << "Decrypted incorrect associated data. expected "
<< QuicFramer::GetAssociatedDataFromEncryptedPacket(
framer_.transport_version(), encrypted,
PACKET_8BYTE_CONNECTION_ID, includes_version,
includes_diversification_nonce,
- PACKET_6BYTE_PACKET_NUMBER)
+ PACKET_4BYTE_PACKET_NUMBER)
<< " actual: " << decrypter_->associated_data_;
return false;
}
@@ -372,7 +404,7 @@ class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
encrypted.AsStringPiece().substr(GetStartOfEncryptedData(
framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
includes_version, includes_diversification_nonce,
- PACKET_6BYTE_PACKET_NUMBER)));
+ PACKET_4BYTE_PACKET_NUMBER)));
if (ciphertext != decrypter_->ciphertext_) {
QUIC_LOG(ERROR) << "Decrypted incorrect ciphertext data. expected "
<< ciphertext << " actual: " << decrypter_->ciphertext_;
@@ -450,7 +482,7 @@ class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
QuicPacketNumber wire_packet_number = expected_packet_number & kMask;
EXPECT_EQ(expected_packet_number,
QuicFramerPeer::CalculatePacketNumberFromWire(
- &framer_, PACKET_6BYTE_PACKET_NUMBER, last_packet_number,
+ &framer_, PACKET_4BYTE_PACKET_NUMBER, last_packet_number,
wire_packet_number))
<< "last_packet_number: " << last_packet_number
<< " wire_packet_number: " << wire_packet_number;
@@ -475,10 +507,19 @@ class QuicFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
test::TestQuicVisitor visitor_;
};
+// Multiple test cases of QuicFramerTest use byte arrays to define packets for
+// testing, and these byte arrays contain the QUIC version. This macro explodes
+// the 32-bit version into four bytes in network order. Since it uses methods of
+// QuicFramerTest, it is only valid to use this in a QuicFramerTest.
+#define QUIC_VERSION_BYTES \
+ GetQuicVersionProtocolByte(), '0', GetQuicVersionDigitTens(), \
+ GetQuicVersionDigitOnes()
+
// Run all framer tests with all supported versions of QUIC.
-INSTANTIATE_TEST_CASE_P(QuicFramerTests,
- QuicFramerTest,
- ::testing::ValuesIn(AllSupportedVersions()));
+INSTANTIATE_TEST_CASE_P(
+ QuicFramerTests,
+ QuicFramerTest,
+ ::testing::ValuesIn(AllSupportedVersionsIncludingTls()));
TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochStart) {
// A few quick manual sanity checks.
@@ -592,11 +633,11 @@ TEST_P(QuicFramerTest, LargePacket) {
// clang-format off
unsigned char packet[kMaxPacketSize + 1] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// private flags
0x00,
};
@@ -604,7 +645,7 @@ TEST_P(QuicFramerTest, LargePacket) {
const size_t header_size = GetPacketHeaderSize(
framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER);
+ !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER);
memset(packet + header_size, 0, kMaxPacketSize - header_size);
@@ -623,25 +664,25 @@ TEST_P(QuicFramerTest, PacketHeader) {
PacketFragments packet38 = {
// public flags (8 byte connection_id)
{"Unable to read public flags.",
- {0x38}},
+ {0x28}},
// connection_id
{"Unable to read ConnectionId.",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"Unable to read packet number.",
- {0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
};
PacketFragments packet39 = {
// public flags (8 byte connection_id)
{"Unable to read public flags.",
- {0x38}},
+ {0x28}},
// connection_id
{"Unable to read ConnectionId.",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"Unable to read packet number.",
- {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
};
// clang-format on
@@ -669,23 +710,21 @@ TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
PacketFragments packet = {
// public flags (0 byte connection_id)
{"Unable to read public flags.",
- {0x30}},
+ {0x20}},
// connection_id
// packet number
{"Unable to read packet number.",
- {0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12}}
+ {0x78, 0x56, 0x34, 0x12}}
};
PacketFragments packet39 = {
// public flags (0 byte connection_id)
{"Unable to read public flags.",
- {0x30}},
+ {0x20}},
// connection_id
// packet number
{"Unable to read packet number.",
- {0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
};
// clang-format on
@@ -709,31 +748,31 @@ TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
PacketFragments packet = {
// public flags (0 byte connection_id)
{"Unable to read public flags.",
- {0x39}},
+ {0x29}},
// connection_id
{"Unable to read ConnectionId.",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// version tag
{"Unable to read protocol version.",
- {'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes()}},
+ {QUIC_VERSION_BYTES}},
// packet number
{"Unable to read packet number.",
- {0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
};
PacketFragments packet39 = {
// public flags (0 byte connection_id)
{"Unable to read public flags.",
- {0x39}},
+ {0x29}},
// connection_id
{"Unable to read ConnectionId.",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// version tag
{"Unable to read protocol version.",
- {'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes()}},
+ {QUIC_VERSION_BYTES}},
// packet number
{"Unable to read packet number.",
- {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
};
// clang-format on
@@ -766,7 +805,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith4BytePacketNumber) {
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"Unable to read packet number.",
- {0xBC, 0x9A, 0x78, 0x56}},
+ {0x78, 0x56, 0x34, 0x12}},
};
PacketFragments packet39 = {
@@ -778,7 +817,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith4BytePacketNumber) {
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"Unable to read packet number.",
- {0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
};
// clang-format on
@@ -810,7 +849,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith2BytePacketNumber) {
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"Unable to read packet number.",
- {0xBC, 0x9A}},
+ {0x78, 0x56}},
};
PacketFragments packet39 = {
@@ -822,7 +861,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith2BytePacketNumber) {
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"Unable to read packet number.",
- {0x9A, 0xBC}},
+ {0x56, 0x78}},
};
// clang-format on
@@ -855,7 +894,7 @@ TEST_P(QuicFramerTest, PacketHeaderWith1BytePacketNumber) {
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"Unable to read packet number.",
- {0xBC}},
+ {0x78}},
};
std::unique_ptr<QuicEncryptedPacket> encrypted(
@@ -891,7 +930,7 @@ TEST_P(QuicFramerTest, PacketNumberDecreasesThenIncreases) {
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
ASSERT_TRUE(visitor_.header_.get());
EXPECT_EQ(kConnectionId, visitor_.header_->connection_id);
- EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER,
+ EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
visitor_.header_->packet_number_length);
EXPECT_EQ(kPacketNumber - 2, visitor_.header_->packet_number);
@@ -936,7 +975,7 @@ TEST_P(QuicFramerTest, PacketWithDiversificationNonce) {
// clang-format off
unsigned char packet[] = {
// public flags: includes nonce flag
- 0x3C,
+ 0x2C,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// nonce
@@ -945,7 +984,7 @@ TEST_P(QuicFramerTest, PacketWithDiversificationNonce) {
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
// packet number
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (padding)
0x00,
@@ -954,7 +993,7 @@ TEST_P(QuicFramerTest, PacketWithDiversificationNonce) {
unsigned char packet39[] = {
// public flags: includes nonce flag
- 0x3C,
+ 0x2C,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// nonce
@@ -963,7 +1002,7 @@ TEST_P(QuicFramerTest, PacketWithDiversificationNonce) {
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
// packet number
- 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
// frame type (padding)
0x00,
@@ -989,14 +1028,13 @@ TEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id, version flag and an unknown flag)
- 0x39,
+ 0x29,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// version tag
'Q', '0', '0', '0',
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (padding frame)
0x00,
@@ -1005,14 +1043,13 @@ TEST_P(QuicFramerTest, LargePublicFlagWithMismatchedVersions) {
unsigned char packet39[] = {
// public flags (8 byte connection_id, version flag and an unknown flag)
- 0x39,
+ 0x29,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// version tag
'Q', '0', '0', '0',
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (padding frame)
0x00,
@@ -1037,12 +1074,11 @@ TEST_P(QuicFramerTest, PaddingFrame) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (padding frame)
0x00,
@@ -1084,7 +1120,7 @@ TEST_P(QuicFramerTest, PaddingFrame) {
GetPacketHeaderSize(framer_.transport_version(),
PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
!kIncludeDiversificationNonce,
- PACKET_6BYTE_PACKET_NUMBER),
+ PACKET_4BYTE_PACKET_NUMBER),
"Packet has no frames.", QUIC_MISSING_PAYLOAD);
}
@@ -1092,12 +1128,11 @@ TEST_P(QuicFramerTest, NewPaddingFrame) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// paddings
0x00, 0x00,
@@ -1120,12 +1155,11 @@ TEST_P(QuicFramerTest, NewPaddingFrame) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// paddings
0x00, 0x00,
@@ -1148,12 +1182,11 @@ TEST_P(QuicFramerTest, NewPaddingFrame) {
unsigned char packet41[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// paddings
0x00, 0x00,
@@ -1208,14 +1241,13 @@ TEST_P(QuicFramerTest, StreamFrame) {
PacketFragments packet = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
// frame type (stream frame with fin)
{"",
{0xFF}},
@@ -1239,14 +1271,13 @@ TEST_P(QuicFramerTest, StreamFrame) {
PacketFragments packet39 = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (stream frame with fin)
{"",
{0xFF}},
@@ -1270,14 +1301,13 @@ TEST_P(QuicFramerTest, StreamFrame) {
PacketFragments packet41 = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (stream frame with fin)
{"",
{0xFF}},
@@ -1324,19 +1354,20 @@ TEST_P(QuicFramerTest, StreamFrame) {
TEST_P(QuicFramerTest, MissingDiversificationNonce) {
QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
framer_.SetDecrypter(ENCRYPTION_NONE,
- new NullDecrypter(Perspective::IS_CLIENT));
+ QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
decrypter_ = new test::TestDecrypter();
- framer_.SetAlternativeDecrypter(ENCRYPTION_INITIAL, decrypter_, false);
+ framer_.SetAlternativeDecrypter(ENCRYPTION_INITIAL,
+ std::unique_ptr<QuicDecrypter>(decrypter_),
+ false);
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (stream frame with fin)
0xFF,
@@ -1355,12 +1386,11 @@ TEST_P(QuicFramerTest, MissingDiversificationNonce) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (stream frame with fin)
0xFF,
@@ -1379,12 +1409,11 @@ TEST_P(QuicFramerTest, MissingDiversificationNonce) {
unsigned char packet41[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (stream frame with fin)
0xFF,
@@ -1418,14 +1447,13 @@ TEST_P(QuicFramerTest, StreamFrame3ByteStreamId) {
PacketFragments packet = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
// frame type (stream frame with fin)
{"",
{0xFE}},
@@ -1449,14 +1477,13 @@ TEST_P(QuicFramerTest, StreamFrame3ByteStreamId) {
PacketFragments packet39 = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (stream frame with fin)
{"",
{0xFE}},
@@ -1480,14 +1507,13 @@ TEST_P(QuicFramerTest, StreamFrame3ByteStreamId) {
PacketFragments packet41 = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (stream frame with fin)
{"",
{0xF7}},
@@ -1537,14 +1563,13 @@ TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) {
PacketFragments packet = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
// frame type (stream frame with fin)
{"",
{0xFD}},
@@ -1568,14 +1593,13 @@ TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) {
PacketFragments packet39 = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (stream frame with fin)
{"",
{0xFD}},
@@ -1599,14 +1623,13 @@ TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) {
PacketFragments packet41 = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (stream frame with fin)
{"",
{0xEF}},
@@ -1656,14 +1679,13 @@ TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) {
PacketFragments packet = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
// frame type (stream frame with fin)
{"",
{0xFC}},
@@ -1687,14 +1709,13 @@ TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) {
PacketFragments packet39 = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (stream frame with fin)
{"",
{0xFC}},
@@ -1718,14 +1739,13 @@ TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) {
PacketFragments packet41 = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (stream frame with fin)
{"",
{0xE7}},
@@ -1775,17 +1795,16 @@ TEST_P(QuicFramerTest, StreamFrameWithVersion) {
PacketFragments packet = {
// public flags (version, 8 byte connection_id)
{"",
- {0x39}},
+ {0x29}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// version tag
{"",
- {'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes()}},
+ {QUIC_VERSION_BYTES}},
// packet number
{"",
- {0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
// frame type (stream frame with fin)
{"",
{0xFE}},
@@ -1809,17 +1828,16 @@ TEST_P(QuicFramerTest, StreamFrameWithVersion) {
PacketFragments packet39 = {
// public flags (version, 8 byte connection_id)
{"",
- {0x39}},
+ {0x29}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// version tag
{"",
- {'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes()}},
+ {QUIC_VERSION_BYTES}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (stream frame with fin)
{"",
{0xFE}},
@@ -1843,17 +1861,16 @@ TEST_P(QuicFramerTest, StreamFrameWithVersion) {
PacketFragments packet41 = {
// public flags (version, 8 byte connection_id)
{"",
- {0x39}},
+ {0x29}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// version tag
{"",
- {'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes()}},
+ {QUIC_VERSION_BYTES}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (stream frame with fin)
{"",
{0xF7}},
@@ -1904,12 +1921,11 @@ TEST_P(QuicFramerTest, RejectPacket) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (stream frame with fin)
0xFF,
@@ -1928,12 +1944,11 @@ TEST_P(QuicFramerTest, RejectPacket) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (stream frame with fin)
0xFF,
@@ -1952,12 +1967,11 @@ TEST_P(QuicFramerTest, RejectPacket) {
unsigned char packet41[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (stream frame with fin)
0xFF,
@@ -1999,7 +2013,7 @@ TEST_P(QuicFramerTest, RejectPublicHeader) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
};
@@ -2018,13 +2032,13 @@ TEST_P(QuicFramerTest, AckFrameOneAckBlock) {
PacketFragments packet = {
// public flags (8 byte connection_id)
{"",
- {0x3C}},
+ {0x2C}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
// frame type (ack frame)
// (one ack block, 2 byte largest observed, 2 byte block length)
{"",
@@ -2046,13 +2060,13 @@ TEST_P(QuicFramerTest, AckFrameOneAckBlock) {
PacketFragments packet39 = {
// public flags (8 byte connection_id)
{"",
- {0x3C}},
+ {0x2C}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (ack frame)
// (one ack block, 2 byte largest observed, 2 byte block length)
{"",
@@ -2074,13 +2088,13 @@ TEST_P(QuicFramerTest, AckFrameOneAckBlock) {
PacketFragments packet41 = {
// public flags (8 byte connection_id)
{"",
- {0x3C}},
+ {0x2C}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (ack frame)
// (one ack block, 2 byte largest observed, 2 byte block length)
{"",
@@ -2126,13 +2140,13 @@ TEST_P(QuicFramerTest, FirstAckFrameUnderflow) {
PacketFragments packet = {
// public flags (8 byte connection_id)
{"",
- {0x3C}},
+ {0x2C}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
// frame type (ack frame)
// (one ack block, 2 byte largest observed, 2 byte block length)
{"",
@@ -2154,13 +2168,13 @@ TEST_P(QuicFramerTest, FirstAckFrameUnderflow) {
PacketFragments packet39 = {
// public flags (8 byte connection_id)
{"",
- {0x3C}},
+ {0x2C}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (ack frame)
// (one ack block, 2 byte largest observed, 2 byte block length)
{"",
@@ -2182,13 +2196,13 @@ TEST_P(QuicFramerTest, FirstAckFrameUnderflow) {
PacketFragments packet41 = {
// public flags (8 byte connection_id)
{"",
- {0x3C}},
+ {0x2C}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (ack frame)
// (one ack block, 2 byte largest observed, 2 byte block length)
{"",
@@ -2222,13 +2236,13 @@ TEST_P(QuicFramerTest, AckFrameFirstAckBlockLengthZero) {
PacketFragments packet = {
// public flags (8 byte connection_id)
{"",
- { 0x3C }},
+ { 0x2C }},
// connection_id
{"",
{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
// packet number
{"",
- { 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12 }},
+ { 0x78, 0x56, 0x34, 0x12 }},
// frame type (ack frame)
// (more than one ack block, 2 byte largest observed, 2 byte block length)
@@ -2263,13 +2277,13 @@ TEST_P(QuicFramerTest, AckFrameFirstAckBlockLengthZero) {
PacketFragments packet39 = {
// public flags (8 byte connection_id)
{"",
- { 0x3C }},
+ { 0x2C }},
// connection_id
{"",
{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
// packet number
{"",
- { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC }},
+ { 0x12, 0x34, 0x56, 0x78 }},
// frame type (ack frame)
// (more than one ack block, 2 byte largest observed, 2 byte block length)
@@ -2304,13 +2318,13 @@ TEST_P(QuicFramerTest, AckFrameFirstAckBlockLengthZero) {
PacketFragments packet41 = {
// public flags (8 byte connection_id)
{"",
- { 0x3C }},
+ { 0x2C }},
// connection_id
{"",
{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
// packet number
{"",
- { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC }},
+ { 0x12, 0x34, 0x56, 0x78 }},
// frame type (ack frame)
// (more than one ack block, 2 byte largest observed, 2 byte block length)
@@ -2372,20 +2386,20 @@ TEST_P(QuicFramerTest, AckFrameOneAckBlockMaxLength) {
PacketFragments packet = {
// public flags (8 byte connection_id)
{"",
- {0x3C}},
+ {0x2C}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
// frame type (ack frame)
- // (one ack block, 6 byte largest observed, 2 byte block length)
+ // (one ack block, 4 byte largest observed, 2 byte block length)
{"",
- {0x4D}},
+ {0x49}},
// largest acked
{"Unable to read largest acked.",
- {0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
// Zero delta time.
{"Unable to read ack delay time.",
{0x00, 0x00}},
@@ -2400,20 +2414,20 @@ TEST_P(QuicFramerTest, AckFrameOneAckBlockMaxLength) {
PacketFragments packet39 = {
// public flags (8 byte connection_id)
{"",
- {0x3C}},
+ {0x2C}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (ack frame)
- // (one ack block, 6 byte largest observed, 2 byte block length)
+ // (one ack block, 4 byte largest observed, 2 byte block length)
{"",
- {0x4D}},
+ {0x49}},
// largest acked
{"Unable to read largest acked.",
- {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// Zero delta time.
{"Unable to read ack delay time.",
{0x00, 0x00}},
@@ -2428,23 +2442,23 @@ TEST_P(QuicFramerTest, AckFrameOneAckBlockMaxLength) {
PacketFragments packet41 = {
// public flags (8 byte connection_id)
{"",
- {0x3C}},
+ {0x2C}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (ack frame)
- // (one ack block, 8 byte largest observed, 2 byte block length)
+ // (one ack block, 4 byte largest observed, 2 byte block length)
{"",
- {0xAD}},
+ {0xA9}},
// num timestamps.
{"Unable to read num received packets.",
{0x00}},
// largest acked
{"Unable to read largest acked.",
- {0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// Zero delta time.
{"Unable to read ack delay time.",
{0x00, 0x00}},
@@ -2481,13 +2495,13 @@ TEST_P(QuicFramerTest, AckFrameTwoTimeStampsMultipleAckBlocks) {
PacketFragments packet = {
// public flags (8 byte connection_id)
{"",
- { 0x3C }},
+ { 0x2C }},
// connection_id
{"",
{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
// packet number
{"",
- { 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12 }},
+ { 0x78, 0x56, 0x34, 0x12 }},
// frame type (ack frame)
// (more than one ack block, 2 byte largest observed, 2 byte block length)
@@ -2549,13 +2563,13 @@ TEST_P(QuicFramerTest, AckFrameTwoTimeStampsMultipleAckBlocks) {
PacketFragments packet39 = {
// public flags (8 byte connection_id)
{"",
- { 0x3C }},
+ { 0x2C }},
// connection_id
{"",
{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
// packet number
{"",
- { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC }},
+ { 0x12, 0x34, 0x56, 0x78 }},
// frame type (ack frame)
// (more than one ack block, 2 byte largest observed, 2 byte block length)
@@ -2617,13 +2631,13 @@ TEST_P(QuicFramerTest, AckFrameTwoTimeStampsMultipleAckBlocks) {
PacketFragments packet41 = {
// public flags (8 byte connection_id)
{"",
- { 0x3C }},
+ { 0x2C }},
// connection_id
{"",
{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }},
// packet number
{"",
- { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC }},
+ { 0x12, 0x34, 0x56, 0x78 }},
// frame type (ack frame)
// (more than one ack block, 2 byte largest observed, 2 byte block length)
@@ -2713,39 +2727,37 @@ TEST_P(QuicFramerTest, NewStopWaitingFrame) {
PacketFragments packet = {
// public flags (8 byte connection_id)
{"",
- {0x3C}},
+ {0x2C}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0xA8, 0x9A, 0x78, 0x56, 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
// frame type (stop waiting frame)
{"",
{0x06}},
// least packet number awaiting an ack, delta from packet number.
{"Unable to read least unacked delta.",
- {0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00}}
+ {0x08, 0x00, 0x00, 0x00}}
};
PacketFragments packet39 = {
// public flags (8 byte connection_id)
{"",
- {0x3C}},
+ {0x2C}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78, 0x9A, 0xA8}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (stop waiting frame)
{"",
{0x06}},
// least packet number awaiting an ack, delta from packet number.
{"Unable to read least unacked delta.",
- {0x00, 0x00, 0x00, 0x00,
- 0x00, 0x08}}
+ {0x00, 0x00, 0x00, 0x08}}
};
// clang-format on
@@ -2772,12 +2784,11 @@ TEST_P(QuicFramerTest, InvalidNewStopWaitingFrame) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x3C,
+ 0x2C,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xA8, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (stop waiting frame)
0x06,
// least packet number awaiting an ack, delta from packet number.
@@ -2787,12 +2798,11 @@ TEST_P(QuicFramerTest, InvalidNewStopWaitingFrame) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x3C,
+ 0x2C,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xA8,
// frame type (stop waiting frame)
0x06,
// least packet number awaiting an ack, delta from packet number.
@@ -2815,13 +2825,13 @@ TEST_P(QuicFramerTest, RstStreamFrame) {
PacketFragments packet = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
// frame type (rst stream frame)
{"",
{0x01}},
@@ -2840,13 +2850,13 @@ TEST_P(QuicFramerTest, RstStreamFrame) {
PacketFragments packet39 = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (rst stream frame)
{"",
{0x01}},
@@ -2865,13 +2875,13 @@ TEST_P(QuicFramerTest, RstStreamFrame) {
PacketFragments packet41 = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (rst stream frame)
{"",
{0x01}},
@@ -2912,13 +2922,13 @@ TEST_P(QuicFramerTest, ConnectionCloseFrame) {
PacketFragments packet = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
// frame type (connection close frame)
{"",
{0x02}},
@@ -2940,13 +2950,13 @@ TEST_P(QuicFramerTest, ConnectionCloseFrame) {
PacketFragments packet39 = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (connection close frame)
{"",
{0x02}},
@@ -2992,13 +3002,13 @@ TEST_P(QuicFramerTest, GoAwayFrame) {
PacketFragments packet = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
// frame type (go away frame)
{"",
{0x03}},
@@ -3023,13 +3033,13 @@ TEST_P(QuicFramerTest, GoAwayFrame) {
PacketFragments packet39 = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (go away frame)
{"",
{0x03}},
@@ -3076,13 +3086,13 @@ TEST_P(QuicFramerTest, WindowUpdateFrame) {
PacketFragments packet = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
// frame type (window update frame)
{"",
{0x04}},
@@ -3098,13 +3108,13 @@ TEST_P(QuicFramerTest, WindowUpdateFrame) {
PacketFragments packet39 = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (window update frame)
{"",
{0x04}},
@@ -3140,13 +3150,13 @@ TEST_P(QuicFramerTest, BlockedFrame) {
PacketFragments packet = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12}},
+ {0x78, 0x56, 0x34, 0x12}},
// frame type (blocked frame)
{"",
{0x05}},
@@ -3158,13 +3168,13 @@ TEST_P(QuicFramerTest, BlockedFrame) {
PacketFragments packet39 = {
// public flags (8 byte connection_id)
{"",
- {0x38}},
+ {0x28}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
- {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}},
+ {0x12, 0x34, 0x56, 0x78}},
// frame type (blocked frame)
{"",
{0x05}},
@@ -3194,12 +3204,11 @@ TEST_P(QuicFramerTest, PingFrame) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (ping frame)
0x07,
@@ -3207,12 +3216,11 @@ TEST_P(QuicFramerTest, PingFrame) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (ping frame)
0x07,
@@ -3430,13 +3438,13 @@ TEST_P(QuicFramerTest, VersionNegotiationPacket) {
PacketFragments packet = {
// public flags (version, 8 byte connection_id)
{"",
- {0x39}},
+ {0x29}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// version tag
{"Unable to read supported version in negotiation.",
- {'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
+ {QUIC_VERSION_BYTES,
'Q', '2', '.', '0'}},
};
// clang-format on
@@ -3465,13 +3473,13 @@ TEST_P(QuicFramerTest, OldVersionNegotiationPacket) {
PacketFragments packet = {
// public flags (version, 8 byte connection_id)
{"",
- {0x3D}},
+ {0x2D}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// version tag
{"Unable to read supported version in negotiation.",
- {'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
+ {QUIC_VERSION_BYTES,
'Q', '2', '.', '0'}},
};
// clang-format on
@@ -3507,12 +3515,11 @@ TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
// clang-format off
unsigned char packet[kMaxPacketSize] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (padding frame)
0x00,
@@ -3521,12 +3528,11 @@ TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
unsigned char packet39[kMaxPacketSize] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (padding frame)
0x00,
@@ -3536,7 +3542,7 @@ TEST_P(QuicFramerTest, BuildPaddingFramePacket) {
uint64_t header_size = GetPacketHeaderSize(
framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
- !kIncludeDiversificationNonce, PACKET_6BYTE_PACKET_NUMBER);
+ !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER);
memset((framer_.transport_version() <= QUIC_VERSION_38 ? packet : packet39) +
header_size + 1,
0x00, kMaxPacketSize - header_size - 1);
@@ -3570,12 +3576,11 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithNewPaddingFrame) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// paddings
0x00, 0x00,
@@ -3598,12 +3603,11 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithNewPaddingFrame) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// paddings
0x00, 0x00,
@@ -3626,12 +3630,11 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithNewPaddingFrame) {
unsigned char packet41[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// paddings
0x00, 0x00,
@@ -3686,7 +3689,7 @@ TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (padding frame)
0x00,
@@ -3699,7 +3702,7 @@ TEST_P(QuicFramerTest, Build4ByteSequenceNumberPaddingFramePacket) {
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
// frame type (padding frame)
0x00,
@@ -3741,7 +3744,7 @@ TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A,
+ 0x78, 0x56,
// frame type (padding frame)
0x00,
@@ -3754,7 +3757,7 @@ TEST_P(QuicFramerTest, Build2ByteSequenceNumberPaddingFramePacket) {
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0x9A, 0xBC,
+ 0x56, 0x78,
// frame type (padding frame)
0x00,
@@ -3796,7 +3799,7 @@ TEST_P(QuicFramerTest, Build1ByteSequenceNumberPaddingFramePacket) {
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC,
+ 0x78,
// frame type (padding frame)
0x00,
@@ -3832,12 +3835,11 @@ TEST_P(QuicFramerTest, BuildStreamFramePacket) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (stream frame with fin and no length)
0xDF,
@@ -3854,12 +3856,11 @@ TEST_P(QuicFramerTest, BuildStreamFramePacket) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (stream frame with fin and no length)
0xDF,
@@ -3876,12 +3877,11 @@ TEST_P(QuicFramerTest, BuildStreamFramePacket) {
unsigned char packet41[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (stream frame with fin and no length)
0xFE,
@@ -3925,13 +3925,13 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
// clang-format off
unsigned char packet[] = {
// public flags (version, 8 byte connection_id)
- 0x3D,
+ 0x2D,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// version tag
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
+ QUIC_VERSION_BYTES,
// packet number
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (stream frame with fin and no length)
0xDF,
@@ -3945,13 +3945,13 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
unsigned char packet39[] = {
// public flags (version, 8 byte connection_id)
- 0x3D,
+ 0x2D,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// version tag
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
+ QUIC_VERSION_BYTES,
// packet number
- 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
// frame type (stream frame with fin and no length)
0xDF,
@@ -3965,13 +3965,13 @@ TEST_P(QuicFramerTest, BuildStreamFramePacketWithVersionFlag) {
unsigned char packet41[] = {
// public flags (version, 8 byte connection_id)
- 0x3D,
+ 0x2D,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// version tag
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
+ QUIC_VERSION_BYTES,
// packet number
- 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
// frame type (stream frame with fin and no length)
0xFE,
@@ -4007,13 +4007,13 @@ TEST_P(QuicFramerTest, BuildVersionNegotiationPacket) {
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// version tag
- 'Q', '0', GetQuicVersionDigitTens(), GetQuicVersionDigitOnes(),
+ QUIC_VERSION_BYTES,
};
// clang-format on
QuicConnectionId connection_id = kConnectionId;
std::unique_ptr<QuicEncryptedPacket> data(
- framer_.BuildVersionNegotiationPacket(connection_id,
+ framer_.BuildVersionNegotiationPacket(connection_id, false,
SupportedVersions(GetParam())));
test::CompareCharArraysWithHexError("constructed packet", data->data(),
data->length(), AsChars(packet),
@@ -4036,11 +4036,11 @@ TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlock) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (ack frame)
// (no ack blocks, 2 byte largest observed, 2 byte block length)
@@ -4057,11 +4057,11 @@ TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlock) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
// frame type (ack frame)
// (no ack blocks, 2 byte largest observed, 2 byte block length)
@@ -4078,11 +4078,11 @@ TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlock) {
unsigned char packet41[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
// frame type (ack frame)
// (no ack blocks, 2 byte largest observed, 2 byte block length)
@@ -4126,65 +4126,65 @@ TEST_P(QuicFramerTest, BuildAckFramePacketOneAckBlockMaxLength) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (ack frame)
- // (no ack blocks, 6 byte largest observed, 6 byte block length)
- 0x4F,
+ // (no ack blocks, 4 byte largest observed, 4 byte block length)
+ 0x4A,
// largest acked
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// Zero delta time.
0x00, 0x00,
// first ack block length.
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// num timestamps.
0x00,
};
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
// frame type (ack frame)
- // (no ack blocks, 6 byte largest observed, 6 byte block length)
- 0x4F,
+ // (no ack blocks, 4 byte largest observed, 4 byte block length)
+ 0x4A,
// largest acked
- 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
// Zero delta time.
0x00, 0x00,
// first ack block length.
- 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
// num timestamps.
0x00,
};
unsigned char packet41[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
// frame type (ack frame)
- // (no ack blocks, 8 byte largest observed, 8 byte block length)
- 0xAF,
+ // (no ack blocks, 4 byte largest observed, 4 byte block length)
+ 0xAA,
// num timestamps.
0x00,
// largest acked
- 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
// Zero delta time.
0x00, 0x00,
// first ack block length.
- 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
};
// clang-format on
unsigned char* p = packet;
@@ -4223,11 +4223,11 @@ TEST_P(QuicFramerTest, BuildAckFramePacketMultipleAckBlocks) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (ack frame)
// (has ack blocks, 2 byte largest observed, 2 byte block length)
@@ -4262,11 +4262,11 @@ TEST_P(QuicFramerTest, BuildAckFramePacketMultipleAckBlocks) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
// frame type (ack frame)
// (has ack blocks, 2 byte largest observed, 2 byte block length)
@@ -4301,11 +4301,11 @@ TEST_P(QuicFramerTest, BuildAckFramePacketMultipleAckBlocks) {
unsigned char packet41[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
// frame type (ack frame)
// (has ack blocks, 2 byte largest observed, 2 byte block length)
@@ -4375,11 +4375,11 @@ TEST_P(QuicFramerTest, BuildAckFramePacketMaxAckBlocks) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (ack frame)
// (has ack blocks, 2 byte largest observed, 2 byte block length)
0x65,
@@ -4468,11 +4468,11 @@ TEST_P(QuicFramerTest, BuildAckFramePacketMaxAckBlocks) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
// frame type (ack frame)
// (has ack blocks, 2 byte largest observed, 2 byte block length)
0x65,
@@ -4561,11 +4561,11 @@ TEST_P(QuicFramerTest, BuildAckFramePacketMaxAckBlocks) {
unsigned char packet41[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
// frame type (ack frame)
// (has ack blocks, 2 byte largest observed, 2 byte block length)
0xB5,
@@ -4682,32 +4682,30 @@ TEST_P(QuicFramerTest, BuildNewStopWaitingPacket) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (stop waiting frame)
0x06,
// least packet number awaiting an ack, delta from packet number.
- 0x1C, 0x00, 0x00, 0x00,
- 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00,
};
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
+ 0x12, 0x34, 0x56, 0x78,
// frame type (stop waiting frame)
0x06,
// least packet number awaiting an ack, delta from packet number.
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x1C,
+ 0x00, 0x00, 0x00, 0x08,
};
// clang-format on
@@ -4736,12 +4734,11 @@ TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (rst stream frame)
0x01,
@@ -4756,12 +4753,11 @@ TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (rst stream frame)
0x01,
@@ -4776,12 +4772,11 @@ TEST_P(QuicFramerTest, BuildRstFramePacketQuic) {
unsigned char packet41[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (rst stream frame)
0x01,
@@ -4829,12 +4824,11 @@ TEST_P(QuicFramerTest, BuildCloseFramePacket) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (connection close frame)
0x02,
@@ -4851,12 +4845,11 @@ TEST_P(QuicFramerTest, BuildCloseFramePacket) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (connection close frame)
0x02,
@@ -4898,12 +4891,11 @@ TEST_P(QuicFramerTest, BuildTruncatedCloseFramePacket) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (connection close frame)
0x02,
@@ -4948,12 +4940,11 @@ TEST_P(QuicFramerTest, BuildTruncatedCloseFramePacket) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (connection close frame)
0x02,
@@ -5028,12 +5019,11 @@ TEST_P(QuicFramerTest, BuildGoAwayPacket) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (go away frame)
0x03,
@@ -5052,12 +5042,11 @@ TEST_P(QuicFramerTest, BuildGoAwayPacket) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (go away frame)
0x03,
@@ -5102,12 +5091,11 @@ TEST_P(QuicFramerTest, BuildTruncatedGoAwayPacket) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (go away frame)
0x03,
@@ -5154,12 +5142,11 @@ TEST_P(QuicFramerTest, BuildTruncatedGoAwayPacket) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (go away frame)
0x03,
@@ -5235,12 +5222,11 @@ TEST_P(QuicFramerTest, BuildWindowUpdatePacket) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (window update frame)
0x04,
@@ -5253,12 +5239,11 @@ TEST_P(QuicFramerTest, BuildWindowUpdatePacket) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (window update frame)
0x04,
@@ -5295,12 +5280,11 @@ TEST_P(QuicFramerTest, BuildBlockedPacket) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (blocked frame)
0x05,
@@ -5310,12 +5294,11 @@ TEST_P(QuicFramerTest, BuildBlockedPacket) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (blocked frame)
0x05,
@@ -5346,12 +5329,11 @@ TEST_P(QuicFramerTest, BuildPingPacket) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (ping frame)
0x07,
@@ -5359,12 +5341,11 @@ TEST_P(QuicFramerTest, BuildPingPacket) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (ping frame)
0x07,
@@ -5393,12 +5374,11 @@ TEST_P(QuicFramerTest, BuildConnectivityProbingPacket) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (ping frame)
0x07,
@@ -5409,12 +5389,11 @@ TEST_P(QuicFramerTest, BuildConnectivityProbingPacket) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (ping frame)
0x07,
@@ -5461,12 +5440,11 @@ TEST_P(QuicFramerTest, BuildMtuDiscoveryPacket) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (ping frame)
0x07,
@@ -5474,12 +5452,11 @@ TEST_P(QuicFramerTest, BuildMtuDiscoveryPacket) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (ping frame)
0x07,
@@ -5579,12 +5556,11 @@ TEST_P(QuicFramerTest, EncryptPacket) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// redundancy
'a', 'b', 'c', 'd',
@@ -5595,12 +5571,11 @@ TEST_P(QuicFramerTest, EncryptPacket) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// redundancy
'a', 'b', 'c', 'd',
@@ -5615,7 +5590,7 @@ TEST_P(QuicFramerTest, EncryptPacket) {
: packet39),
QUIC_ARRAYSIZE(packet), false, PACKET_8BYTE_CONNECTION_ID,
!kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_6BYTE_PACKET_NUMBER));
+ PACKET_4BYTE_PACKET_NUMBER));
char buffer[kMaxPacketSize];
size_t encrypted_length = framer_.EncryptPayload(
ENCRYPTION_NONE, packet_number, *raw, buffer, kMaxPacketSize);
@@ -5629,14 +5604,13 @@ TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
// clang-format off
unsigned char packet[] = {
// public flags (version, 8 byte connection_id)
- 0x39,
+ 0x29,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// version tag
'Q', '.', '1', '0',
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// redundancy
'a', 'b', 'c', 'd',
@@ -5647,14 +5621,13 @@ TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
unsigned char packet39[] = {
// public flags (version, 8 byte connection_id)
- 0x39,
+ 0x29,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// version tag
'Q', '.', '1', '0',
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// redundancy
'a', 'b', 'c', 'd',
@@ -5669,7 +5642,7 @@ TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
: packet39),
QUIC_ARRAYSIZE(packet), false, PACKET_8BYTE_CONNECTION_ID,
kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_6BYTE_PACKET_NUMBER));
+ PACKET_4BYTE_PACKET_NUMBER));
char buffer[kMaxPacketSize];
size_t encrypted_length = framer_.EncryptPayload(
ENCRYPTION_NONE, packet_number, *raw, buffer, kMaxPacketSize);
@@ -5736,8 +5709,8 @@ TEST_P(QuicFramerTest, AckTruncationSmallPacket) {
ASSERT_EQ(1u, visitor_.ack_frames_.size());
QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
EXPECT_EQ(600u, LargestAcked(processed_ack_frame));
- ASSERT_EQ(239u, processed_ack_frame.packets.NumPacketsSlow());
- EXPECT_EQ(124u, processed_ack_frame.packets.Min());
+ ASSERT_EQ(240u, processed_ack_frame.packets.NumPacketsSlow());
+ EXPECT_EQ(122u, processed_ack_frame.packets.Min());
EXPECT_EQ(600u, processed_ack_frame.packets.Max());
}
@@ -5782,12 +5755,11 @@ TEST_P(QuicFramerTest, StopPacketProcessing) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// frame type (stream frame with fin)
0xFF,
@@ -5820,12 +5792,11 @@ TEST_P(QuicFramerTest, StopPacketProcessing) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (stream frame with fin)
0xFF,
@@ -5858,12 +5829,11 @@ TEST_P(QuicFramerTest, StopPacketProcessing) {
unsigned char packet41[] = {
// public flags (8 byte connection_id)
- 0x38,
+ 0x28,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// frame type (stream frame with fin)
0xFF,
@@ -5934,14 +5904,14 @@ TEST_P(QuicFramerTest, ConstructEncryptedPacket) {
// Since we are using ConstructEncryptedPacket, we have to set the framer's
// crypto to be Null.
framer_.SetDecrypter(ENCRYPTION_NONE,
- new NullDecrypter(framer_.perspective()));
+ QuicMakeUnique<NullDecrypter>(framer_.perspective()));
framer_.SetEncrypter(ENCRYPTION_NONE,
- new NullEncrypter(framer_.perspective()));
+ QuicMakeUnique<NullEncrypter>(framer_.perspective()));
ParsedQuicVersionVector versions;
versions.push_back(framer_.version());
std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
42, false, false, kTestQuicStreamId, kTestString,
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, &versions));
+ PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER, &versions));
MockFramerVisitor visitor;
framer_.set_visitor(&visitor);
@@ -5970,14 +5940,14 @@ TEST_P(QuicFramerTest, ConstructMisFramedEncryptedPacket) {
// Since we are using ConstructEncryptedPacket, we have to set the framer's
// crypto to be Null.
framer_.SetDecrypter(ENCRYPTION_NONE,
- new NullDecrypter(framer_.perspective()));
+ QuicMakeUnique<NullDecrypter>(framer_.perspective()));
framer_.SetEncrypter(ENCRYPTION_NONE,
- new NullEncrypter(framer_.perspective()));
+ QuicMakeUnique<NullEncrypter>(framer_.perspective()));
ParsedQuicVersionVector versions;
versions.push_back(framer_.version());
std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
42, false, false, kTestQuicStreamId, kTestString,
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, &versions,
+ PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER, &versions,
Perspective::IS_CLIENT));
MockFramerVisitor visitor;
@@ -6010,6 +5980,7 @@ extern "C" {
void QuicFramerFuzzFunc(unsigned char* data, size_t size) {
QuicFramer framer(AllSupportedVersions(), QuicTime::Zero(),
Perspective::IS_SERVER);
+ ASSERT_EQ(GetQuicFlag(FLAGS_quic_supports_tls_handshake), true);
const char* const packet_bytes = reinterpret_cast<const char*>(data);
// Test the CryptoFramer.
@@ -6032,12 +6003,11 @@ TEST_P(QuicFramerTest, FramerFuzzTest) {
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
- 0x3C,
+ 0x2C,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
- 0xBC, 0x9A, 0x78, 0x56,
- 0x34, 0x12,
+ 0x78, 0x56, 0x34, 0x12,
// private flags
0x00,
@@ -6058,12 +6028,11 @@ TEST_P(QuicFramerTest, FramerFuzzTest) {
unsigned char packet39[] = {
// public flags (8 byte connection_id)
- 0x3C,
+ 0x2C,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// private flags
0x00,
@@ -6084,12 +6053,11 @@ TEST_P(QuicFramerTest, FramerFuzzTest) {
unsigned char packet41[] = {
// public flags (8 byte connection_id)
- 0x3C,
+ 0x2C,
// connection_id
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
// packet number
0x12, 0x34, 0x56, 0x78,
- 0x9A, 0xBC,
// private flags
0x00,
diff --git a/chromium/net/quic/core/quic_headers_stream.cc b/chromium/net/quic/core/quic_headers_stream.cc
index 22da417ce0b..52e6c41917d 100644
--- a/chromium/net/quic/core/quic_headers_stream.cc
+++ b/chromium/net/quic/core/quic_headers_stream.cc
@@ -26,7 +26,8 @@ QuicHeadersStream::CompressedHeaderInfo::CompressedHeaderInfo(
QuicHeadersStream::CompressedHeaderInfo::~CompressedHeaderInfo() {}
QuicHeadersStream::QuicHeadersStream(QuicSpdySession* session)
- : QuicStream(kHeadersStreamId, session), spdy_session_(session) {
+ : QuicStream(kHeadersStreamId, session, /*is_static=*/true),
+ spdy_session_(session) {
// The headers stream is exempt from connection level flow control.
DisableConnectionFlowControlForThisStream();
}
diff --git a/chromium/net/quic/core/quic_headers_stream_test.cc b/chromium/net/quic/core/quic_headers_stream_test.cc
index 30ca9007bc9..d515adcad4c 100644
--- a/chromium/net/quic/core/quic_headers_stream_test.cc
+++ b/chromium/net/quic/core/quic_headers_stream_test.cc
@@ -76,7 +76,8 @@ class MockVisitor : public SpdyFramerVisitorInterface {
MOCK_METHOD2(OnRstStream,
void(SpdyStreamId stream_id, SpdyErrorCode error_code));
MOCK_METHOD0(OnSettings, void());
- MOCK_METHOD2(OnSetting, void(SpdyKnownSettingsId id, uint32_t value));
+ MOCK_METHOD2(OnSettingOld, void(SpdyKnownSettingsId id, uint32_t value));
+ MOCK_METHOD2(OnSetting, void(SpdySettingsId id, uint32_t value));
MOCK_METHOD0(OnSettingsAck, void());
MOCK_METHOD0(OnSettingsEnd, void());
MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack));
@@ -167,10 +168,11 @@ class QuicHeadersStreamTest : public QuicTestWithParam<TestParams> {
perspective(),
GetVersion())),
session_(connection_),
- headers_stream_(QuicSpdySessionPeer::GetHeadersStream(&session_)),
body_("hello world"),
stream_frame_(kHeadersStreamId, /*fin=*/false, /*offset=*/0, ""),
next_promised_stream_id_(2) {
+ session_.Initialize();
+ headers_stream_ = QuicSpdySessionPeer::GetHeadersStream(&session_);
headers_[":version"] = "HTTP/1.1";
headers_[":status"] = "200 Ok";
headers_["content-length"] = "11";
diff --git a/chromium/net/quic/core/quic_ietf_framer_test.cc b/chromium/net/quic/core/quic_ietf_framer_test.cc
index 5373d6fcf31..daed5d083e9 100644
--- a/chromium/net/quic/core/quic_ietf_framer_test.cc
+++ b/chromium/net/quic/core/quic_ietf_framer_test.cc
@@ -96,20 +96,20 @@ class QuicIetfFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
QuicStreamFrame source_stream_frame(
stream_id, fin_bit, offset, xmit_packet_data, xmit_packet_data_size);
- // write the frame to the packet buffer.
+ // Write the frame to the packet buffer.
EXPECT_TRUE(QuicFramerPeer::AppendIetfStreamFrame(
&framer_, source_stream_frame, last_frame_bit, &writer));
- // better have something in the packet buffer.
+ // Better have something in the packet buffer.
EXPECT_NE(0u, writer.length());
- // now set up a reader to read in the thing in.
+ // Now set up a reader to read in the frame.
QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
- // read in the frame type
+ // Read in the frame type
uint8_t received_frame_type;
EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
EXPECT_EQ(received_frame_type, frame_type);
- // a StreamFrame to hold the results... we know the frame type,
+ // A StreamFrame to hold the results... we know the frame type,
// put it into the QuicIetfStreamFrame
QuicStreamFrame sink_stream_frame;
@@ -123,10 +123,10 @@ class QuicIetfFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
EXPECT_EQ(sink_stream_frame.fin, source_stream_frame.fin);
EXPECT_EQ(sink_stream_frame.data_length, source_stream_frame.data_length);
if (frame_type & IETF_STREAM_FRAME_OFF_BIT) {
- // there was an offset in the frame, see if xmit and rcv vales equal.
+ // There was an offset in the frame, see if xmit and rcv vales equal.
EXPECT_EQ(sink_stream_frame.offset, source_stream_frame.offset);
} else {
- // offset not in frame, so it better come out 0.
+ // Offset not in frame, so it better come out 0.
EXPECT_EQ(sink_stream_frame.offset, 0u);
}
EXPECT_NE(sink_stream_frame.data_buffer, nullptr);
@@ -157,15 +157,14 @@ class QuicIetfFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
QuicAckFrame transmit_frame = InitAckFrame(frame->ranges);
transmit_frame.ack_delay_time =
QuicTime::Delta::FromMicroseconds(frame->delay_time);
- QUIC_LOG(INFO) << "XXXXXXXXXX transmit frame is " << transmit_frame;
- // write the frame to the packet buffer.
- EXPECT_TRUE(QuicFramerPeer::AppendIetfAckFrameAndTypeByte(
- &framer_, transmit_frame, &writer));
- // better have something in the packet buffer.
+ // Write the frame to the packet buffer.
+ EXPECT_TRUE(
+ QuicFramerPeer::AppendIetfAckFrame(&framer_, transmit_frame, &writer));
+ // Better have something in the packet buffer.
EXPECT_NE(0u, writer.length());
- // now set up a reader to read in the thing in.
+ // Now set up a reader to read in the frame.
QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
// read in the frame type
@@ -179,7 +178,7 @@ class QuicIetfFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
EXPECT_TRUE(QuicFramerPeer::ProcessIetfAckFrame(
&framer_, &reader, received_frame_type, &receive_frame));
- // Now check that things are correct
+ // Now check that the received frame matches the sent frame.
EXPECT_EQ(transmit_frame.largest_acked, receive_frame.largest_acked);
// The ~0x7 needs some explaining. The ack frame format down shifts the
// delay time by 3 (divide by 8) to allow for greater ranges in delay time.
@@ -205,6 +204,121 @@ class QuicIetfFramerTest : public QuicTestWithParam<ParsedQuicVersion> {
return true;
}
+ // encode, decode, and check a Path Challenge frame.
+ bool TryPathChallengeFrame(char* packet_buffer,
+ size_t packet_buffer_size,
+ const QuicPathFrameBuffer& data) {
+ // Make a writer so that the serialized packet is placed in
+ // packet_buffer.
+ QuicDataWriter writer(packet_buffer_size, packet_buffer,
+ NETWORK_BYTE_ORDER);
+
+ QuicPathChallengeFrame transmit_frame(0, data);
+
+ // write the frame to the packet buffer.
+ EXPECT_TRUE(QuicFramerPeer::AppendIetfPathChallengeFrame(
+ &framer_, transmit_frame, &writer));
+
+ // Check for correct length in the packet buffer.
+ EXPECT_EQ(kQuicPathChallengeFrameSize, writer.length());
+
+ // now set up a reader to read in the frame.
+ QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
+
+ // read in the frame type
+ uint8_t received_frame_type;
+ EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
+ EXPECT_EQ(received_frame_type, IETF_PATH_CHALLENGE);
+
+ QuicPathChallengeFrame receive_frame;
+
+ EXPECT_TRUE(QuicFramerPeer::ProcessIetfPathChallengeFrame(&framer_, &reader,
+ &receive_frame));
+
+ // Now check that the received frame matches the sent frame.
+ EXPECT_EQ(
+ 0, memcmp(transmit_frame.data_buffer.data(),
+ receive_frame.data_buffer.data(), kQuicPathFrameBufferSize));
+ return true;
+ }
+
+ // encode, decode, and check a Path Response frame.
+ bool TryPathResponseFrame(char* packet_buffer,
+ size_t packet_buffer_size,
+ const QuicPathFrameBuffer& data) {
+ // Make a writer so that the serialized packet is placed in
+ // packet_buffer.
+ QuicDataWriter writer(packet_buffer_size, packet_buffer,
+ NETWORK_BYTE_ORDER);
+
+ QuicPathResponseFrame transmit_frame(0, data);
+
+ // Write the frame to the packet buffer.
+ EXPECT_TRUE(QuicFramerPeer::AppendIetfPathResponseFrame(
+ &framer_, transmit_frame, &writer));
+
+ // Check for correct length in the packet buffer.
+ EXPECT_EQ(kQuicPathResponseFrameSize, writer.length());
+
+ // Set up a reader to read in the frame.
+ QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
+
+ // Read in the frame type
+ uint8_t received_frame_type;
+ EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
+ EXPECT_EQ(received_frame_type, IETF_PATH_RESPONSE);
+
+ QuicPathResponseFrame receive_frame;
+
+ EXPECT_TRUE(QuicFramerPeer::ProcessIetfPathResponseFrame(&framer_, &reader,
+ &receive_frame));
+
+ // Now check that the received frame matches the sent frame.
+ EXPECT_EQ(
+ 0, memcmp(transmit_frame.data_buffer.data(),
+ receive_frame.data_buffer.data(), kQuicPathFrameBufferSize));
+ return true;
+ }
+
+ // Test the Serialization/deserialization of a Reset Stream Frame.
+ void TryResetFrame(char* packet_buffer,
+ size_t packet_buffer_size,
+ QuicStreamId stream_id,
+ QuicRstStreamErrorCode error_code,
+ QuicStreamOffset final_offset) {
+ // Initialize a writer so that the serialized packet is placed in
+ // packet_buffer.
+ QuicDataWriter writer(packet_buffer_size, packet_buffer,
+ NETWORK_BYTE_ORDER);
+
+ QuicRstStreamFrame transmit_frame(static_cast<QuicControlFrameId>(1),
+ stream_id, error_code, final_offset);
+
+ // Write the frame to the packet buffer.
+ EXPECT_TRUE(QuicFramerPeer::AppendIetfResetStreamFrame(
+ &framer_, transmit_frame, &writer));
+ // Check that the size of the serialzed frame is in the allowed range.
+ EXPECT_LT(4u, writer.length());
+ EXPECT_GT(20u, writer.length());
+ // Now set up a reader to read in the thing in.
+ QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
+
+ // Read in the frame type and check that it is IETF_RST_STREAM.
+ uint8_t received_frame_type;
+ EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
+ EXPECT_EQ(received_frame_type, QuicIetfFrameType::IETF_RST_STREAM);
+
+ // A QuicRstStreamFrame to hold the results
+ QuicRstStreamFrame receive_frame;
+ EXPECT_TRUE(QuicFramerPeer::ProcessIetfResetStreamFrame(&framer_, &reader,
+ &receive_frame));
+
+ // Now check that the received values match the input.
+ EXPECT_EQ(receive_frame.stream_id, transmit_frame.stream_id);
+ EXPECT_EQ(receive_frame.error_code, transmit_frame.error_code);
+ EXPECT_EQ(receive_frame.byte_offset, transmit_frame.byte_offset);
+ }
+
QuicTime start_;
QuicFramer framer_;
};
@@ -372,11 +486,7 @@ TEST_F(QuicIetfFramerTest, StreamFrame) {
}
}
-// tests for the ietf connection/application close frames.
-// These are not regular enough to be table driven, so doing
-// explicit tests is what we need to do...
-
-TEST_F(QuicIetfFramerTest, ConnectionClose1) {
+TEST_F(QuicIetfFramerTest, ConnectionCloseEmptyString) {
char packet_buffer[kNormalPacketBufferSize];
// initialize a writer so that the serialized packet is placed in
@@ -384,16 +494,19 @@ TEST_F(QuicIetfFramerTest, ConnectionClose1) {
QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
NETWORK_BYTE_ORDER);
- QuicString test_string = "This is a test of the emergency broadcast system";
+ // empty string,
+ QuicString test_string = "Ich Bin Ein Jelly Donut?";
+ QuicConnectionCloseFrame sent_frame;
+ sent_frame.error_code = static_cast<QuicErrorCode>(0);
+ sent_frame.error_details = test_string;
// write the frame to the packet buffer.
EXPECT_TRUE(QuicFramerPeer::AppendIetfConnectionCloseFrame(
- &framer_, QuicIetfTransportErrorCodes::VERSION_NEGOTIATION_ERROR,
- test_string, &writer));
+ &framer_, sent_frame, &writer));
// better have something in the packet buffer.
EXPECT_NE(0u, writer.length());
- // now set up a reader to read in the thing in.
+ // now set up a reader to read in the frame.
QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
// read in the frame type
@@ -408,14 +521,11 @@ TEST_F(QuicIetfFramerTest, ConnectionClose1) {
&framer_, &reader, received_frame_type, &sink_frame));
// Now check that received == sent
- EXPECT_EQ(sink_frame.error_code,
- static_cast<QuicErrorCode>(
- QuicIetfTransportErrorCodes::VERSION_NEGOTIATION_ERROR));
+ EXPECT_EQ(sink_frame.error_code, static_cast<QuicErrorCode>(0));
EXPECT_EQ(sink_frame.error_details, test_string);
}
-// test case of having no string. also the 0 error code,
-TEST_F(QuicIetfFramerTest, ConnectionClose2) {
+TEST_F(QuicIetfFramerTest, ApplicationCloseEmptyString) {
char packet_buffer[kNormalPacketBufferSize];
// initialize a writer so that the serialized packet is placed in
@@ -424,212 +534,515 @@ TEST_F(QuicIetfFramerTest, ConnectionClose2) {
NETWORK_BYTE_ORDER);
// empty string,
- QuicString test_string;
+ QuicString test_string = "Ich Bin Ein Jelly Donut?";
+ QuicConnectionCloseFrame sent_frame;
+ sent_frame.error_code = static_cast<QuicErrorCode>(0);
+ sent_frame.error_details = test_string;
// write the frame to the packet buffer.
- EXPECT_TRUE(QuicFramerPeer::AppendIetfConnectionCloseFrame(
- &framer_,
- QuicIetfTransportErrorCodes::NO_IETF_QUIC_ERROR, // NO_ERROR == 0
- test_string, &writer));
+ EXPECT_TRUE(QuicFramerPeer::AppendIetfApplicationCloseFrame(
+ &framer_, sent_frame, &writer));
// better have something in the packet buffer.
EXPECT_NE(0u, writer.length());
- // now set up a reader to read in the thing in.
+ // now set up a reader to read in the frame.
QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
// read in the frame type
uint8_t received_frame_type;
EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
- EXPECT_EQ(received_frame_type, QuicIetfFrameType::IETF_CONNECTION_CLOSE);
+ EXPECT_EQ(received_frame_type, QuicIetfFrameType::IETF_APPLICATION_CLOSE);
// a QuicConnectionCloseFrame to hold the results.
QuicConnectionCloseFrame sink_frame;
- EXPECT_TRUE(QuicFramerPeer::ProcessIetfConnectionCloseFrame(
+ EXPECT_TRUE(QuicFramerPeer::ProcessIetfApplicationCloseFrame(
&framer_, &reader, received_frame_type, &sink_frame));
// Now check that received == sent
- EXPECT_EQ(sink_frame.error_code,
- static_cast<QuicErrorCode>(
- QuicIetfTransportErrorCodes::NO_IETF_QUIC_ERROR));
+ EXPECT_EQ(sink_frame.error_code, static_cast<QuicErrorCode>(0));
EXPECT_EQ(sink_frame.error_details, test_string);
}
-// Set fields of the frame via a QuicConnectionClose object
-// test case of having no string. also the 0 error code,
-TEST_F(QuicIetfFramerTest, ConnectionClose3) {
+
+// Testing for the IETF ACK framer.
+// clang-format off
+struct ack_frame ack_frame_variants[] = {
+ { 90000, {{1000, 2001}} },
+ { 0, {{1000, 2001}} },
+ { 1, {{1, 2}, {5, 6}} },
+ { 63, {{1, 2}, {5, 6}} },
+ { 64, {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}}},
+ { 10000, {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}}},
+ { 100000000, {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}}},
+};
+// clang-format on
+
+TEST_F(QuicIetfFramerTest, AckFrame) {
char packet_buffer[kNormalPacketBufferSize];
+ for (auto ack_frame_variant : ack_frame_variants) {
+ EXPECT_TRUE(
+ TryAckFrame(packet_buffer, sizeof(packet_buffer), &ack_frame_variant));
+ }
+}
- // initialize a writer so that the serialized packet is placed in
- // packet_buffer.
+TEST_F(QuicIetfFramerTest, PaddingEntirePacket) {
+ char packet_buffer[kNormalPacketBufferSize];
+
+ // ensure that buffer is not all 0 prior to the test.
+ memset(packet_buffer, 0xff, sizeof(packet_buffer));
+
+ // Set up the writer and transmit QuicPaddingFrame
QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
NETWORK_BYTE_ORDER);
+ QuicPaddingFrame transmit_frame(sizeof(packet_buffer));
- // empty string,
- QuicString test_string = "Ich Bin Ein Jelly Donut?";
- QuicConnectionCloseFrame sent_frame;
- sent_frame.error_code = static_cast<QuicErrorCode>(0);
- sent_frame.error_details = test_string;
- // write the frame to the packet buffer.
- EXPECT_TRUE(QuicFramerPeer::AppendIetfConnectionCloseFrame(
- &framer_, sent_frame, &writer));
+ // Fill buffer with padding.
+ EXPECT_TRUE(QuicFramerPeer::AppendIetfPaddingFrame(&framer_, transmit_frame,
+ &writer));
- // better have something in the packet buffer.
- EXPECT_NE(0u, writer.length());
+ // better have written to the entire packet buffer.
+ EXPECT_EQ(kNormalPacketBufferSize, writer.length());
- // now set up a reader to read in the thing in.
+ // see if entire buffer is 0
+ for (auto i = 0; i != sizeof(packet_buffer); i++) {
+ EXPECT_EQ(0, packet_buffer[i])
+ << "Packet_buffer[" << i << "] is " << packet_buffer[i] << " not 0x00";
+ }
+
+ // set up reader and empty receive QuicPaddingFrame.
QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
+ QuicPaddingFrame receive_frame;
// read in the frame type
uint8_t received_frame_type;
EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
- EXPECT_EQ(received_frame_type, QuicIetfFrameType::IETF_CONNECTION_CLOSE);
-
- // a QuicConnectionCloseFrame to hold the results.
- QuicConnectionCloseFrame sink_frame;
+ EXPECT_EQ(received_frame_type, 0u);
- EXPECT_TRUE(QuicFramerPeer::ProcessIetfConnectionCloseFrame(
- &framer_, &reader, received_frame_type, &sink_frame));
+ // deframe it
+ QuicFramerPeer::ProcessIetfPaddingFrame(&framer_, &reader, &receive_frame);
// Now check that received == sent
- EXPECT_EQ(sink_frame.error_code, static_cast<QuicErrorCode>(0));
- EXPECT_EQ(sink_frame.error_details, test_string);
+ EXPECT_EQ(transmit_frame.num_padding_bytes, receive_frame.num_padding_bytes);
+ int packet_buffer_size = static_cast<int>(sizeof(packet_buffer));
+ EXPECT_EQ(packet_buffer_size, receive_frame.num_padding_bytes);
+ EXPECT_EQ(packet_buffer_size, transmit_frame.num_padding_bytes);
}
-TEST_F(QuicIetfFramerTest, ApplicationClose1) {
+// Place a padding frame between two non-padding frames:
+// app_close
+// padding
+// connection_close
+// we do a loop, with different amounts of padding in each.
+TEST_F(QuicIetfFramerTest, PaddingSandwich) {
+ int pad_lengths[] = {1, 2, 5, 10, 20, 50, 100, 200, 500, 0};
+ int* pad_length = pad_lengths;
+ while (*pad_length) {
+ char packet_buffer[kNormalPacketBufferSize];
+
+ // ensure that buffer is not all 0 prior to the test.
+ memset(packet_buffer, 0xff, sizeof(packet_buffer));
+
+ // Set up the writer and transmit Quic...Frames
+ QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
+ NETWORK_BYTE_ORDER);
+ QuicPaddingFrame transmit_pad_frame(*pad_length);
+ QuicString app_close_test_string = "Ich Bin Ein Jelly Donut?";
+ QuicConnectionCloseFrame transmit_app_close_frame;
+ transmit_app_close_frame.error_code = static_cast<QuicErrorCode>(0);
+ transmit_app_close_frame.error_details = app_close_test_string;
+
+ QuicString conn_close_test_string = "I am a Berliner?";
+ QuicConnectionCloseFrame transmit_conn_close_frame;
+ transmit_conn_close_frame.error_code = static_cast<QuicErrorCode>(0);
+ transmit_conn_close_frame.error_details = conn_close_test_string;
+
+ // Put in the frames. App close first.
+ EXPECT_TRUE(QuicFramerPeer::AppendIetfApplicationCloseFrame(
+ &framer_, transmit_app_close_frame, &writer));
+
+ size_t pre_padding_len = writer.length();
+ // padding next.
+ EXPECT_TRUE(QuicFramerPeer::AppendIetfPaddingFrame(
+ &framer_, transmit_pad_frame, &writer));
+ size_t post_padding_len = writer.length();
+ EXPECT_EQ(static_cast<int>(post_padding_len - pre_padding_len),
+ *pad_length);
+
+ // finally, connection close
+ EXPECT_TRUE(QuicFramerPeer::AppendIetfConnectionCloseFrame(
+ &framer_, transmit_conn_close_frame, &writer));
+
+ // see if buffer from offset pre_padding_len, for *pad_len, is 0
+ for (auto i = pre_padding_len; i != pre_padding_len + (*pad_length); i++) {
+ EXPECT_EQ(0, packet_buffer[i]) << "Packet_buffer[" << i << "] is "
+ << packet_buffer[i] << " not 0x00";
+ }
+
+ // set up reader and empty receive QuicFrames.
+ QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
+ QuicPaddingFrame receive_pad_frame;
+ QuicConnectionCloseFrame receive_app_close_frame;
+ QuicConnectionCloseFrame receive_conn_close_frame;
+
+ // read in the frame type and data for the app-close frame
+ uint8_t received_frame_type;
+ EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
+ EXPECT_EQ(received_frame_type, IETF_APPLICATION_CLOSE);
+ EXPECT_TRUE(QuicFramerPeer::ProcessIetfApplicationCloseFrame(
+ &framer_, &reader, received_frame_type, &receive_app_close_frame));
+
+ // Now the padding.
+ EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
+ EXPECT_EQ(received_frame_type, IETF_PADDING);
+ QuicFramerPeer::ProcessIetfPaddingFrame(&framer_, &reader,
+ &receive_pad_frame);
+ // check that pad size is correct
+ EXPECT_EQ(receive_pad_frame.num_padding_bytes, *pad_length);
+
+ // Now get the connection close frame.
+ EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
+ EXPECT_EQ(received_frame_type, IETF_CONNECTION_CLOSE);
+ EXPECT_TRUE(QuicFramerPeer::ProcessIetfConnectionCloseFrame(
+ &framer_, &reader, received_frame_type, &receive_conn_close_frame));
+
+ pad_length++;
+ }
+}
+
+TEST_F(QuicIetfFramerTest, PathChallengeFrame) {
+ // Double-braces needed on some platforms due to
+ // https://bugs.llvm.org/show_bug.cgi?id=21629
+ QuicPathFrameBuffer buffer0 = {{0, 0, 0, 0, 0, 0, 0, 0}};
+ QuicPathFrameBuffer buffer1 = {
+ {0x80, 0x91, 0xa2, 0xb3, 0xc4, 0xd5, 0xe5, 0xf7}};
char packet_buffer[kNormalPacketBufferSize];
+ EXPECT_TRUE(
+ TryPathChallengeFrame(packet_buffer, sizeof(packet_buffer), buffer0));
+ EXPECT_TRUE(
+ TryPathChallengeFrame(packet_buffer, sizeof(packet_buffer), buffer1));
+}
- // initialize a writer so that the serialized packet is placed in
+TEST_F(QuicIetfFramerTest, PathResponseFrame) {
+ // Double-braces needed on some platforms due to
+ // https://bugs.llvm.org/show_bug.cgi?id=21629
+ QuicPathFrameBuffer buffer0 = {{0, 0, 0, 0, 0, 0, 0, 0}};
+ QuicPathFrameBuffer buffer1 = {
+ {0x80, 0x91, 0xa2, 0xb3, 0xc4, 0xd5, 0xe5, 0xf7}};
+ char packet_buffer[kNormalPacketBufferSize];
+ EXPECT_TRUE(
+ TryPathResponseFrame(packet_buffer, sizeof(packet_buffer), buffer0));
+ EXPECT_TRUE(
+ TryPathResponseFrame(packet_buffer, sizeof(packet_buffer), buffer1));
+}
+
+TEST_F(QuicIetfFramerTest, ResetStreamFrame) {
+ char packet_buffer[kNormalPacketBufferSize];
+ struct resets {
+ QuicStreamId stream_id;
+ QuicRstStreamErrorCode error_code;
+ QuicStreamOffset final_offset;
+ } reset_frames[] = {
+ {0, QUIC_STREAM_NO_ERROR, 0}, {0x10, QUIC_HEADERS_TOO_LARGE, 0x300},
+ };
+ for (auto reset : reset_frames) {
+ TryResetFrame(packet_buffer, sizeof(packet_buffer), reset.stream_id,
+ reset.error_code, reset.final_offset);
+ }
+}
+
+TEST_F(QuicIetfFramerTest, StopSendingFrame) {
+ char packet_buffer[kNormalPacketBufferSize];
+
+ // Make a writer so that the serialized packet is placed in
// packet_buffer.
QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
NETWORK_BYTE_ORDER);
- QuicString test_string = "This is a test of the emergency broadcast system";
- // write the frame to the packet buffer.
- EXPECT_TRUE(QuicFramerPeer::AppendIetfApplicationCloseFrame(
- &framer_,
- static_cast<uint16_t>(QuicErrorCode::QUIC_CRYPTO_VERSION_NOT_SUPPORTED),
- test_string, &writer));
+ QuicStopSendingFrame transmit_frame;
+ transmit_frame.stream_id = 12345;
+ transmit_frame.application_error_code = 543;
- // better have something in the packet buffer.
- EXPECT_NE(0u, writer.length());
+ // Write the frame to the packet buffer.
+ EXPECT_TRUE(QuicFramerPeer::AppendIetfStopSendingFrame(
+ &framer_, transmit_frame, &writer));
+ // Check that the number of bytes in the buffer is in the
+ // allowed range.
+ EXPECT_LE(4u, writer.length());
+ EXPECT_GE(11u, writer.length());
- // now set up a reader to read in the thing in.
QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
- // read in the frame type
+ // Read in the frame type
uint8_t received_frame_type;
EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
- EXPECT_EQ(received_frame_type, QuicIetfFrameType::IETF_APPLICATION_CLOSE);
+ EXPECT_EQ(received_frame_type, IETF_STOP_SENDING);
- // a QuicConnectionCloseFrame to hold the results.
- QuicConnectionCloseFrame sink_frame;
+ // A frame to hold the results
+ QuicStopSendingFrame receive_frame;
- EXPECT_TRUE(QuicFramerPeer::ProcessIetfApplicationCloseFrame(
- &framer_, &reader, received_frame_type, &sink_frame));
+ EXPECT_TRUE(QuicFramerPeer::ProcessIetfStopSendingFrame(&framer_, &reader,
+ &receive_frame));
- // Now check that received == sent
- EXPECT_EQ(sink_frame.error_code,
- QuicErrorCode::QUIC_CRYPTO_VERSION_NOT_SUPPORTED);
- EXPECT_EQ(sink_frame.error_details, test_string);
+ // Verify that the transmitted and received values are the same.
+ EXPECT_EQ(receive_frame.stream_id, 12345u);
+ EXPECT_EQ(receive_frame.application_error_code, 543u);
+ EXPECT_EQ(receive_frame.stream_id, transmit_frame.stream_id);
+ EXPECT_EQ(receive_frame.application_error_code,
+ transmit_frame.application_error_code);
}
-// test case of having no string. also the 0 error code,
-TEST_F(QuicIetfFramerTest, ApplicationClose2) {
+TEST_F(QuicIetfFramerTest, MaxDataFrame) {
char packet_buffer[kNormalPacketBufferSize];
+ QuicStreamOffset window_sizes[] = {0, 1, 2, 5, 10,
+ 20, 50, 100, 200, 500,
+ 1000000, kOffset8, kOffset4, kOffset2};
+ for (QuicStreamOffset window_size : window_sizes) {
+ memset(packet_buffer, 0, sizeof(packet_buffer));
+
+ // Set up the writer and transmit QuicWindowUpdateFrame
+ QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
+ NETWORK_BYTE_ORDER);
+ QuicWindowUpdateFrame transmit_frame(0, 99, window_size);
- // initialize a writer so that the serialized packet is placed in
- // packet_buffer.
- QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
- NETWORK_BYTE_ORDER);
+ // Add the frame.
+ EXPECT_TRUE(QuicFramerPeer::AppendIetfMaxDataFrame(&framer_, transmit_frame,
+ &writer));
- // empty string,
- QuicString test_string;
- // write the frame to the packet buffer.
- EXPECT_TRUE(QuicFramerPeer::AppendIetfApplicationCloseFrame(
- &framer_, 0, test_string, &writer));
+ // Check that the number of bytes in the buffer is in the expected range.
+ EXPECT_LE(2u, writer.length());
+ EXPECT_GE(9u, writer.length());
- // better have something in the packet buffer.
- EXPECT_NE(0u, writer.length());
+ // Set up reader and an empty QuicWindowUpdateFrame
+ QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
+ QuicWindowUpdateFrame receive_frame;
- // now set up a reader to read in the thing in.
- QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
+ // Read in the frame type
+ uint8_t received_frame_type;
+ EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
+ EXPECT_EQ(received_frame_type, IETF_MAX_DATA);
- // read in the frame type
- uint8_t received_frame_type;
- EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
- EXPECT_EQ(received_frame_type, QuicIetfFrameType::IETF_APPLICATION_CLOSE);
+ // Deframe it
+ EXPECT_TRUE(QuicFramerPeer::ProcessIetfMaxDataFrame(&framer_, &reader,
+ &receive_frame));
- // a QuicConnectionCloseFrame to hold the results.
- QuicConnectionCloseFrame sink_frame;
+ // Now check that the received data equals the sent data.
+ EXPECT_EQ(transmit_frame.byte_offset, window_size);
+ EXPECT_EQ(transmit_frame.byte_offset, receive_frame.byte_offset);
+ EXPECT_EQ(0u, receive_frame.stream_id);
+ }
+}
- EXPECT_TRUE(QuicFramerPeer::ProcessIetfApplicationCloseFrame(
- &framer_, &reader, received_frame_type, &sink_frame));
+TEST_F(QuicIetfFramerTest, MaxStreamDataFrame) {
+ char packet_buffer[kNormalPacketBufferSize];
+ QuicStreamOffset window_sizes[] = {0, 1, 2, 5, 10,
+ 20, 50, 100, 200, 500,
+ 1000000, kOffset8, kOffset4, kOffset2};
+ QuicIetfStreamId stream_ids[] = {kStreamId4, kStreamId2, kStreamId1,
+ kStreamId0};
+
+ for (QuicIetfStreamId stream_id : stream_ids) {
+ for (QuicStreamOffset window_size : window_sizes) {
+ memset(packet_buffer, 0, sizeof(packet_buffer));
+
+ // Set up the writer and transmit QuicWindowUpdateFrame
+ QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
+ NETWORK_BYTE_ORDER);
+ QuicWindowUpdateFrame transmit_frame(0, stream_id, window_size);
+
+ // Add the frame.
+ EXPECT_TRUE(QuicFramerPeer::AppendIetfMaxStreamDataFrame(
+ &framer_, transmit_frame, &writer));
+
+ // Check that number of bytes in the buffer is in the expected range.
+ EXPECT_LE(3u, writer.length());
+ EXPECT_GE(17u, writer.length());
+
+ // Set up reader and empty receive QuicPaddingFrame.
+ QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
+ QuicWindowUpdateFrame receive_frame;
+
+ // Read in the frame type
+ uint8_t received_frame_type;
+ EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
+ EXPECT_EQ(received_frame_type, IETF_MAX_STREAM_DATA);
+
+ // Deframe it
+ EXPECT_TRUE(QuicFramerPeer::ProcessIetfMaxStreamDataFrame(
+ &framer_, &reader, &receive_frame));
+
+ // Now check that received data and sent data are equal.
+ EXPECT_EQ(transmit_frame.byte_offset, window_size);
+ EXPECT_EQ(transmit_frame.byte_offset, receive_frame.byte_offset);
+ EXPECT_EQ(stream_id, receive_frame.stream_id);
+ EXPECT_EQ(transmit_frame.stream_id, receive_frame.stream_id);
+ }
+ }
+}
- // Now check that received == sent
- EXPECT_EQ(sink_frame.error_code, 0);
- EXPECT_EQ(sink_frame.error_details, test_string);
+TEST_F(QuicIetfFramerTest, MaxStreamIdFrame) {
+ char packet_buffer[kNormalPacketBufferSize];
+ QuicIetfStreamId stream_ids[] = {kStreamId4, kStreamId2, kStreamId1,
+ kStreamId0};
+
+ for (QuicIetfStreamId stream_id : stream_ids) {
+ memset(packet_buffer, 0, sizeof(packet_buffer));
+
+ // Set up the writer and transmit QuicIetfMaxStreamIdFrame
+ QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
+ NETWORK_BYTE_ORDER);
+ QuicIetfMaxStreamIdFrame transmit_frame(0, stream_id);
+
+ // Add the frame.
+ EXPECT_TRUE(QuicFramerPeer::AppendIetfMaxStreamIdFrame(
+ &framer_, transmit_frame, &writer));
+
+ // Check that buffer length is in the expected range
+ EXPECT_LE(2u, writer.length());
+ EXPECT_GE(9u, writer.length());
+
+ // Set up reader and empty receive QuicPaddingFrame.
+ QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
+ QuicIetfMaxStreamIdFrame receive_frame;
+
+ // Read in the frame type
+ uint8_t received_frame_type;
+ EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
+ EXPECT_EQ(received_frame_type, IETF_MAX_STREAM_ID);
+
+ // Deframe it
+ EXPECT_TRUE(QuicFramerPeer::ProcessIetfMaxStreamIdFrame(&framer_, &reader,
+ &receive_frame));
+
+ // Now check that received and sent data are equivalent
+ EXPECT_EQ(stream_id, receive_frame.max_stream_id);
+ EXPECT_EQ(transmit_frame.max_stream_id, receive_frame.max_stream_id);
+ }
}
-// Set fields of the frame via a QuicConnectionClose object wahoo
-// test case of having no string. also the 0 error code,
-TEST_F(QuicIetfFramerTest, ApplicationClose3) {
+TEST_F(QuicIetfFramerTest, BlockedFrame) {
char packet_buffer[kNormalPacketBufferSize];
+ QuicStreamOffset offsets[] = {kOffset8, kOffset4, kOffset2, kOffset1,
+ kOffset0};
- // initialize a writer so that the serialized packet is placed in
- // packet_buffer.
- QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
- NETWORK_BYTE_ORDER);
+ for (QuicStreamOffset offset : offsets) {
+ memset(packet_buffer, 0, sizeof(packet_buffer));
- // empty string,
- QuicString test_string = "Ich Bin Ein Jelly Donut?";
- QuicConnectionCloseFrame sent_frame;
- sent_frame.error_code = static_cast<QuicErrorCode>(0);
- sent_frame.error_details = test_string;
- // write the frame to the packet buffer.
- EXPECT_TRUE(QuicFramerPeer::AppendIetfApplicationCloseFrame(
- &framer_, sent_frame, &writer));
+ // Set up the writer and transmit QuicIetfBlockedFrame
+ QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
+ NETWORK_BYTE_ORDER);
+ QuicIetfBlockedFrame transmit_frame(0, offset);
- // better have something in the packet buffer.
- EXPECT_NE(0u, writer.length());
+ // Add the frame.
+ EXPECT_TRUE(QuicFramerPeer::AppendIetfBlockedFrame(&framer_, transmit_frame,
+ &writer));
- // now set up a reader to read in the thing in.
- QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
+ // Check that buffer length is in the expected range
+ EXPECT_LE(2u, writer.length());
+ EXPECT_GE(9u, writer.length());
- // read in the frame type
- uint8_t received_frame_type;
- EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
- EXPECT_EQ(received_frame_type, QuicIetfFrameType::IETF_APPLICATION_CLOSE);
+ // Set up reader and empty receive QuicFrame.
+ QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
+ QuicIetfBlockedFrame receive_frame;
- // a QuicConnectionCloseFrame to hold the results.
- QuicConnectionCloseFrame sink_frame;
+ // Read in the frame type
+ uint8_t received_frame_type;
+ EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
+ EXPECT_EQ(received_frame_type, IETF_BLOCKED);
- EXPECT_TRUE(QuicFramerPeer::ProcessIetfApplicationCloseFrame(
- &framer_, &reader, received_frame_type, &sink_frame));
+ // Deframe it
+ EXPECT_TRUE(QuicFramerPeer::ProcessIetfBlockedFrame(&framer_, &reader,
+ &receive_frame));
- // Now check that received == sent
- EXPECT_EQ(sink_frame.error_code, static_cast<QuicErrorCode>(0));
- EXPECT_EQ(sink_frame.error_details, test_string);
+ // Check that received and sent data are equivalent
+ EXPECT_EQ(offset, receive_frame.offset);
+ EXPECT_EQ(transmit_frame.offset, receive_frame.offset);
+ }
}
-// Testing for the IETF ACK framer.
-// clang-format off
-struct ack_frame ack_frame_variants[] = {
- { 90000, {{1000, 2001}} },
- { 0, {{1000, 2001}} },
- { 1, {{1, 2}, {5, 6}} },
- { 63, {{1, 2}, {5, 6}} },
- { 64, {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}}},
- { 10000, {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}}},
- { 100000000, {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}}},
-};
-// clang-format on
+TEST_F(QuicIetfFramerTest, StreamBlockedFrame) {
+ char packet_buffer[kNormalPacketBufferSize];
+ QuicStreamOffset offsets[] = {0, 1, 2, 5, 10,
+ 20, 50, 100, 200, 500,
+ 1000000, kOffset8, kOffset4, kOffset2};
+ QuicIetfStreamId stream_ids[] = {kStreamId4, kStreamId2, kStreamId1,
+ kStreamId0};
+
+ for (QuicIetfStreamId stream_id : stream_ids) {
+ for (QuicStreamOffset offset : offsets) {
+ memset(packet_buffer, 0, sizeof(packet_buffer));
+
+ // Set up the writer and transmit QuicWindowUpdateFrame
+ QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
+ NETWORK_BYTE_ORDER);
+ QuicWindowUpdateFrame transmit_frame(0, stream_id, offset);
+
+ // Add the frame.
+ EXPECT_TRUE(QuicFramerPeer::AppendIetfStreamBlockedFrame(
+ &framer_, transmit_frame, &writer));
+
+ // Check that number of bytes in the buffer is in the expected range.
+ EXPECT_LE(3u, writer.length());
+ EXPECT_GE(17u, writer.length());
+
+ // Set up reader and empty receive QuicPaddingFrame.
+ QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
+ QuicWindowUpdateFrame receive_frame;
+
+ // Read in the frame type
+ uint8_t received_frame_type;
+ EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
+ EXPECT_EQ(received_frame_type, IETF_STREAM_BLOCKED);
+
+ // Deframe it
+ EXPECT_TRUE(QuicFramerPeer::ProcessIetfStreamBlockedFrame(
+ &framer_, &reader, &receive_frame));
+
+ // Now check that received == sent
+ EXPECT_EQ(transmit_frame.byte_offset, offset);
+ EXPECT_EQ(transmit_frame.byte_offset, receive_frame.byte_offset);
+ EXPECT_EQ(stream_id, receive_frame.stream_id);
+ EXPECT_EQ(transmit_frame.stream_id, receive_frame.stream_id);
+ }
+ }
+}
-TEST_F(QuicIetfFramerTest, AckFrame) {
+TEST_F(QuicIetfFramerTest, StreamIdBlockedFrame) {
char packet_buffer[kNormalPacketBufferSize];
- for (auto ack_frame_variant : ack_frame_variants) {
- QUIC_LOG(INFO) << "Doing an ack, delay = " << ack_frame_variant.delay_time;
- EXPECT_TRUE(
- TryAckFrame(packet_buffer, sizeof(packet_buffer), &ack_frame_variant));
+ QuicIetfStreamId stream_ids[] = {kStreamId4, kStreamId2, kStreamId1,
+ kStreamId0};
+
+ for (QuicIetfStreamId stream_id : stream_ids) {
+ memset(packet_buffer, 0, sizeof(packet_buffer));
+
+ // Set up the writer and transmit QuicIetfStreamIdBlockedFrame
+ QuicDataWriter writer(sizeof(packet_buffer), packet_buffer,
+ NETWORK_BYTE_ORDER);
+ QuicIetfStreamIdBlockedFrame transmit_frame(0, stream_id);
+
+ // Add the frame.
+ EXPECT_TRUE(QuicFramerPeer::AppendIetfStreamIdBlockedFrame(
+ &framer_, transmit_frame, &writer));
+
+ // Check that buffer length is in the expected range
+ EXPECT_LE(2u, writer.length());
+ EXPECT_GE(9u, writer.length());
+
+ // Set up reader and empty receive QuicPaddingFrame.
+ QuicDataReader reader(packet_buffer, writer.length(), NETWORK_BYTE_ORDER);
+ QuicIetfStreamIdBlockedFrame receive_frame;
+
+ // Read in the frame type
+ uint8_t received_frame_type;
+ EXPECT_TRUE(reader.ReadUInt8(&received_frame_type));
+ EXPECT_EQ(received_frame_type, IETF_STREAM_ID_BLOCKED);
+
+ // Deframe it
+ EXPECT_TRUE(QuicFramerPeer::ProcessIetfStreamIdBlockedFrame(
+ &framer_, &reader, &receive_frame));
+
+ // Now check that received == sent
+ EXPECT_EQ(stream_id, receive_frame.stream_id);
+ EXPECT_EQ(transmit_frame.stream_id, receive_frame.stream_id);
}
}
diff --git a/chromium/net/quic/core/quic_packet_creator.cc b/chromium/net/quic/core/quic_packet_creator.cc
index 27ed0b93401..0d05a8c2dee 100644
--- a/chromium/net/quic/core/quic_packet_creator.cc
+++ b/chromium/net/quic/core/quic_packet_creator.cc
@@ -54,8 +54,8 @@ QuicPacketCreator::~QuicPacketCreator() {
}
void QuicPacketCreator::SetEncrypter(EncryptionLevel level,
- QuicEncrypter* encrypter) {
- framer_->SetEncrypter(level, encrypter);
+ std::unique_ptr<QuicEncrypter> encrypter) {
+ framer_->SetEncrypter(level, std::move(encrypter));
max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
}
@@ -182,7 +182,7 @@ void QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
QuicFrame* frame) {
DCHECK_GT(max_packet_length_,
StreamFramePacketOverhead(framer_->transport_version(),
- connection_id_length_, kIncludeVersion,
+ GetConnectionIdLength(), kIncludeVersion,
IncludeNonceInPublicHeader(),
PACKET_6BYTE_PACKET_NUMBER, offset));
@@ -398,10 +398,10 @@ size_t QuicPacketCreator::PacketSize() {
if (!queued_frames_.empty()) {
return packet_size_;
}
- packet_size_ =
- GetPacketHeaderSize(framer_->transport_version(), connection_id_length_,
- send_version_in_packet_, IncludeNonceInPublicHeader(),
- packet_.packet_number_length);
+ packet_size_ = GetPacketHeaderSize(
+ framer_->transport_version(), GetConnectionIdLength(),
+ IncludeVersionInHeader(), IncludeNonceInPublicHeader(),
+ GetPacketNumberLength());
return packet_size_;
}
@@ -467,10 +467,11 @@ void QuicPacketCreator::SerializePacket(char* encrypted_buffer,
std::unique_ptr<QuicEncryptedPacket>
QuicPacketCreator::SerializeVersionNegotiationPacket(
+ bool ietf_quic,
const ParsedQuicVersionVector& supported_versions) {
DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
std::unique_ptr<QuicEncryptedPacket> encrypted =
- QuicFramer::BuildVersionNegotiationPacket(connection_id_,
+ QuicFramer::BuildVersionNegotiationPacket(connection_id_, ietf_quic,
supported_versions);
DCHECK(encrypted);
DCHECK_GE(max_packet_length_, encrypted->length());
@@ -504,17 +505,25 @@ QuicPacketCreator::SerializeConnectivityProbingPacket() {
return serialize_packet;
}
-// TODO(jri): Make this a public method of framer?
+// TODO(b/74062209): Make this a public method of framer?
SerializedPacket QuicPacketCreator::NoPacket() {
return SerializedPacket(0, PACKET_1BYTE_PACKET_NUMBER, nullptr, 0, false,
false);
}
+QuicConnectionIdLength QuicPacketCreator::GetConnectionIdLength() const {
+ return connection_id_length_;
+}
+
+QuicPacketNumberLength QuicPacketCreator::GetPacketNumberLength() const {
+ return packet_.packet_number_length;
+}
+
void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
header->connection_id = connection_id_;
- header->connection_id_length = connection_id_length_;
+ header->connection_id_length = GetConnectionIdLength();
header->reset_flag = false;
- header->version_flag = send_version_in_packet_;
+ header->version_flag = IncludeVersionInHeader();
if (IncludeNonceInPublicHeader()) {
DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
header->nonce = &diversification_nonce_;
@@ -553,7 +562,7 @@ bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
}
size_t frame_len = framer_->GetSerializedFrameLength(
frame, BytesFree(), queued_frames_.empty(), true,
- packet_.packet_number_length);
+ GetPacketNumberLength());
if (frame_len == 0) {
// Current open packet is full.
Flush();
@@ -618,11 +627,15 @@ void QuicPacketCreator::MaybeAddPadding() {
DCHECK(success);
}
-bool QuicPacketCreator::IncludeNonceInPublicHeader() {
+bool QuicPacketCreator::IncludeNonceInPublicHeader() const {
return have_diversification_nonce_ &&
packet_.encryption_level == ENCRYPTION_INITIAL;
}
+bool QuicPacketCreator::IncludeVersionInHeader() const {
+ return send_version_in_packet_;
+}
+
void QuicPacketCreator::AddPendingPadding(QuicByteCount size) {
pending_padding_bytes_ += size;
}
@@ -644,8 +657,9 @@ void QuicPacketCreator::SetConnectionIdLength(QuicConnectionIdLength length) {
void QuicPacketCreator::SetTransmissionType(TransmissionType type) {
DCHECK(can_set_transmission_type_);
- QUIC_DVLOG(1) << "Setting Transmission type to "
- << QuicUtils::TransmissionTypeToString(type);
+ QUIC_DVLOG_IF(1, type != packet_.transmission_type)
+ << "Setting Transmission type to "
+ << QuicUtils::TransmissionTypeToString(type);
packet_.transmission_type = type;
}
diff --git a/chromium/net/quic/core/quic_packet_creator.h b/chromium/net/quic/core/quic_packet_creator.h
index b03e5803868..03af92ff215 100644
--- a/chromium/net/quic/core/quic_packet_creator.h
+++ b/chromium/net/quic/core/quic_packet_creator.h
@@ -153,6 +153,7 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
// Creates a version negotiation packet which supports |supported_versions|.
std::unique_ptr<QuicEncryptedPacket> SerializeVersionNegotiationPacket(
+ bool ietf_quic,
const ParsedQuicVersionVector& supported_versions);
// Creates a connectivity probing packet.
@@ -161,6 +162,9 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
// Returns a dummy packet that is valid but contains no useful information.
static SerializedPacket NoPacket();
+ // Returns length of connection ID to send over the wire.
+ QuicConnectionIdLength GetConnectionIdLength() const;
+
// Sets the encryption level that will be applied to new packets.
void set_encryption_level(EncryptionLevel level) {
packet_.encryption_level = level;
@@ -170,10 +174,6 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
// created.
QuicPacketNumber packet_number() const { return packet_.packet_number; }
- QuicConnectionIdLength connection_id_length() const {
- return connection_id_length_;
- }
-
void SetConnectionIdLength(QuicConnectionIdLength length);
QuicByteCount max_packet_length() const { return max_packet_length_; }
@@ -184,7 +184,8 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
// Sets the encrypter to use for the encryption level and updates the max
// plaintext size.
- void SetEncrypter(EncryptionLevel level, QuicEncrypter* encrypter);
+ void SetEncrypter(EncryptionLevel level,
+ std::unique_ptr<QuicEncrypter> encrypter);
// Indicates whether the packet creator is in a state where it can change
// current maximum packet length.
@@ -251,7 +252,15 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
// Returns true if a diversification nonce should be included in the current
// packet's header.
- bool IncludeNonceInPublicHeader();
+ bool IncludeNonceInPublicHeader() const;
+
+ // Returns true if version should be included in current packet's header.
+ bool IncludeVersionInHeader() const;
+
+ // Returns length of packet number to send over the wire.
+ // packet_.packet_number_length should never be read directly, use this
+ // function instead.
+ QuicPacketNumberLength GetPacketNumberLength() const;
// Returns true if |frame| starts with CHLO.
bool StreamFrameStartsWithChlo(const QuicStreamFrame& frame) const;
@@ -262,6 +271,8 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
QuicFramer* framer_;
// Controls whether version should be included while serializing the packet.
+ // send_version_in_packet_ should never be read directly, use
+ // IncludeVersionInHeader() instead.
bool send_version_in_packet_;
// If true, then |diversification_nonce_| will be included in the header of
// all packets created at the initial encryption level.
@@ -270,7 +281,8 @@ class QUIC_EXPORT_PRIVATE QuicPacketCreator {
// Maximum length including headers and encryption (UDP payload length.)
QuicByteCount max_packet_length_;
size_t max_plaintext_size_;
- // Length of connection_id to send over the wire.
+ // Length of connection_id to send over the wire. connection_id_length_ should
+ // never be read directly, use GetConnectionIdLength() instead.
QuicConnectionIdLength connection_id_length_;
// Frames to be added to the next SerializedPacket
diff --git a/chromium/net/quic/core/quic_packet_creator_test.cc b/chromium/net/quic/core/quic_packet_creator_test.cc
index 7dbb617d3ee..342b5b2ec2a 100644
--- a/chromium/net/quic/core/quic_packet_creator_test.cc
+++ b/chromium/net/quic/core/quic_packet_creator_test.cc
@@ -135,10 +135,11 @@ class QuicPacketCreatorTest : public QuicTestWithParam<TestParams> {
data_("foo"),
creator_(connection_id_, &client_framer_, &delegate_, &producer_),
serialized_packet_(creator_.NoPacket()) {
- creator_.SetEncrypter(ENCRYPTION_INITIAL,
- new NullEncrypter(Perspective::IS_CLIENT));
- creator_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- new NullEncrypter(Perspective::IS_CLIENT));
+ creator_.SetEncrypter(ENCRYPTION_INITIAL, QuicMakeUnique<NullEncrypter>(
+ Perspective::IS_CLIENT));
+ creator_.SetEncrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
client_framer_.set_visitor(&framer_visitor_);
server_framer_.set_visitor(&framer_visitor_);
client_framer_.set_data_producer(&producer_);
@@ -186,7 +187,8 @@ class QuicPacketCreatorTest : public QuicTestWithParam<TestParams> {
// the version.
size_t GetPacketHeaderOverhead(QuicTransportVersion version) {
return GetPacketHeaderSize(
- version, creator_.connection_id_length(), kIncludeVersion,
+ version, creator_.GetConnectionIdLength(),
+ QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
!kIncludeDiversificationNonce,
QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
}
@@ -668,7 +670,7 @@ TEST_P(QuicPacketCreatorTest, SerializeVersionNegotiationPacket) {
ParsedQuicVersionVector versions;
versions.push_back(test::QuicVersionMax());
std::unique_ptr<QuicEncryptedPacket> encrypted(
- creator_.SerializeVersionNegotiationPacket(versions));
+ creator_.SerializeVersionNegotiationPacket(false, versions));
{
InSequence s;
@@ -798,8 +800,9 @@ TEST_P(QuicPacketCreatorTest, ConsumeDataLargerThanOneStreamFrame) {
creator_.SetMaxPacketLength(GetPacketLengthForOneStream(
client_framer_.transport_version(),
QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
- !kIncludeDiversificationNonce, creator_.connection_id_length(),
- PACKET_1BYTE_PACKET_NUMBER, &payload_length));
+ !kIncludeDiversificationNonce, creator_.GetConnectionIdLength(),
+ QuicPacketCreatorPeer::GetPacketNumberLength(&creator_),
+ &payload_length));
QuicFrame frame;
const QuicString too_long_payload(payload_length * 2, 'a');
MakeIOVector(too_long_payload, &iov_);
@@ -827,9 +830,10 @@ TEST_P(QuicPacketCreatorTest, AddFrameAndFlush) {
EXPECT_EQ(max_plaintext_size -
GetPacketHeaderSize(
client_framer_.transport_version(),
- creator_.connection_id_length(),
+ creator_.GetConnectionIdLength(),
QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
- !kIncludeDiversificationNonce, PACKET_1BYTE_PACKET_NUMBER),
+ !kIncludeDiversificationNonce,
+ QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)),
creator_.BytesFree());
// Add a variety of frame types and then a padding frame.
@@ -874,9 +878,10 @@ TEST_P(QuicPacketCreatorTest, AddFrameAndFlush) {
EXPECT_EQ(max_plaintext_size -
GetPacketHeaderSize(
client_framer_.transport_version(),
- creator_.connection_id_length(),
+ creator_.GetConnectionIdLength(),
QuicPacketCreatorPeer::SendVersionInPacket(&creator_),
- !kIncludeDiversificationNonce, PACKET_1BYTE_PACKET_NUMBER),
+ !kIncludeDiversificationNonce,
+ QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)),
creator_.BytesFree());
}
@@ -982,9 +987,9 @@ TEST_P(QuicPacketCreatorTest, SendPendingPaddingInRetransmission) {
QuicFrames frames;
frames.push_back(QuicFrame(stream_frame));
char buffer[kMaxPacketSize];
- QuicPendingRetransmission retransmission(
- CreateRetransmission(frames, true, /*num_padding_bytes=*/0,
- ENCRYPTION_NONE, PACKET_1BYTE_PACKET_NUMBER));
+ QuicPendingRetransmission retransmission(CreateRetransmission(
+ frames, true, /*num_padding_bytes=*/0, ENCRYPTION_NONE,
+ QuicPacketCreatorPeer::GetPacketNumberLength(&creator_)));
EXPECT_CALL(delegate_, OnSerializedPacket(_))
.WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
creator_.AddPendingPadding(kMaxNumRandomPaddingBytes);
diff --git a/chromium/net/quic/core/quic_packet_generator.cc b/chromium/net/quic/core/quic_packet_generator.cc
index 85814b40409..5c2471c2f4d 100644
--- a/chromium/net/quic/core/quic_packet_generator.cc
+++ b/chromium/net/quic/core/quic_packet_generator.cc
@@ -309,8 +309,10 @@ void QuicPacketGenerator::SetMaxPacketLength(QuicByteCount length) {
std::unique_ptr<QuicEncryptedPacket>
QuicPacketGenerator::SerializeVersionNegotiationPacket(
+ bool ietf_quic,
const ParsedQuicVersionVector& supported_versions) {
- return packet_creator_.SerializeVersionNegotiationPacket(supported_versions);
+ return packet_creator_.SerializeVersionNegotiationPacket(ietf_quic,
+ supported_versions);
}
OwningSerializedPacketPointer
@@ -344,9 +346,10 @@ void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) {
packet_creator_.set_encryption_level(level);
}
-void QuicPacketGenerator::SetEncrypter(EncryptionLevel level,
- QuicEncrypter* encrypter) {
- packet_creator_.SetEncrypter(level, encrypter);
+void QuicPacketGenerator::SetEncrypter(
+ EncryptionLevel level,
+ std::unique_ptr<QuicEncrypter> encrypter) {
+ packet_creator_.SetEncrypter(level, std::move(encrypter));
}
void QuicPacketGenerator::AddRandomPadding() {
diff --git a/chromium/net/quic/core/quic_packet_generator.h b/chromium/net/quic/core/quic_packet_generator.h
index f1cfd7978e9..08176a969ff 100644
--- a/chromium/net/quic/core/quic_packet_generator.h
+++ b/chromium/net/quic/core/quic_packet_generator.h
@@ -137,6 +137,7 @@ class QUIC_EXPORT_PRIVATE QuicPacketGenerator {
// Creates a version negotiation packet which supports |supported_versions|.
std::unique_ptr<QuicEncryptedPacket> SerializeVersionNegotiationPacket(
+ bool ietf_quic,
const ParsedQuicVersionVector& supported_versions);
// Creates a connectivity probing packet.
@@ -157,7 +158,8 @@ class QUIC_EXPORT_PRIVATE QuicPacketGenerator {
void SetConnectionIdLength(uint32_t length);
// Sets the encrypter to use for the encryption level.
- void SetEncrypter(EncryptionLevel level, QuicEncrypter* encrypter);
+ void SetEncrypter(EncryptionLevel level,
+ std::unique_ptr<QuicEncrypter> encrypter);
// Returns true if there are control frames or current constructed packet has
// pending retransmittable frames.
diff --git a/chromium/net/quic/core/quic_packet_generator_test.cc b/chromium/net/quic/core/quic_packet_generator_test.cc
index 074eb4ebbdc..b2e4905f6cd 100644
--- a/chromium/net/quic/core/quic_packet_generator_test.cc
+++ b/chromium/net/quic/core/quic_packet_generator_test.cc
@@ -26,6 +26,7 @@
#include "net/quic/test_tools/simple_data_producer.h"
#include "net/quic/test_tools/simple_quic_framer.h"
+using std::string;
using testing::_;
using testing::InSequence;
using testing::Return;
@@ -150,8 +151,9 @@ class QuicPacketGeneratorTest : public QuicTest {
Perspective::IS_CLIENT),
generator_(42, &framer_, &random_generator_, &delegate_, &producer_),
creator_(QuicPacketGeneratorPeer::GetPacketCreator(&generator_)) {
- creator_->SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- new NullEncrypter(Perspective::IS_CLIENT));
+ creator_->SetEncrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
creator_->set_encryption_level(ENCRYPTION_FORWARD_SECURE);
framer_.set_data_producer(&producer_);
generator_.AttachPacketFlusher();
@@ -511,8 +513,9 @@ TEST_F(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) {
size_t length =
NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) +
GetPacketHeaderSize(
- framer_.transport_version(), creator_->connection_id_length(),
- kIncludeVersion, !kIncludeDiversificationNonce,
+ framer_.transport_version(), creator_->GetConnectionIdLength(),
+ QuicPacketCreatorPeer::SendVersionInPacket(creator_),
+ !kIncludeDiversificationNonce,
QuicPacketCreatorPeer::GetPacketNumberLength(creator_)) +
// Add an extra 3 bytes for the payload and 1 byte so BytesFree is larger
// than the GetMinStreamFrameSize.
@@ -774,11 +777,11 @@ TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations2) {
TEST_F(QuicPacketGeneratorTest, TestConnectionIdLength) {
QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
generator_.SetConnectionIdLength(0);
- EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID, creator_->connection_id_length());
+ EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID, creator_->GetConnectionIdLength());
for (size_t i = 1; i < 10; i++) {
generator_.SetConnectionIdLength(i);
- EXPECT_EQ(PACKET_8BYTE_CONNECTION_ID, creator_->connection_id_length());
+ EXPECT_EQ(PACKET_8BYTE_CONNECTION_ID, creator_->GetConnectionIdLength());
}
}
@@ -1066,7 +1069,7 @@ TEST_F(QuicPacketGeneratorTest, ConnectionCloseFrameLargerThanPacketSize) {
frame->error_code = QUIC_PACKET_WRITE_ERROR;
char buf[2000] = {};
QuicStringPiece error_details(buf, 2000);
- frame->error_details = error_details.as_string();
+ frame->error_details = string(error_details);
generator_.AddControlFrame(QuicFrame(frame));
EXPECT_TRUE(generator_.HasQueuedFrames());
EXPECT_TRUE(generator_.HasRetransmittableFrames());
@@ -1081,8 +1084,9 @@ TEST_F(QuicPacketGeneratorTest, RandomPaddingAfterFinSingleStreamSinglePacket) {
size_t length =
NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) +
GetPacketHeaderSize(
- framer_.transport_version(), creator_->connection_id_length(),
- kIncludeVersion, !kIncludeDiversificationNonce,
+ framer_.transport_version(), creator_->GetConnectionIdLength(),
+ QuicPacketCreatorPeer::SendVersionInPacket(creator_),
+ !kIncludeDiversificationNonce,
QuicPacketCreatorPeer::GetPacketNumberLength(creator_)) +
QuicFramer::GetMinStreamFrameSize(framer_.transport_version(),
kDataStreamId, 0,
@@ -1118,8 +1122,9 @@ TEST_F(QuicPacketGeneratorTest,
size_t length =
NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) +
GetPacketHeaderSize(
- framer_.transport_version(), creator_->connection_id_length(),
- kIncludeVersion, !kIncludeDiversificationNonce,
+ framer_.transport_version(), creator_->GetConnectionIdLength(),
+ QuicPacketCreatorPeer::SendVersionInPacket(creator_),
+ !kIncludeDiversificationNonce,
QuicPacketCreatorPeer::GetPacketNumberLength(creator_)) +
QuicFramer::GetMinStreamFrameSize(framer_.transport_version(),
kDataStreamId, 0,
@@ -1163,8 +1168,9 @@ TEST_F(QuicPacketGeneratorTest,
size_t length =
NullEncrypter(Perspective::IS_CLIENT).GetCiphertextSize(0) +
GetPacketHeaderSize(
- framer_.transport_version(), creator_->connection_id_length(),
- kIncludeVersion, !kIncludeDiversificationNonce,
+ framer_.transport_version(), creator_->GetConnectionIdLength(),
+ QuicPacketCreatorPeer::SendVersionInPacket(creator_),
+ !kIncludeDiversificationNonce,
QuicPacketCreatorPeer::GetPacketNumberLength(creator_)) +
QuicFramer::GetMinStreamFrameSize(framer_.transport_version(),
kDataStreamId1, 0,
diff --git a/chromium/net/quic/core/quic_packets.cc b/chromium/net/quic/core/quic_packets.cc
index 35013e0fadc..c157fd0ece0 100644
--- a/chromium/net/quic/core/quic_packets.cc
+++ b/chromium/net/quic/core/quic_packets.cc
@@ -53,7 +53,7 @@ QuicPacketHeader::QuicPacketHeader()
connection_id_length(PACKET_8BYTE_CONNECTION_ID),
reset_flag(false),
version_flag(false),
- packet_number_length(PACKET_6BYTE_PACKET_NUMBER),
+ packet_number_length(PACKET_4BYTE_PACKET_NUMBER),
version(
ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED)),
nonce(nullptr),
@@ -81,6 +81,19 @@ QuicVersionNegotiationPacket::QuicVersionNegotiationPacket(
QuicVersionNegotiationPacket::~QuicVersionNegotiationPacket() {}
+QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket()
+ : stateless_reset_token(0) {}
+
+QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket(
+ const QuicPacketHeader& header,
+ uint128 token)
+ : header(header), stateless_reset_token(token) {}
+
+QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket(
+ const QuicIetfStatelessResetPacket& other) = default;
+
+QuicIetfStatelessResetPacket::~QuicIetfStatelessResetPacket() {}
+
std::ostream& operator<<(std::ostream& os, const QuicPacketHeader& header) {
os << "{ connection_id: " << header.connection_id
<< ", connection_id_length: " << header.connection_id_length
diff --git a/chromium/net/quic/core/quic_packets.h b/chromium/net/quic/core/quic_packets.h
index b3866c36557..085bb422df8 100644
--- a/chromium/net/quic/core/quic_packets.h
+++ b/chromium/net/quic/core/quic_packets.h
@@ -26,6 +26,7 @@
#include "net/quic/platform/api/quic_export.h"
#include "net/quic/platform/api/quic_socket_address.h"
#include "net/quic/platform/api/quic_string_piece.h"
+#include "net/quic/platform/api/quic_uint128.h"
namespace net {
@@ -97,6 +98,17 @@ struct QUIC_EXPORT_PRIVATE QuicVersionNegotiationPacket {
ParsedQuicVersionVector versions;
};
+struct QUIC_EXPORT_PRIVATE QuicIetfStatelessResetPacket {
+ QuicIetfStatelessResetPacket();
+ QuicIetfStatelessResetPacket(const QuicPacketHeader& header,
+ QuicUint128 token);
+ QuicIetfStatelessResetPacket(const QuicIetfStatelessResetPacket& other);
+ ~QuicIetfStatelessResetPacket();
+
+ QuicPacketHeader header;
+ QuicUint128 stateless_reset_token;
+};
+
class QUIC_EXPORT_PRIVATE QuicData {
public:
QuicData(const char* buffer, size_t length);
diff --git a/chromium/net/quic/core/quic_sent_packet_manager.cc b/chromium/net/quic/core/quic_sent_packet_manager.cc
index 5b61f6dd065..af956ea8c2f 100644
--- a/chromium/net/quic/core/quic_sent_packet_manager.cc
+++ b/chromium/net/quic/core/quic_sent_packet_manager.cc
@@ -31,8 +31,8 @@ static const int64_t kMaxRetransmissionTimeMs = 60000;
static const size_t kMaxRetransmissions = 10;
// Maximum number of packets retransmitted upon an RTO.
static const size_t kMaxRetransmissionsOnTimeout = 2;
-// Minimum number of consecutive RTOs before path is considered to be degrading.
-const size_t kMinTimeoutsBeforePathDegrading = 2;
+// The path degrading delay is the sum of this number of consecutive RTO delays.
+const size_t kNumRetransmissionDelaysForPathDegradingDelay = 2;
// Ensure the handshake timer isnt't faster than 10ms.
// This limits the tenth retransmitted packet to 10s after the initial CHLO.
@@ -90,7 +90,14 @@ QuicSentPacketManager::QuicSentPacketManager(
handshake_confirmed_(false),
largest_packet_peer_knows_is_acked_(0),
delayed_ack_time_(
- QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)) {
+ QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
+ rtt_updated_(false),
+ acked_packets_iter_(last_ack_frame_.packets.rbegin()),
+ use_path_degrading_alarm_(
+ GetQuicReloadableFlag(quic_path_degrading_alarm)),
+ use_better_crypto_retransmission_(
+ GetQuicReloadableFlag(quic_better_crypto_retransmission)) {
+ QUIC_FLAG_COUNT(quic_reloadable_flag_quic_better_crypto_retransmission);
SetSendAlgorithm(congestion_control_type);
}
@@ -127,13 +134,11 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
min_rto_timeout_ = QuicTime::Delta::Zero();
}
if (GetQuicReloadableFlag(quic_max_ack_delay2) &&
- GetQuicReloadableFlag(quic_min_rtt_ack_delay) &&
config.HasClientSentConnectionOption(kMAD4, perspective_)) {
QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_max_ack_delay2, 3, 4);
ietf_style_tlp_ = true;
}
if (GetQuicReloadableFlag(quic_max_ack_delay2) &&
- GetQuicReloadableFlag(quic_min_rtt_ack_delay) &&
config.HasClientSentConnectionOption(kMAD5, perspective_)) {
QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_max_ack_delay2, 4, 4);
ietf_style_2x_tlp_ = true;
@@ -154,6 +159,25 @@ void QuicSentPacketManager::SetFromConfig(const QuicConfig& config) {
config.HasClientRequestedIndependentOption(kTPCC, perspective_)) {
SetSendAlgorithm(kPCC);
}
+ // Initial window.
+ if (GetQuicReloadableFlag(quic_unified_iw_options)) {
+ if (config.HasClientRequestedIndependentOption(kIW03, perspective_)) {
+ initial_congestion_window_ = 3;
+ send_algorithm_->SetInitialCongestionWindowInPackets(3);
+ }
+ if (config.HasClientRequestedIndependentOption(kIW10, perspective_)) {
+ initial_congestion_window_ = 10;
+ send_algorithm_->SetInitialCongestionWindowInPackets(10);
+ }
+ if (config.HasClientRequestedIndependentOption(kIW20, perspective_)) {
+ initial_congestion_window_ = 20;
+ send_algorithm_->SetInitialCongestionWindowInPackets(20);
+ }
+ if (config.HasClientRequestedIndependentOption(kIW50, perspective_)) {
+ initial_congestion_window_ = 50;
+ send_algorithm_->SetInitialCongestionWindowInPackets(50);
+ }
+ }
using_pacing_ = !FLAGS_quic_disable_pacing_for_perf_tests;
@@ -237,21 +261,34 @@ void QuicSentPacketManager::SetHandshakeConfirmed() {
handshake_confirmed_ = true;
}
-void QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame,
+bool QuicSentPacketManager::OnIncomingAck(const QuicAckFrame& ack_frame,
QuicTime ack_receive_time) {
DCHECK_LE(LargestAcked(ack_frame), unacked_packets_.largest_sent_packet());
QuicByteCount prior_in_flight = unacked_packets_.bytes_in_flight();
- bool rtt_updated = MaybeUpdateRTT(ack_frame, ack_receive_time);
+ bool rtt_updated = MaybeUpdateRTT(LargestAcked(ack_frame),
+ ack_frame.ack_delay_time, ack_receive_time);
DCHECK_GE(LargestAcked(ack_frame), unacked_packets_.largest_observed());
unacked_packets_.IncreaseLargestObserved(LargestAcked(ack_frame));
HandleAckForSentPackets(ack_frame);
+ const bool acked_new_packet = !packets_acked_.empty();
+ PostProcessAfterMarkingPacketHandled(ack_frame, ack_receive_time, rtt_updated,
+ prior_in_flight);
+ return acked_new_packet;
+}
+
+void QuicSentPacketManager::PostProcessAfterMarkingPacketHandled(
+ const QuicAckFrame& ack_frame,
+ QuicTime ack_receive_time,
+ bool rtt_updated,
+ QuicByteCount prior_bytes_in_flight) {
InvokeLossDetection(ack_receive_time);
// Ignore losses in RTO mode.
if (consecutive_rto_count_ > 0 && !use_new_rto_) {
packets_lost_.clear();
}
- MaybeInvokeCongestionEvent(rtt_updated, prior_in_flight, ack_receive_time);
+ MaybeInvokeCongestionEvent(rtt_updated, prior_bytes_in_flight,
+ ack_receive_time);
unacked_packets_.RemoveObsoletePackets();
sustained_bandwidth_recorder_.RecordEstimate(
@@ -337,8 +374,8 @@ void QuicSentPacketManager::HandleAckForSentPackets(
// If data is associated with the most recent transmission of this
// packet, then inform the caller.
if (it->in_flight) {
- packets_acked_.push_back(
- AckedPacket(packet_number, it->bytes_sent, QuicTime::Zero()));
+ packets_acked_.emplace_back(packet_number, it->bytes_sent,
+ QuicTime::Zero());
} else {
// Unackable packets are skipped earlier.
largest_newly_acked_ = packet_number;
@@ -398,6 +435,9 @@ void QuicSentPacketManager::MarkForRetransmission(
QuicTransmissionInfo* transmission_info =
unacked_packets_.GetMutableTransmissionInfo(packet_number);
QUIC_BUG_IF(!unacked_packets_.HasRetransmittableFrames(*transmission_info));
+ // Handshake packets should never be sent as probing retransmissions.
+ DCHECK(!transmission_info->has_crypto_handshake ||
+ transmission_type != PROBING_RETRANSMISSION);
// Both TLP and the new RTO leave the packets in flight and let the loss
// detection decide if packets are lost.
if (transmission_type != TLP_RETRANSMISSION &&
@@ -572,6 +612,10 @@ bool QuicSentPacketManager::HasUnackedPackets() const {
return unacked_packets_.HasUnackedPackets();
}
+bool QuicSentPacketManager::HasUnackedCryptoPackets() const {
+ return unacked_packets_.HasPendingCryptoPackets();
+}
+
QuicPacketNumber QuicSentPacketManager::GetLeastUnacked() const {
return unacked_packets_.GetLeastUnacked();
}
@@ -646,10 +690,13 @@ void QuicSentPacketManager::OnRetransmissionTimeout() {
case RTO_MODE:
++stats_->rto_count;
RetransmitRtoPackets();
- if (!session_decides_what_to_write() &&
- network_change_visitor_ != nullptr &&
- consecutive_rto_count_ == kMinTimeoutsBeforePathDegrading) {
- network_change_visitor_->OnPathDegrading();
+ if (!use_path_degrading_alarm_) {
+ if (!session_decides_what_to_write() &&
+ network_change_visitor_ != nullptr &&
+ consecutive_rto_count_ ==
+ kNumRetransmissionDelaysForPathDegradingDelay) {
+ network_change_visitor_->OnPathDegrading();
+ }
}
return;
}
@@ -754,9 +801,12 @@ void QuicSentPacketManager::RetransmitRtoPackets() {
++consecutive_rto_count_;
}
if (session_decides_what_to_write()) {
- if (network_change_visitor_ != nullptr &&
- consecutive_rto_count_ == kMinTimeoutsBeforePathDegrading) {
- network_change_visitor_->OnPathDegrading();
+ if (!use_path_degrading_alarm_) {
+ if (network_change_visitor_ != nullptr &&
+ consecutive_rto_count_ ==
+ kNumRetransmissionDelaysForPathDegradingDelay) {
+ network_change_visitor_->OnPathDegrading();
+ }
}
for (QuicPacketNumber retransmission : retransmissions) {
MarkForRetransmission(retransmission, RTO_RETRANSMISSION);
@@ -809,26 +859,27 @@ void QuicSentPacketManager::InvokeLossDetection(QuicTime time) {
}
}
-bool QuicSentPacketManager::MaybeUpdateRTT(const QuicAckFrame& ack_frame,
+bool QuicSentPacketManager::MaybeUpdateRTT(QuicPacketNumber largest_acked,
+ QuicTime::Delta ack_delay_time,
QuicTime ack_receive_time) {
// We rely on ack_delay_time to compute an RTT estimate, so we
// only update rtt when the largest observed gets acked.
- if (!unacked_packets_.IsUnacked(LargestAcked(ack_frame))) {
+ if (!unacked_packets_.IsUnacked(largest_acked)) {
return false;
}
// We calculate the RTT based on the highest ACKed packet number, the lower
// packet numbers will include the ACK aggregation delay.
const QuicTransmissionInfo& transmission_info =
- unacked_packets_.GetTransmissionInfo(LargestAcked(ack_frame));
+ unacked_packets_.GetTransmissionInfo(largest_acked);
// Ensure the packet has a valid sent time.
if (transmission_info.sent_time == QuicTime::Zero()) {
QUIC_BUG << "Acked packet has zero sent time, largest_observed:"
- << LargestAcked(ack_frame);
+ << largest_acked;
return false;
}
QuicTime::Delta send_delta = ack_receive_time - transmission_info.sent_time;
- rtt_stats_.UpdateRtt(send_delta, ack_frame.ack_delay_time, ack_receive_time);
+ rtt_stats_.UpdateRtt(send_delta, ack_delay_time, ack_receive_time);
return true;
}
@@ -862,6 +913,10 @@ const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
}
switch (GetRetransmissionMode()) {
case HANDSHAKE_MODE:
+ if (use_better_crypto_retransmission_) {
+ return unacked_packets_.GetLastCryptoPacketSentTime() +
+ GetCryptoRetransmissionDelay();
+ }
return clock_->ApproximateNow() + GetCryptoRetransmissionDelay();
case LOSS_MODE:
return loss_algorithm_->GetLossTimeout();
@@ -888,6 +943,17 @@ const QuicTime QuicSentPacketManager::GetRetransmissionTime() const {
return QuicTime::Zero();
}
+const QuicTime::Delta QuicSentPacketManager::GetPathDegradingDelay() const {
+ QuicTime::Delta delay = QuicTime::Delta::Zero();
+ for (size_t i = 0; i < max_tail_loss_probes_; ++i) {
+ delay = delay + GetTailLossProbeDelay(i);
+ }
+ for (size_t i = 0; i < kNumRetransmissionDelaysForPathDegradingDelay; ++i) {
+ delay = delay + GetRetransmissionDelay(i);
+ }
+ return delay;
+}
+
const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
const {
// This is equivalent to the TailLossProbeDelay, but slightly more aggressive
@@ -907,9 +973,10 @@ const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
delay_ms << consecutive_crypto_retransmission_count_);
}
-const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const {
+const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay(
+ size_t consecutive_tlp_count) const {
QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
- if (enable_half_rtt_tail_loss_probe_ && consecutive_tlp_count_ == 0u) {
+ if (enable_half_rtt_tail_loss_probe_ && consecutive_tlp_count == 0u) {
return std::max(min_tlp_timeout_, srtt * 0.5);
}
if (ietf_style_tlp_) {
@@ -927,7 +994,12 @@ const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const {
return std::max(min_tlp_timeout_, 2 * srtt);
}
-const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const {
+const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const {
+ return GetTailLossProbeDelay(consecutive_tlp_count_);
+}
+
+const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay(
+ size_t consecutive_rto_count) const {
QuicTime::Delta retransmission_delay = QuicTime::Delta::Zero();
if (rtt_stats_.smoothed_rtt().IsZero()) {
// We are in the initial state, use default timeout values.
@@ -944,7 +1016,7 @@ const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const {
// Calculate exponential back off.
retransmission_delay =
retransmission_delay *
- (1 << std::min<size_t>(consecutive_rto_count_, kMaxRetransmissions));
+ (1 << std::min<size_t>(consecutive_rto_count, kMaxRetransmissions));
if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) {
return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs);
@@ -952,6 +1024,10 @@ const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const {
return retransmission_delay;
}
+const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const {
+ return GetRetransmissionDelay(consecutive_rto_count_);
+}
+
const RttStats* QuicSentPacketManager::GetRttStats() const {
return &rtt_stats_;
}
@@ -1034,22 +1110,98 @@ void QuicSentPacketManager::OnConnectionMigration(AddressChangeType type) {
}
void QuicSentPacketManager::OnAckFrameStart(QuicPacketNumber largest_acked,
- QuicTime::Delta ack_delay_time) {
- last_ack_frame_.largest_acked = largest_acked;
+ QuicTime::Delta ack_delay_time,
+ QuicTime ack_receive_time) {
+ DCHECK(packets_acked_.empty());
+ DCHECK_LE(largest_acked, unacked_packets_.largest_sent_packet());
+ rtt_updated_ =
+ MaybeUpdateRTT(largest_acked, ack_delay_time, ack_receive_time);
+ DCHECK_GE(largest_acked, unacked_packets_.largest_observed());
last_ack_frame_.ack_delay_time = ack_delay_time;
+ acked_packets_iter_ = last_ack_frame_.packets.rbegin();
}
void QuicSentPacketManager::OnAckRange(QuicPacketNumber start,
- QuicPacketNumber end,
- bool last_range,
- QuicTime ack_receive_time) {
- last_ack_frame_.packets.AddRange(start, end);
- if (!last_range) {
+ QuicPacketNumber end) {
+ if (end > last_ack_frame_.largest_acked + 1) {
+ // Largest acked increases.
+ unacked_packets_.IncreaseLargestObserved(end - 1);
+ last_ack_frame_.largest_acked = end - 1;
+ }
+ // Drop ack ranges which ack packets below least_unacked.
+ QuicPacketNumber least_unacked = unacked_packets_.GetLeastUnacked();
+ if (end <= least_unacked) {
return;
}
- OnIncomingAck(last_ack_frame_, ack_receive_time);
- // Clear last_ack_frame_.
- last_ack_frame_.Clear();
+ start = std::max(start, least_unacked);
+ DCHECK_LT(start, end);
+ do {
+ QuicPacketNumber newly_acked_start = start;
+ if (acked_packets_iter_ != last_ack_frame_.packets.rend()) {
+ newly_acked_start = std::max(start, acked_packets_iter_->max());
+ }
+ for (QuicPacketNumber acked = end - 1; acked >= newly_acked_start;
+ --acked) {
+ // Check if end is above the current range. If so add newly acked packets
+ // in descending order.
+ packets_acked_.push_back(AckedPacket(acked, 0, QuicTime::Zero()));
+ }
+ if (acked_packets_iter_ == last_ack_frame_.packets.rend() ||
+ start > acked_packets_iter_->min()) {
+ // Finish adding all newly acked packets.
+ return;
+ }
+ end = std::min(end, acked_packets_iter_->min());
+ ++acked_packets_iter_;
+ } while (start < end);
+}
+
+bool QuicSentPacketManager::OnAckFrameEnd(QuicTime ack_receive_time) {
+ QuicByteCount prior_bytes_in_flight = unacked_packets_.bytes_in_flight();
+ // Reverse packets_acked_ so that it is in ascending order.
+ reverse(packets_acked_.begin(), packets_acked_.end());
+ for (AckedPacket& acked_packet : packets_acked_) {
+ QuicTransmissionInfo* info =
+ unacked_packets_.GetMutableTransmissionInfo(acked_packet.packet_number);
+ if (!QuicUtils::IsAckable(info->state)) {
+ if (info->state == ACKED) {
+ QUIC_BUG << "Trying to ack an already acked packet: "
+ << acked_packet.packet_number;
+ } else {
+ QUIC_PEER_BUG << "Received ack for unackable packet: "
+ << acked_packet.packet_number << " with state: "
+ << QuicUtils::SentPacketStateToString(info->state);
+ }
+ continue;
+ }
+ QUIC_DVLOG(1) << ENDPOINT << "Got an ack for packet "
+ << acked_packet.packet_number;
+ last_ack_frame_.packets.Add(acked_packet.packet_number);
+ if (info->largest_acked > 0) {
+ largest_packet_peer_knows_is_acked_ =
+ std::max(largest_packet_peer_knows_is_acked_, info->largest_acked);
+ }
+ // If data is associated with the most recent transmission of this
+ // packet, then inform the caller.
+ if (info->in_flight) {
+ acked_packet.bytes_acked = info->bytes_sent;
+ } else {
+ // Unackable packets are skipped earlier.
+ largest_newly_acked_ = acked_packet.packet_number;
+ }
+ MarkPacketHandled(acked_packet.packet_number, info,
+ last_ack_frame_.ack_delay_time);
+ }
+ const bool acked_new_packet = !packets_acked_.empty();
+ PostProcessAfterMarkingPacketHandled(last_ack_frame_, ack_receive_time,
+ rtt_updated_, prior_bytes_in_flight);
+ // TODO(fayang): Move this line to PostProcessAfterMarkingPacketHandled
+ // when deprecating quic_reloadable_flag_quic_use_incremental_ack_processing3.
+ // Remove packets below least unacked from all_packets_acked_ and
+ // last_ack_frame_.
+ last_ack_frame_.packets.RemoveUpTo(unacked_packets_.GetLeastUnacked());
+
+ return acked_new_packet;
}
void QuicSentPacketManager::SetDebugDelegate(DebugDelegate* debug_delegate) {
diff --git a/chromium/net/quic/core/quic_sent_packet_manager.h b/chromium/net/quic/core/quic_sent_packet_manager.h
index d067950c721..4c916ea3d99 100644
--- a/chromium/net/quic/core/quic_sent_packet_manager.h
+++ b/chromium/net/quic/core/quic_sent_packet_manager.h
@@ -82,6 +82,8 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// Called with the path may be degrading. Note that the path may only be
// temporarily degrading.
+ // TODO(b/76462761): remove this once
+ // FLAGS_quic_reloadable_flag_quic_path_degrading_alarm is deprecated.
virtual void OnPathDegrading() = 0;
// Called when the Path MTU may have increased.
@@ -110,8 +112,9 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
void SetHandshakeConfirmed();
- // Processes the incoming ack.
- void OnIncomingAck(const QuicAckFrame& ack_frame, QuicTime ack_receive_time);
+ // Processes the incoming ack. Returns true if a previously-unacked packet is
+ // acked.
+ bool OnIncomingAck(const QuicAckFrame& ack_frame, QuicTime ack_receive_time);
// Requests retransmission of all unacked packets of |retransmission_type|.
// The behavior of this method depends on the value of |retransmission_type|:
@@ -148,6 +151,9 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
bool HasUnackedPackets() const;
+ // Returns true if there's outstanding crypto data.
+ bool HasUnackedCryptoPackets() const;
+
// Returns the smallest packet number of a serialized packet which has not
// been acked by the peer.
QuicPacketNumber GetLeastUnacked() const;
@@ -176,6 +182,10 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// there are no retransmittable packets.
const QuicTime GetRetransmissionTime() const;
+ // Returns the current delay for the path degrading timer, which is used to
+ // notify the session that this connection is degrading.
+ const QuicTime::Delta GetPathDegradingDelay() const;
+
const RttStats* GetRttStats() const;
// Returns the estimated bandwidth calculated by the congestion algorithm.
@@ -218,13 +228,16 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// Called when an ack frame is initially parsed.
void OnAckFrameStart(QuicPacketNumber largest_acked,
- QuicTime::Delta ack_delay_time);
+ QuicTime::Delta ack_delay_time,
+ QuicTime ack_receive_time);
+
+ // Called when ack range [start, end) is received. Populates packets_acked_
+ // with newly acked packets.
+ void OnAckRange(QuicPacketNumber start, QuicPacketNumber end);
- // Called when ack range [start, end) is received.
- void OnAckRange(QuicPacketNumber start,
- QuicPacketNumber end,
- bool last_range,
- QuicTime ack_receive_time);
+ // Called when an ack frame is parsed completely. Returns true if a previously
+ // -unacked packet is acked.
+ bool OnAckFrameEnd(QuicTime ack_receive_time);
// Called to enable/disable letting session decide what to write.
void SetSessionDecideWhatToWrite(bool session_decides_what_to_write);
@@ -249,6 +262,10 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
void SetSessionNotifier(SessionNotifierInterface* session_notifier);
+ QuicPacketCount initial_congestion_window() const {
+ return initial_congestion_window_;
+ }
+
QuicPacketNumber largest_packet_peer_knows_is_acked() const {
return largest_packet_peer_knows_is_acked_;
}
@@ -301,13 +318,26 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// packets from flight.
void RetransmitRtoPackets();
- // Returns the timer for retransmitting crypto handshake packets.
+ // Returns the timeout for retransmitting crypto handshake packets.
const QuicTime::Delta GetCryptoRetransmissionDelay() const;
- // Returns the timer for a new tail loss probe.
+ // Returns the timeout for a new tail loss probe. |consecutive_tlp_count| is
+ // the number of consecutive tail loss probes that have already been sent.
+ const QuicTime::Delta GetTailLossProbeDelay(
+ size_t consecutive_tlp_count) const;
+
+ // Calls GetTailLossProbeDelay() with values from the current state of this
+ // packet manager as its params.
const QuicTime::Delta GetTailLossProbeDelay() const;
// Returns the retransmission timeout, after which a full RTO occurs.
+ // |consecutive_rto_count| is the number of consecutive RTOs that have already
+ // occurred.
+ const QuicTime::Delta GetRetransmissionDelay(
+ size_t consecutive_rto_count) const;
+
+ // Calls GetRetransmissionDelay() with values from the current state of this
+ // packet manager as its params.
const QuicTime::Delta GetRetransmissionDelay() const;
// Returns the newest transmission associated with a packet.
@@ -317,7 +347,9 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// Update the RTT if the ack is for the largest acked packet number.
// Returns true if the rtt was updated.
- bool MaybeUpdateRTT(const QuicAckFrame& ack_frame, QuicTime ack_receive_time);
+ bool MaybeUpdateRTT(QuicPacketNumber largest_acked,
+ QuicTime::Delta ack_delay_time,
+ QuicTime ack_receive_time);
// Invokes the loss detection algorithm and loses and retransmits packets if
// necessary.
@@ -345,6 +377,13 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
void MarkForRetransmission(QuicPacketNumber packet_number,
TransmissionType transmission_type);
+ // Called after packets have been marked handled with last received ack frame.
+ void PostProcessAfterMarkingPacketHandled(
+ const QuicAckFrame& ack_frame,
+ QuicTime ack_receive_time,
+ bool rtt_updated,
+ QuicByteCount prior_bytes_in_flight);
+
// Notify observers that packet with QuicTransmissionInfo |info| is a spurious
// retransmission. It is caller's responsibility to guarantee the packet with
// QuicTransmissionInfo |info| is a spurious retransmission before calling
@@ -389,7 +428,7 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
DebugDelegate* debug_delegate_;
NetworkChangeVisitor* network_change_visitor_;
- const QuicPacketCount initial_congestion_window_;
+ QuicPacketCount initial_congestion_window_;
RttStats rtt_stats_;
std::unique_ptr<SendAlgorithmInterface> send_algorithm_;
// Not owned. Always points to |general_loss_algorithm_| outside of tests.
@@ -459,6 +498,23 @@ class QUIC_EXPORT_PRIVATE QuicSentPacketManager {
// Latest received ack frame.
QuicAckFrame last_ack_frame_;
+ // Record whether RTT gets updated by last largest acked. This is only used
+ // when quic_reloadable_flag_quic_use_incremental_ack_processing3 is true.
+ bool rtt_updated_;
+
+ // A reverse iterator of last_ack_frame_.packets. This is reset in
+ // OnAckRangeStart, and gradually moves in OnAckRange. This is only used
+ // when quic_reloadable_flag_quic_use_incremental_ack_processing3 is true.
+ PacketNumberQueue::const_reverse_iterator acked_packets_iter_;
+
+ // Latched value of
+ // quic_reloadable_flag_quic_path_degrading_alarm
+ const bool use_path_degrading_alarm_;
+
+ // Latched value of
+ // quic_reloadable_flag_quic_better_crypto_retransmission
+ const bool use_better_crypto_retransmission_;
+
DISALLOW_COPY_AND_ASSIGN(QuicSentPacketManager);
};
diff --git a/chromium/net/quic/core/quic_sent_packet_manager_test.cc b/chromium/net/quic/core/quic_sent_packet_manager_test.cc
index 49ae651f2c6..17154215e04 100644
--- a/chromium/net/quic/core/quic_sent_packet_manager_test.cc
+++ b/chromium/net/quic/core/quic_sent_packet_manager_test.cc
@@ -86,7 +86,9 @@ class QuicSentPacketManagerTest : public QuicTestWithParam<bool> {
QuicSentPacketManagerTest()
: manager_(Perspective::IS_SERVER, &clock_, &stats_, kCubicBytes, kNack),
send_algorithm_(new StrictMock<MockSendAlgorithm>),
- network_change_visitor_(new StrictMock<MockNetworkChangeVisitor>) {
+ network_change_visitor_(new StrictMock<MockNetworkChangeVisitor>),
+ use_path_degrading_alarm_(
+ GetQuicReloadableFlag(quic_path_degrading_alarm)) {
QuicSentPacketManagerPeer::SetSendAlgorithm(&manager_, send_algorithm_);
// Disable tail loss probes for most tests.
QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 0);
@@ -255,7 +257,7 @@ class QuicSentPacketManagerTest : public QuicTestWithParam<bool> {
SerializedPacket CreatePacket(QuicPacketNumber packet_number,
bool retransmittable) {
- SerializedPacket packet(packet_number, PACKET_6BYTE_PACKET_NUMBER, nullptr,
+ SerializedPacket packet(packet_number, PACKET_4BYTE_PACKET_NUMBER, nullptr,
kDefaultLength, false, false);
if (retransmittable) {
packet.retransmittable_frames.push_back(QuicFrame(
@@ -318,6 +320,10 @@ class QuicSentPacketManagerTest : public QuicTestWithParam<bool> {
MockSendAlgorithm* send_algorithm_;
std::unique_ptr<MockNetworkChangeVisitor> network_change_visitor_;
StrictMock<MockSessionNotifier> notifier_;
+
+ // Latched value of
+ // quic_reloadable_flag_quic_path_degrading_alarm
+ bool use_path_degrading_alarm_;
};
INSTANTIATE_TEST_CASE_P(Tests, QuicSentPacketManagerTest, testing::Bool());
@@ -357,11 +363,12 @@ TEST_P(QuicSentPacketManagerTest, RetransmitThenAck) {
QuicAckFrame ack_frame = InitAckFrame({{2, 3}});
ExpectAck(2);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite());
- manager_.OnAckRange(2, 3, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(2, 3);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.Now());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now()));
}
if (manager_.session_decides_what_to_write()) {
EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
@@ -391,11 +398,12 @@ TEST_P(QuicSentPacketManagerTest, RetransmitThenAckBeforeSend) {
// Ack 1.
QuicAckFrame ack_frame = InitAckFrame(1);
ExpectAck(1);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.Now());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now()));
}
// There should no longer be a pending retransmission.
@@ -448,11 +456,12 @@ TEST_P(QuicSentPacketManagerTest, RetransmitThenAckPrevious) {
// Ack 1 but not 2.
ExpectAck(1);
QuicAckFrame ack_frame = InitAckFrame(1);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
if (manager_.session_decides_what_to_write()) {
EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
@@ -467,9 +476,10 @@ TEST_P(QuicSentPacketManagerTest, RetransmitThenAckPrevious) {
EXPECT_CALL(notifier_, OnFrameAcked(_, _)).WillOnce(Return(false));
ExpectAck(2);
QuicAckFrame ack_frame2 = InitAckFrame(2);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite());
- manager_.OnAckRange(1, 3, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(1, 3);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
manager_.OnIncomingAck(ack_frame2, clock_.ApproximateNow());
}
@@ -487,11 +497,12 @@ TEST_P(QuicSentPacketManagerTest, RetransmitThenAckPreviousThenNackRetransmit) {
// First, ACK packet 1 which makes packet 2 non-retransmittable.
ExpectAck(1);
QuicAckFrame ack_frame = InitAckFrame(1);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
SendDataPacket(3);
@@ -503,22 +514,24 @@ TEST_P(QuicSentPacketManagerTest, RetransmitThenAckPreviousThenNackRetransmit) {
ack_frame = InitAckFrame({{1, 2}, {3, 4}});
ExpectAck(3);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite());
- manager_.OnAckRange(3, 4, /*last_range=*/false, clock_.ApproximateNow());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(3, 4);
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
ack_frame = InitAckFrame({{1, 2}, {3, 5}});
ExpectAck(4);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite());
- manager_.OnAckRange(3, 5, /*last_range=*/false, clock_.ApproximateNow());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(3, 5);
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
ack_frame = InitAckFrame({{1, 2}, {3, 6}});
@@ -527,12 +540,13 @@ TEST_P(QuicSentPacketManagerTest, RetransmitThenAckPreviousThenNackRetransmit) {
// Frames in all packets are acked.
EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
}
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite());
- manager_.OnAckRange(3, 6, /*last_range=*/false, clock_.ApproximateNow());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(3, 6);
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
// No packets remain unacked.
@@ -562,11 +576,12 @@ TEST_P(QuicSentPacketManagerTest,
QuicAckFrame ack_frame = InitAckFrame(1);
ExpectUpdatedRtt(1);
EXPECT_CALL(*send_algorithm_, RevertRetransmissionTimeout());
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
// Since 2 was marked for retransmit, when 1 is acked, 2 is kept for RTT.
@@ -602,11 +617,12 @@ TEST_P(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) {
// Ack 1 but not 2 or 3.
ExpectAck(1);
QuicAckFrame ack_frame = InitAckFrame(1);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
if (manager_.session_decides_what_to_write()) {
// Frames in packets 2 and 3 are acked.
@@ -632,12 +648,13 @@ TEST_P(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) {
ack_frame = InitAckFrame({{1, 2}, {3, 5}});
QuicPacketNumber acked[] = {3, 4};
ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite());
- manager_.OnAckRange(3, 5, /*last_range=*/false, clock_.ApproximateNow());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(3, 5);
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
QuicPacketNumber unacked2[] = {2};
@@ -652,12 +669,13 @@ TEST_P(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) {
// Frames in all packetss are acked.
EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
}
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite());
- manager_.OnAckRange(3, 6, /*last_range=*/false, clock_.ApproximateNow());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(3, 6);
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
VerifyUnackedPackets(nullptr, 0);
@@ -684,11 +702,12 @@ TEST_P(QuicSentPacketManagerTest, AckOriginalTransmission) {
QuicAckFrame ack_frame = InitAckFrame(1);
ExpectAck(1);
EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _));
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.Now());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now()));
}
}
@@ -699,27 +718,33 @@ TEST_P(QuicSentPacketManagerTest, AckOriginalTransmission) {
QuicAckFrame ack_frame = InitAckFrame({{1, 2}, {4, 5}});
ExpectAck(4);
EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _));
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite());
- manager_.OnAckRange(4, 5, /*last_range=*/false, clock_.Now());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(4, 5);
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.Now());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now()));
}
RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
}
// Ack 3, which causes SpuriousRetransmitDetected to be called.
{
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ QuicPacketNumber acked[] = {3};
+ ExpectAcksAndLosses(false, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
+ }
QuicAckFrame ack_frame = InitAckFrame({{1, 2}, {3, 5}});
EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _));
EXPECT_CALL(*loss_algorithm, SpuriousRetransmitDetected(_, _, _, 5));
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite());
- manager_.OnAckRange(3, 5, /*last_range=*/false, clock_.Now());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(3, 5);
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.Now());
+ EXPECT_FALSE(manager_.OnIncomingAck(ack_frame, clock_.Now()));
}
if (manager_.session_decides_what_to_write()) {
// Ack 3 will not cause 5 be considered as a spurious retransmission. Ack
@@ -729,10 +754,11 @@ TEST_P(QuicSentPacketManagerTest, AckOriginalTransmission) {
EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _));
EXPECT_CALL(notifier_, OnFrameAcked(_, _)).WillOnce(Return(false));
QuicAckFrame ack_frame2 = InitAckFrame({{1, 2}, {3, 6}});
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite());
- manager_.OnAckRange(3, 6, /*last_range=*/false, clock_.Now());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(3, 6);
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
manager_.OnIncomingAck(ack_frame2, clock_.Now());
}
@@ -758,12 +784,19 @@ TEST_P(QuicSentPacketManagerTest, AckAckAndUpdateRtt) {
QuicAckFrame ack_frame = InitAckFrame(2);
ack_frame.ack_delay_time = QuicTime::Delta::FromMilliseconds(5);
- ExpectAck(1);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(2, QuicTime::Delta::FromMilliseconds(5));
- manager_.OnAckRange(1, 3, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ QuicPacketNumber acked[] = {1, 2};
+ ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
+ } else {
+ ExpectAck(1);
+ }
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(2, QuicTime::Delta::FromMilliseconds(5),
+ clock_.Now());
+ manager_.OnAckRange(1, 3);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.Now());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now()));
}
EXPECT_EQ(1u, manager_.largest_packet_peer_knows_is_acked());
@@ -771,12 +804,18 @@ TEST_P(QuicSentPacketManagerTest, AckAckAndUpdateRtt) {
// Now ack the ack and expect only an RTT update.
ack_frame = InitAckFrame(3);
- ExpectUpdatedRtt(3);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite());
- manager_.OnAckRange(1, 4, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ QuicPacketNumber acked[] = {3};
+ ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
} else {
- manager_.OnIncomingAck(ack_frame, clock_.Now());
+ ExpectUpdatedRtt(3);
+ }
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(1, 4);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+ } else {
+ EXPECT_FALSE(manager_.OnIncomingAck(ack_frame, clock_.Now()));
}
EXPECT_EQ(3u, manager_.largest_packet_peer_knows_is_acked());
}
@@ -789,11 +828,12 @@ TEST_P(QuicSentPacketManagerTest, Rtt) {
ExpectAck(packet_number);
QuicAckFrame ack_frame = InitAckFrame(packet_number);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.Now());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now()));
}
EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
}
@@ -810,11 +850,13 @@ TEST_P(QuicSentPacketManagerTest, RttWithInvalidDelta) {
ExpectAck(packet_number);
QuicAckFrame ack_frame = InitAckFrame(packet_number);
ack_frame.ack_delay_time = QuicTime::Delta::FromMilliseconds(11);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(1, QuicTime::Delta::FromMilliseconds(11));
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(1, QuicTime::Delta::FromMilliseconds(11),
+ clock_.Now());
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.Now());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now()));
}
EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
}
@@ -830,11 +872,12 @@ TEST_P(QuicSentPacketManagerTest, RttWithInfiniteDelta) {
ExpectAck(packet_number);
QuicAckFrame ack_frame = InitAckFrame(packet_number);
ack_frame.ack_delay_time = QuicTime::Delta::Infinite();
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.Now());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now()));
}
EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
}
@@ -850,11 +893,12 @@ TEST_P(QuicSentPacketManagerTest, RttZeroDelta) {
ExpectAck(packet_number);
QuicAckFrame ack_frame = InitAckFrame(packet_number);
ack_frame.ack_delay_time = QuicTime::Delta::Zero();
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(1, QuicTime::Delta::Zero());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(1, QuicTime::Delta::Zero(), clock_.Now());
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.Now());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now()));
}
EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
}
@@ -904,11 +948,12 @@ TEST_P(QuicSentPacketManagerTest, TailLossProbeTimeout) {
ExpectAck(3);
QuicAckFrame ack_frame = InitAckFrame({{3, 4}});
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite());
- manager_.OnAckRange(3, 4, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(3, 4);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
@@ -925,11 +970,12 @@ TEST_P(QuicSentPacketManagerTest, TailLossProbeTimeout) {
// Frames in all packets are acked.
EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
}
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite());
- manager_.OnAckRange(3, 6, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(3, 6);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
EXPECT_FALSE(manager_.HasPendingRetransmissions());
@@ -1038,11 +1084,12 @@ TEST_P(QuicSentPacketManagerTest, TailLossProbeThenRTO) {
// Packets 1, 2 and [4, 102] are lost.
EXPECT_CALL(notifier_, OnFrameLost(_)).Times(101);
}
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(103, QuicTime::Delta::Infinite());
- manager_.OnAckRange(103, 104, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(103, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(103, 104);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
// All packets before 103 should be lost.
if (manager_.session_decides_what_to_write()) {
@@ -1106,12 +1153,13 @@ TEST_P(QuicSentPacketManagerTest, CryptoHandshakeTimeout) {
EXPECT_CALL(notifier_, HasPendingCryptoData())
.WillRepeatedly(Return(false));
}
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(9, QuicTime::Delta::Infinite());
- manager_.OnAckRange(8, 10, /*last_range=*/false, clock_.ApproximateNow());
- manager_.OnAckRange(3, 6, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(9, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(8, 10);
+ manager_.OnAckRange(3, 6);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
@@ -1179,11 +1227,12 @@ TEST_P(QuicSentPacketManagerTest, CryptoHandshakeTimeoutVersionNegotiation) {
QuicPacketNumber acked[] = {8, 9};
ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
QuicAckFrame ack_frame = InitAckFrame({{8, 10}});
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(9, QuicTime::Delta::Infinite());
- manager_.OnAckRange(8, 10, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(9, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(8, 10);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
if (manager_.session_decides_what_to_write()) {
EXPECT_CALL(notifier_, HasPendingCryptoData())
@@ -1219,18 +1268,24 @@ TEST_P(QuicSentPacketManagerTest, CryptoHandshakeSpuriousRetransmission) {
// Now ack the second crypto packet, and ensure the first gets removed, but
// the third does not.
- ExpectUpdatedRtt(2);
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ QuicPacketNumber acked[] = {2};
+ ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
+ } else {
+ ExpectUpdatedRtt(2);
+ }
QuicAckFrame ack_frame = InitAckFrame({{2, 3}});
if (manager_.session_decides_what_to_write()) {
EXPECT_CALL(notifier_, HasPendingCryptoData())
.WillRepeatedly(Return(false));
EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
}
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite());
- manager_.OnAckRange(2, 3, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(2, 3);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_FALSE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
@@ -1347,12 +1402,18 @@ TEST_P(QuicSentPacketManagerTest,
// Ensure both packets get discarded when packet 2 is acked.
QuicAckFrame ack_frame = InitAckFrame({{3, 4}});
- ExpectUpdatedRtt(3);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite());
- manager_.OnAckRange(3, 4, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ QuicPacketNumber acked[] = {3};
+ ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
+ } else {
+ ExpectUpdatedRtt(3);
+ }
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(3, 4);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.Now());
+ EXPECT_FALSE(manager_.OnIncomingAck(ack_frame, clock_.Now()));
}
VerifyUnackedPackets(nullptr, 0);
VerifyRetransmittablePackets(nullptr, 0);
@@ -1420,11 +1481,12 @@ TEST_P(QuicSentPacketManagerTest, RetransmissionTimeout) {
// retransmittable frames as packet 102 is acked.
EXPECT_CALL(notifier_, OnFrameLost(_)).Times(98);
}
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(102, QuicTime::Delta::Zero());
- manager_.OnAckRange(102, 103, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(102, QuicTime::Delta::Zero(), clock_.Now());
+ manager_.OnAckRange(102, 103);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.Now());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now()));
}
}
@@ -1495,11 +1557,12 @@ TEST_P(QuicSentPacketManagerTest, NewRetransmissionTimeout) {
// retransmittable frames as packet 102 is acked.
EXPECT_CALL(notifier_, OnFrameLost(_)).Times(98);
}
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(102, QuicTime::Delta::Zero());
- manager_.OnAckRange(102, 103, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(102, QuicTime::Delta::Zero(), clock_.Now());
+ manager_.OnAckRange(102, 103);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.Now());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now()));
}
}
@@ -1525,7 +1588,9 @@ TEST_P(QuicSentPacketManagerTest, TwoRetransmissionTimeoutsAckSecond) {
}
// Rto a second time.
- EXPECT_CALL(*network_change_visitor_, OnPathDegrading());
+ if (!use_path_degrading_alarm_) {
+ EXPECT_CALL(*network_change_visitor_, OnPathDegrading());
+ }
if (manager_.session_decides_what_to_write()) {
EXPECT_CALL(notifier_, RetransmitFrames(_, _))
.WillOnce(WithArgs<1>(Invoke(
@@ -1548,11 +1613,12 @@ TEST_P(QuicSentPacketManagerTest, TwoRetransmissionTimeoutsAckSecond) {
QuicAckFrame ack_frame = InitAckFrame({{2, 3}});
ack_frame.ack_delay_time = QuicTime::Delta::Zero();
ExpectAck(2);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(2, QuicTime::Delta::Zero());
- manager_.OnAckRange(2, 3, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(2, QuicTime::Delta::Zero(), clock_.Now());
+ manager_.OnAckRange(2, 3);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
// The original packet and newest should be outstanding.
@@ -1582,7 +1648,9 @@ TEST_P(QuicSentPacketManagerTest, TwoRetransmissionTimeoutsAckFirst) {
}
// Rto a second time.
- EXPECT_CALL(*network_change_visitor_, OnPathDegrading());
+ if (!use_path_degrading_alarm_) {
+ EXPECT_CALL(*network_change_visitor_, OnPathDegrading());
+ }
if (manager_.session_decides_what_to_write()) {
EXPECT_CALL(notifier_, RetransmitFrames(_, _))
.WillOnce(WithArgs<1>(Invoke(
@@ -1605,11 +1673,12 @@ TEST_P(QuicSentPacketManagerTest, TwoRetransmissionTimeoutsAckFirst) {
QuicAckFrame ack_frame = InitAckFrame({{3, 4}});
ack_frame.ack_delay_time = QuicTime::Delta::Zero();
ExpectAck(3);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(3, QuicTime::Delta::Zero());
- manager_.OnAckRange(3, 4, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(3, QuicTime::Delta::Zero(), clock_.Now());
+ manager_.OnAckRange(3, 4);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
// The first two packets should still be outstanding.
@@ -1618,6 +1687,10 @@ TEST_P(QuicSentPacketManagerTest, TwoRetransmissionTimeoutsAckFirst) {
}
TEST_P(QuicSentPacketManagerTest, OnPathDegrading) {
+ if (use_path_degrading_alarm_) {
+ return;
+ }
+
SendDataPacket(1);
for (size_t i = 1; i < kMinTimeoutsBeforePathDegrading; ++i) {
if (manager_.session_decides_what_to_write()) {
@@ -1645,6 +1718,7 @@ TEST_P(QuicSentPacketManagerTest, GetTransmissionTime) {
}
TEST_P(QuicSentPacketManagerTest, GetTransmissionTimeCryptoHandshake) {
+ QuicTime crypto_packet_send_time = clock_.Now();
SendCryptoPacket(1);
// Check the min.
@@ -1665,6 +1739,7 @@ TEST_P(QuicSentPacketManagerTest, GetTransmissionTimeCryptoHandshake) {
if (manager_.session_decides_what_to_write()) {
EXPECT_CALL(notifier_, RetransmitFrames(_, _))
.WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(2); }));
+ crypto_packet_send_time = clock_.Now();
}
manager_.OnRetransmissionTimeout();
if (!manager_.session_decides_what_to_write()) {
@@ -1672,7 +1747,11 @@ TEST_P(QuicSentPacketManagerTest, GetTransmissionTimeCryptoHandshake) {
}
// The retransmission time should now be twice as far in the future.
- expected_time = clock_.Now() + srtt * 2 * 1.5;
+ if (GetQuicReloadableFlag(quic_better_crypto_retransmission)) {
+ expected_time = crypto_packet_send_time + srtt * 2 * 1.5;
+ } else {
+ expected_time = clock_.Now() + srtt * 2 * 1.5;
+ }
EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
}
@@ -1691,6 +1770,7 @@ TEST_P(QuicSentPacketManagerTest,
EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
.WillRepeatedly(Return(10 * kDefaultTCPMSS));
+ QuicTime crypto_packet_send_time = clock_.Now();
SendCryptoPacket(1);
// Check the min.
@@ -1711,6 +1791,7 @@ TEST_P(QuicSentPacketManagerTest,
if (manager_.session_decides_what_to_write()) {
EXPECT_CALL(notifier_, RetransmitFrames(_, _))
.WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(2); }));
+ crypto_packet_send_time = clock_.Now();
}
manager_.OnRetransmissionTimeout();
if (!manager_.session_decides_what_to_write()) {
@@ -1718,7 +1799,11 @@ TEST_P(QuicSentPacketManagerTest,
}
// The retransmission time should now be twice as far in the future.
- expected_time = clock_.Now() + srtt * 2 * 2;
+ if (GetQuicReloadableFlag(quic_better_crypto_retransmission)) {
+ expected_time = crypto_packet_send_time + srtt * 2 * 2;
+ } else {
+ expected_time = clock_.Now() + srtt * 2 * 2;
+ }
EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
}
@@ -1811,11 +1896,12 @@ TEST_P(QuicSentPacketManagerTest, GetTransmissionTimeSpuriousRTO) {
// original value and OnRetransmissionTimeout is not called or reverted.
QuicAckFrame ack_frame = InitAckFrame({{2, 3}});
ExpectAck(2);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite());
- manager_.OnAckRange(2, 3, /*last_range=*/true, clock_.ApproximateNow());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(2, 3);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.ApproximateNow()));
}
EXPECT_FALSE(manager_.HasPendingRetransmissions());
EXPECT_EQ(5 * kDefaultLength,
@@ -1841,10 +1927,14 @@ TEST_P(QuicSentPacketManagerTest, GetTransmissionDelayMin) {
// If the delay is smaller than the min, ensure it exponentially backs off
// from the min.
- EXPECT_CALL(*network_change_visitor_, OnPathDegrading());
+ if (!use_path_degrading_alarm_) {
+ EXPECT_CALL(*network_change_visitor_, OnPathDegrading());
+ }
for (int i = 0; i < 5; ++i) {
EXPECT_EQ(delay,
QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+ EXPECT_EQ(delay,
+ QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, i));
delay = delay + delay;
if (manager_.session_decides_what_to_write()) {
EXPECT_CALL(notifier_, RetransmitFrames(_, _))
@@ -1868,6 +1958,8 @@ TEST_P(QuicSentPacketManagerTest, GetTransmissionDelayMax) {
EXPECT_EQ(QuicTime::Delta::FromSeconds(60),
QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(60),
+ QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, 0));
}
TEST_P(QuicSentPacketManagerTest, GetTransmissionDelayExponentialBackoff) {
@@ -1875,10 +1967,14 @@ TEST_P(QuicSentPacketManagerTest, GetTransmissionDelayExponentialBackoff) {
QuicTime::Delta delay = QuicTime::Delta::FromMilliseconds(500);
// Delay should back off exponentially.
- EXPECT_CALL(*network_change_visitor_, OnPathDegrading());
+ if (!use_path_degrading_alarm_) {
+ EXPECT_CALL(*network_change_visitor_, OnPathDegrading());
+ }
for (int i = 0; i < 5; ++i) {
EXPECT_EQ(delay,
QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+ EXPECT_EQ(delay,
+ QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, i));
delay = delay + delay;
if (manager_.session_decides_what_to_write()) {
EXPECT_CALL(notifier_, RetransmitFrames(_, _))
@@ -1908,6 +2004,8 @@ TEST_P(QuicSentPacketManagerTest, RetransmissionDelay) {
QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4);
EXPECT_EQ(expected_delay,
QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+ EXPECT_EQ(expected_delay,
+ QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, 0));
for (int i = 0; i < 100; ++i) {
// Run to make sure that we converge.
@@ -1925,6 +2023,8 @@ TEST_P(QuicSentPacketManagerTest, RetransmissionDelay) {
QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_)
.ToMilliseconds(),
1);
+ EXPECT_EQ(QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, 0),
+ QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
}
TEST_P(QuicSentPacketManagerTest, GetLossDelay) {
@@ -1941,11 +2041,12 @@ TEST_P(QuicSentPacketManagerTest, GetLossDelay) {
ExpectAck(2);
EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _));
QuicAckFrame ack_frame = InitAckFrame({{2, 3}});
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite());
- manager_.OnAckRange(2, 3, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(2, 3);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.Now());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now()));
}
QuicTime timeout(clock_.Now() + QuicTime::Delta::FromMilliseconds(10));
@@ -2116,12 +2217,16 @@ TEST_F(QuicSentPacketManagerTest,
// The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(200ms).
EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+ EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
+ QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
// Send two packets, and the TLP should be 2 us.
SendDataPacket(1);
SendDataPacket(2);
EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+ EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
+ QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
}
TEST_F(QuicSentPacketManagerTest,
@@ -2146,18 +2251,20 @@ TEST_F(QuicSentPacketManagerTest,
// The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(200ms).
EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
-
+ EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
+ QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
// Send two packets, and the TLP should be 2 us.
SendDataPacket(1);
SendDataPacket(2);
EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+ EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
+ QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
}
TEST_F(QuicSentPacketManagerTest,
DISABLED_NegotiateIETFTLPFromOptionsAtServer) {
SetQuicReloadableFlag(quic_max_ack_delay2, true);
- SetQuicReloadableFlag(quic_min_rtt_ack_delay, true);
QuicConfig config;
QuicTagVector options;
@@ -2173,18 +2280,21 @@ TEST_F(QuicSentPacketManagerTest,
// Expect 1.5x * SRTT + 0ms MAD
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(150),
QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+ EXPECT_EQ(QuicTime::Delta::FromMilliseconds(150),
+ QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
// Expect 1.5x * SRTT + 50ms MAD
rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(150),
QuicTime::Delta::FromMilliseconds(50), QuicTime::Zero());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats->smoothed_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200),
QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+ EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200),
+ QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
}
TEST_F(QuicSentPacketManagerTest,
DISABLED_NegotiateIETFTLPFromOptionsAtClient) {
SetQuicReloadableFlag(quic_max_ack_delay2, true);
- SetQuicReloadableFlag(quic_min_rtt_ack_delay, true);
QuicConfig client_config;
QuicTagVector options;
@@ -2201,12 +2311,16 @@ TEST_F(QuicSentPacketManagerTest,
// Expect 1.5x * SRTT + 0ms MAD
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(150),
QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+ EXPECT_EQ(QuicTime::Delta::FromMilliseconds(150),
+ QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
// Expect 1.5x * SRTT + 50ms MAD
rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(150),
QuicTime::Delta::FromMilliseconds(50), QuicTime::Zero());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats->smoothed_rtt());
EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200),
QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+ EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200),
+ QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
}
TEST_F(QuicSentPacketManagerTest,
@@ -2226,9 +2340,13 @@ TEST_F(QuicSentPacketManagerTest,
QuicTime::Delta::Zero(), QuicTime::Zero());
EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1),
QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+ EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1),
+ QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, 0));
// The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(0ms).
EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+ EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
+ QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
}
TEST_F(QuicSentPacketManagerTest,
@@ -2249,9 +2367,13 @@ TEST_F(QuicSentPacketManagerTest,
QuicTime::Delta::Zero(), QuicTime::Zero());
EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1),
QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+ EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1),
+ QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, 0));
// The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(0ms).
EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+ EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
+ QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
}
TEST_F(QuicSentPacketManagerTest, DISABLED_NegotiateNoTLPFromOptionsAtServer) {
@@ -2444,7 +2566,7 @@ TEST_P(QuicSentPacketManagerTest, ConnectionMigrationPortChange) {
TEST_P(QuicSentPacketManagerTest, PathMtuIncreased) {
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, BytesInFlight(), 1, _, _));
- SerializedPacket packet(1, PACKET_6BYTE_PACKET_NUMBER, nullptr,
+ SerializedPacket packet(1, PACKET_4BYTE_PACKET_NUMBER, nullptr,
kDefaultLength + 100, false, false);
manager_.OnPacketSent(&packet, 0, clock_.Now(), NOT_RETRANSMISSION,
HAS_RETRANSMITTABLE_DATA);
@@ -2454,12 +2576,41 @@ TEST_P(QuicSentPacketManagerTest, PathMtuIncreased) {
EXPECT_CALL(*network_change_visitor_,
OnPathMtuIncreased(kDefaultLength + 100));
QuicAckFrame ack_frame = InitAckFrame(1);
- if (GetQuicReloadableFlag(quic_use_incremental_ack_processing)) {
- manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite());
- manager_.OnAckRange(1, 2, /*last_range=*/true, clock_.Now());
+ if (GetQuicReloadableFlag(quic_use_incremental_ack_processing3)) {
+ manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(1, 2);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
} else {
- manager_.OnIncomingAck(ack_frame, clock_.Now());
+ EXPECT_TRUE(manager_.OnIncomingAck(ack_frame, clock_.Now()));
+ }
+}
+
+TEST_P(QuicSentPacketManagerTest, OnAckRangeSlowPath) {
+ SetQuicReloadableFlag(quic_use_incremental_ack_processing3, true);
+ // Send packets 1 - 20.
+ for (size_t i = 1; i <= 20; ++i) {
+ SendDataPacket(i);
}
+ // Ack [5, 7), [10, 12), [15, 17).
+ QuicPacketNumber acked1[] = {5, 6, 10, 11, 15, 16};
+ QuicPacketNumber lost1[] = {1, 2, 3, 4, 7, 8, 9, 12, 13};
+ ExpectAcksAndLosses(true, acked1, QUIC_ARRAYSIZE(acked1), lost1,
+ QUIC_ARRAYSIZE(lost1));
+ EXPECT_CALL(notifier_, OnFrameLost(_)).Times(AnyNumber());
+ manager_.OnAckFrameStart(16, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(15, 17);
+ manager_.OnAckRange(10, 12);
+ manager_.OnAckRange(5, 7);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+ // Ack [4, 8), [9, 13), [14, 21).
+ QuicPacketNumber acked2[] = {4, 7, 9, 12, 14, 17, 18, 19, 20};
+ ExpectAcksAndLosses(true, acked2, QUIC_ARRAYSIZE(acked2), nullptr, 0);
+ manager_.OnAckFrameStart(20, QuicTime::Delta::Infinite(), clock_.Now());
+ manager_.OnAckRange(14, 21);
+ manager_.OnAckRange(9, 13);
+ manager_.OnAckRange(4, 8);
+ EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
}
} // namespace
diff --git a/chromium/net/quic/core/quic_server_session_base_test.cc b/chromium/net/quic/core/quic_server_session_base_test.cc
index afc48cc1b62..cb8dd785c81 100644
--- a/chromium/net/quic/core/quic_server_session_base_test.cc
+++ b/chromium/net/quic/core/quic_server_session_base_test.cc
@@ -207,14 +207,9 @@ TEST_P(QuicServerSessionBaseTest, CloseStreamDueToReset) {
QuicRstStreamFrame rst1(kInvalidControlFrameId, GetNthClientInitiatedId(0),
QUIC_ERROR_PROCESSING_STREAM, 0);
EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0),
- QUIC_RST_ACKNOWLEDGEMENT));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(GetNthClientInitiatedId(0),
- QUIC_RST_ACKNOWLEDGEMENT, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0),
+ QUIC_RST_ACKNOWLEDGEMENT));
visitor_->OnRstStream(rst1);
EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
@@ -231,14 +226,9 @@ TEST_P(QuicServerSessionBaseTest, NeverOpenStreamDueToReset) {
QuicRstStreamFrame rst1(kInvalidControlFrameId, GetNthClientInitiatedId(0),
QUIC_ERROR_PROCESSING_STREAM, 0);
EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0),
- QUIC_RST_ACKNOWLEDGEMENT));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(GetNthClientInitiatedId(0),
- QUIC_RST_ACKNOWLEDGEMENT, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0),
+ QUIC_RST_ACKNOWLEDGEMENT));
visitor_->OnRstStream(rst1);
EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
@@ -266,14 +256,9 @@ TEST_P(QuicServerSessionBaseTest, AcceptClosedStream) {
QuicRstStreamFrame rst(kInvalidControlFrameId, GetNthClientInitiatedId(0),
QUIC_ERROR_PROCESSING_STREAM, 0);
EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0),
- QUIC_RST_ACKNOWLEDGEMENT));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(GetNthClientInitiatedId(0),
- QUIC_RST_ACKNOWLEDGEMENT, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0),
+ QUIC_RST_ACKNOWLEDGEMENT));
visitor_->OnRstStream(rst);
// If we were tracking, we'd probably want to reject this because it's data
@@ -322,12 +307,8 @@ TEST_P(QuicServerSessionBaseTest, MaxOpenStreams) {
// Now violate the server's internal stream limit.
stream_id += QuicSpdySessionPeer::NextStreamId(*session_);
EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream_id, QUIC_REFUSED_STREAM));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(stream_id, QUIC_REFUSED_STREAM, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(stream_id, QUIC_REFUSED_STREAM));
// Even if the connection remains open, the stream creation should fail.
EXPECT_FALSE(QuicServerSessionBasePeer::GetOrCreateDynamicStream(
session_.get(), stream_id));
@@ -424,10 +405,20 @@ TEST_P(QuicServerSessionBaseTest, BandwidthEstimates) {
const QuicString serving_region = "not a real region";
session_->set_serving_region(serving_region);
+ if (GetQuicReloadableFlag(quic_register_streams_early2) &&
+ GetQuicReloadableFlag(quic_register_static_streams)) {
+ session_->UnregisterStreamPriority(kHeadersStreamId, /*is_static=*/true);
+ }
+ QuicServerSessionBasePeer::SetCryptoStream(session_.get(), nullptr);
MockQuicCryptoServerStream* crypto_stream =
new MockQuicCryptoServerStream(&crypto_config_, &compressed_certs_cache_,
session_.get(), &stream_helper_);
QuicServerSessionBasePeer::SetCryptoStream(session_.get(), crypto_stream);
+ if (GetQuicReloadableFlag(quic_register_streams_early2) &&
+ GetQuicReloadableFlag(quic_register_static_streams)) {
+ session_->RegisterStreamPriority(kHeadersStreamId, /*is_static=*/true,
+ QuicStream::kDefaultPriority);
+ }
// Set some initial bandwidth values.
QuicSentPacketManager* sent_packet_manager =
@@ -474,7 +465,7 @@ TEST_P(QuicServerSessionBaseTest, BandwidthEstimates) {
// Bandwidth estimate has now changed sufficiently, enough time has passed,
// and enough packets have been sent.
SerializedPacket packet(1 + kMinPacketsBetweenServerConfigUpdates,
- PACKET_6BYTE_PACKET_NUMBER, nullptr, 1000, false,
+ PACKET_4BYTE_PACKET_NUMBER, nullptr, 1000, false,
false);
sent_packet_manager->OnPacketSent(&packet, 0, now, NOT_RETRANSMISSION,
HAS_RETRANSMITTABLE_DATA);
@@ -615,7 +606,7 @@ TEST_P(StreamMemberLifetimeTest, Basic) {
QuicString(chlo.GetSerialized(Perspective::IS_CLIENT)
.AsStringPiece()
.as_string()),
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
+ PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
&packet_version_list));
EXPECT_CALL(stream_helper_, CanAcceptClientHello(_, _, _))
diff --git a/chromium/net/quic/core/quic_session.cc b/chromium/net/quic/core/quic_session.cc
index 636e2ed8ccc..91157d7db7f 100644
--- a/chromium/net/quic/core/quic_session.cc
+++ b/chromium/net/quic/core/quic_session.cc
@@ -17,13 +17,15 @@
#include "net/quic/platform/api/quic_str_cat.h"
#include "net/quic/platform/api/quic_string.h"
+using net::SpdyPriority;
+
namespace net {
namespace {
// Stateless reset token used in IETF public reset packet.
// TODO(fayang): use a real stateless reset token instead of a hard code one.
-const uint128 kStatelessResetToken = 1010101;
+const QuicUint128 kStatelessResetToken = 1010101;
} // namespace
@@ -35,6 +37,11 @@ QuicSession::QuicSession(QuicConnection* connection,
const QuicConfig& config)
: connection_(connection),
visitor_(owner),
+ register_streams_early_(
+ GetQuicReloadableFlag(quic_register_streams_early2)),
+ write_blocked_streams_(
+ GetQuicReloadableFlag(quic_register_static_streams) &&
+ register_streams_early_),
config_(config),
max_open_outgoing_streams_(kDefaultMaxStreamsPerConnection),
max_open_incoming_streams_(config_.GetMaxIncomingDynamicStreamsToSend()),
@@ -56,12 +63,9 @@ QuicSession::QuicSession(QuicConnection* connection,
currently_writing_stream_id_(0),
goaway_sent_(false),
goaway_received_(false),
- control_frame_manager_(this),
- can_use_slices_(GetQuicReloadableFlag(quic_use_mem_slices)),
- session_unblocks_stream_(
- GetQuicReloadableFlag(quic_streams_unblocked_by_session2)) {
- if (use_control_frame_manager()) {
- QUIC_FLAG_COUNT(quic_reloadable_flag_quic_use_control_frame_manager);
+ control_frame_manager_(this) {
+ if (register_streams_early()) {
+ QUIC_FLAG_COUNT(quic_reloadable_flag_quic_register_streams_early2);
}
}
@@ -212,6 +216,8 @@ bool QuicSession::AllowSelfAddressChange() const {
return false;
}
+void QuicSession::OnForwardProgressConfirmed() {}
+
void QuicSession::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
// Stream may be closed by the time we receive a WINDOW_UPDATE, so we can't
// assume that it still exists.
@@ -299,35 +305,27 @@ void QuicSession::OnCanWrite() {
// streams become pending, WillingAndAbleToWrite will be true, which will
// cause the connection to request resumption before yielding to other
// connections.
- size_t num_writes = write_blocked_streams_.NumBlockedStreams();
- if (flow_controller_.IsBlocked()) {
- // If we are connection level flow control blocked, then only allow the
- // crypto and headers streams to try writing as all other streams will be
- // blocked.
- num_writes = 0;
- if (write_blocked_streams_.crypto_stream_blocked()) {
- num_writes += 1;
- }
- if (write_blocked_streams_.headers_stream_blocked()) {
- num_writes += 1;
- }
- }
- if (num_writes == 0 && (!use_control_frame_manager() ||
- !control_frame_manager_.WillingToWrite())) {
+ // If we are connection level flow control blocked, then only allow the
+ // crypto and headers streams to try writing as all other streams will be
+ // blocked.
+ size_t num_writes = flow_controller_.IsBlocked()
+ ? write_blocked_streams_.NumBlockedSpecialStreams()
+ : write_blocked_streams_.NumBlockedStreams();
+ if (num_writes == 0 && !control_frame_manager_.WillingToWrite()) {
return;
}
QuicConnection::ScopedPacketFlusher flusher(
connection_, QuicConnection::SEND_ACK_IF_QUEUED);
- if (use_control_frame_manager() && control_frame_manager_.WillingToWrite()) {
+ if (control_frame_manager_.WillingToWrite()) {
control_frame_manager_.OnCanWrite();
}
for (size_t i = 0; i < num_writes; ++i) {
- if (!(write_blocked_streams_.HasWriteBlockedCryptoOrHeadersStream() ||
+ if (!(write_blocked_streams_.HasWriteBlockedSpecialStream() ||
write_blocked_streams_.HasWriteBlockedDataStreams())) {
// Writing one stream removed another!? Something's broken.
QUIC_BUG << "WriteBlockedStream is missing";
- RecordInternalErrorLocation(QUIC_SESSION_1);
+ RecordInternalErrorLocation(QUIC_SESSION_ON_CAN_WRITE);
connection_->CloseConnection(QUIC_INTERNAL_ERROR,
"WriteBlockedStream is missing",
ConnectionCloseBehavior::SILENT_CLOSE);
@@ -361,10 +359,9 @@ bool QuicSession::WillingAndAbleToWrite() const {
// 3) If the crypto or headers streams are blocked, or
// 4) connection is not flow control blocked and there are write blocked
// streams.
- return (use_control_frame_manager() &&
- control_frame_manager_.WillingToWrite()) ||
+ return control_frame_manager_.WillingToWrite() ||
!streams_with_pending_retransmission_.empty() ||
- write_blocked_streams_.HasWriteBlockedCryptoOrHeadersStream() ||
+ write_blocked_streams_.HasWriteBlockedSpecialStream() ||
(!flow_controller_.IsBlocked() &&
write_blocked_streams_.HasWriteBlockedDataStreams());
}
@@ -372,7 +369,7 @@ bool QuicSession::WillingAndAbleToWrite() const {
bool QuicSession::HasPendingHandshake() const {
return QuicContainsKey(streams_with_pending_retransmission_,
kCryptoStreamId) ||
- write_blocked_streams_.crypto_stream_blocked();
+ write_blocked_streams_.IsStreamBlocked(kCryptoStreamId);
}
bool QuicSession::HasOpenDynamicStreams() const {
@@ -398,7 +395,7 @@ QuicConsumedData QuicSession::WritevData(QuicStream* stream,
// seems like a reasonable mitigation.
if (id == kCryptoStreamId && stream != GetMutableCryptoStream()) {
QUIC_BUG << "Stream id mismatch";
- RecordInternalErrorLocation(QUIC_SESSION_2);
+ RecordInternalErrorLocation(QUIC_SESSION_WRITEV_DATA);
connection_->CloseConnection(
QUIC_INTERNAL_ERROR,
"Non-crypto stream attempted to write data as crypto stream.",
@@ -420,7 +417,6 @@ QuicConsumedData QuicSession::WritevData(QuicStream* stream,
}
bool QuicSession::WriteControlFrame(const QuicFrame& frame) {
- DCHECK(use_control_frame_manager());
return connection_->SendControlFrame(frame);
}
@@ -434,12 +430,8 @@ void QuicSession::SendRstStream(QuicStreamId id,
if (connection()->connected()) {
// Only send a RST_STREAM frame if still connected.
- if (use_control_frame_manager()) {
- control_frame_manager_.WriteOrBufferRstStream(id, error, bytes_written);
- connection_->OnStreamReset(id, error);
- } else {
- connection_->SendRstStream(id, error, bytes_written);
- }
+ control_frame_manager_.WriteOrBufferRstStream(id, error, bytes_written);
+ connection_->OnStreamReset(id, error);
}
CloseStreamInner(id, true);
}
@@ -450,23 +442,16 @@ void QuicSession::SendGoAway(QuicErrorCode error_code,
return;
}
goaway_sent_ = true;
- if (use_control_frame_manager()) {
- control_frame_manager_.WriteOrBufferGoAway(
- error_code, largest_peer_created_stream_id_, reason);
- } else {
- connection_->SendGoAway(error_code, largest_peer_created_stream_id_,
- reason);
- }
+ control_frame_manager_.WriteOrBufferGoAway(
+ error_code, largest_peer_created_stream_id_, reason);
}
void QuicSession::SendBlocked(QuicStreamId id) {
- DCHECK(use_control_frame_manager());
control_frame_manager_.WriteOrBufferBlocked(id);
}
void QuicSession::SendWindowUpdate(QuicStreamId id,
QuicStreamOffset byte_offset) {
- DCHECK(use_control_frame_manager());
control_frame_manager_.WriteOrBufferWindowUpdate(id, byte_offset);
}
@@ -484,14 +469,14 @@ void QuicSession::InsertLocallyClosedStreamsHighestOffset(
}
void QuicSession::CloseStreamInner(QuicStreamId stream_id, bool locally_reset) {
- QUIC_DLOG(INFO) << ENDPOINT << "Closing stream " << stream_id;
+ QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << stream_id;
DynamicStreamMap::iterator it = dynamic_stream_map_.find(stream_id);
if (it == dynamic_stream_map_.end()) {
// When CloseStreamInner has been called recursively (via
// QuicStream::OnClose), the stream will already have been deleted
// from stream_map_, so return immediately.
- QUIC_DLOG(INFO) << ENDPOINT << "Stream is already closed: " << stream_id;
+ QUIC_DVLOG(1) << ENDPOINT << "Stream is already closed: " << stream_id;
return;
}
QuicStream* stream = it->second.get();
@@ -752,14 +737,48 @@ void QuicSession::OnCryptoHandshakeMessageSent(
void QuicSession::OnCryptoHandshakeMessageReceived(
const CryptoHandshakeMessage& /*message*/) {}
+void QuicSession::RegisterStreamPriority(QuicStreamId id,
+ bool is_static,
+ SpdyPriority priority) {
+ // Static streams should not be registered unless register_streams_early
+ // is true.
+ DCHECK(register_streams_early() || !is_static);
+ // Static streams do not need to be registered with the write blocked list,
+ // since it has special handling for them.
+ if (!write_blocked_streams()->register_static_streams() &&
+ register_streams_early() && is_static) {
+ return;
+ }
+
+ write_blocked_streams()->RegisterStream(id, is_static, priority);
+}
+
+void QuicSession::UnregisterStreamPriority(QuicStreamId id, bool is_static) {
+ // Static streams should not be registered unless register_streams_early
+ // is true.
+ DCHECK(register_streams_early() || !is_static);
+ // Static streams do not need to be registered with the write blocked list,
+ // since it has special handling for them.
+ if (!write_blocked_streams()->register_static_streams() &&
+ register_streams_early() && is_static) {
+ return;
+ }
+ write_blocked_streams()->UnregisterStream(id, is_static);
+}
+
+void QuicSession::UpdateStreamPriority(QuicStreamId id,
+ SpdyPriority new_priority) {
+ write_blocked_streams()->UpdateStreamPriority(id, new_priority);
+}
+
QuicConfig* QuicSession::config() {
return &config_;
}
void QuicSession::ActivateStream(std::unique_ptr<QuicStream> stream) {
QuicStreamId stream_id = stream->id();
- QUIC_DLOG(INFO) << ENDPOINT << "num_streams: " << dynamic_stream_map_.size()
- << ". activating " << stream_id;
+ QUIC_DVLOG(1) << ENDPOINT << "num_streams: " << dynamic_stream_map_.size()
+ << ". activating " << stream_id;
DCHECK(!QuicContainsKey(dynamic_stream_map_, stream_id));
DCHECK(!QuicContainsKey(static_stream_map_, stream_id));
dynamic_stream_map_[stream_id] = std::move(stream);
@@ -837,14 +856,6 @@ bool QuicSession::ShouldYield(QuicStreamId stream_id) {
return write_blocked_streams()->ShouldYield(stream_id);
}
-void QuicSession::NeuterUnencryptedStreamData() {
- QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
- crypto_stream->NeuterUnencryptedStreamData();
- if (!crypto_stream->HasPendingRetransmission()) {
- streams_with_pending_retransmission_.erase(kCryptoStreamId);
- }
-}
-
QuicStream* QuicSession::GetOrCreateDynamicStream(
const QuicStreamId stream_id) {
DCHECK(!QuicContainsKey(static_stream_map_, stream_id))
@@ -927,9 +938,9 @@ size_t QuicSession::GetNumOpenIncomingStreams() const {
}
size_t QuicSession::GetNumOpenOutgoingStreams() const {
- CHECK_GE(GetNumDynamicOutgoingStreams() +
- GetNumLocallyClosedOutgoingStreamsHighestOffset(),
- GetNumDrainingOutgoingStreams());
+ DCHECK_GE(GetNumDynamicOutgoingStreams() +
+ GetNumLocallyClosedOutgoingStreamsHighestOffset(),
+ GetNumDrainingOutgoingStreams());
return GetNumDynamicOutgoingStreams() +
GetNumLocallyClosedOutgoingStreamsHighestOffset() -
GetNumDrainingOutgoingStreams();
@@ -951,12 +962,11 @@ void QuicSession::MarkConnectionLevelWriteBlocked(QuicStreamId id) {
}
bool QuicSession::HasDataToWrite() const {
- return write_blocked_streams_.HasWriteBlockedCryptoOrHeadersStream() ||
+ return write_blocked_streams_.HasWriteBlockedSpecialStream() ||
write_blocked_streams_.HasWriteBlockedDataStreams() ||
connection_->HasQueuedData() ||
!streams_with_pending_retransmission_.empty() ||
- (use_control_frame_manager() &&
- control_frame_manager_.WillingToWrite());
+ control_frame_manager_.WillingToWrite();
}
void QuicSession::PostProcessAfterData() {
@@ -965,13 +975,16 @@ void QuicSession::PostProcessAfterData() {
void QuicSession::OnAckNeedsRetransmittableFrame() {
flow_controller_.SendWindowUpdate();
- if (use_control_frame_manager() && !control_frame_manager_.WillingToWrite()) {
+ if (GetQuicReloadableFlag(quic_remove_redundant_ping)) {
+ QUIC_FLAG_COUNT(quic_reloadable_flag_quic_remove_redundant_ping);
+ return;
+ }
+ if (!control_frame_manager_.WillingToWrite()) {
SendPing();
}
}
void QuicSession::SendPing() {
- DCHECK(use_control_frame_manager());
control_frame_manager_.WritePing();
}
@@ -1049,10 +1062,7 @@ QuicStream* QuicSession::GetStream(QuicStreamId id) const {
bool QuicSession::OnFrameAcked(const QuicFrame& frame,
QuicTime::Delta ack_delay_time) {
if (frame.type != STREAM_FRAME) {
- if (use_control_frame_manager()) {
- return control_frame_manager_.OnControlFrameAcked(frame);
- }
- return false;
+ return control_frame_manager_.OnControlFrameAcked(frame);
}
bool new_stream_data_acked = false;
QuicStream* stream = GetStream(frame.stream_frame->stream_id);
@@ -1073,7 +1083,7 @@ void QuicSession::OnStreamFrameRetransmitted(const QuicStreamFrame& frame) {
if (stream == nullptr) {
QUIC_BUG << "Stream: " << frame.stream_id << " is closed when " << frame
<< " is retransmitted.";
- RecordInternalErrorLocation(QUIC_SESSION_3);
+ RecordInternalErrorLocation(QUIC_SESSION_STREAM_FRAME_RETRANSMITTED);
connection()->CloseConnection(
QUIC_INTERNAL_ERROR, "Attempt to retransmit frame of a closed stream",
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
@@ -1085,9 +1095,7 @@ void QuicSession::OnStreamFrameRetransmitted(const QuicStreamFrame& frame) {
void QuicSession::OnFrameLost(const QuicFrame& frame) {
if (frame.type != STREAM_FRAME) {
- if (use_control_frame_manager()) {
- control_frame_manager_.OnControlFrameLost(frame);
- }
+ control_frame_manager_.OnControlFrameLost(frame);
return;
}
QuicStream* stream = GetStream(frame.stream_frame->stream_id);
@@ -1112,8 +1120,7 @@ void QuicSession::RetransmitFrames(const QuicFrames& frames,
SetTransmissionType(type);
for (const QuicFrame& frame : frames) {
if (frame.type != STREAM_FRAME) {
- if (use_control_frame_manager() &&
- !control_frame_manager_.RetransmitControlFrame(frame)) {
+ if (!control_frame_manager_.RetransmitControlFrame(frame)) {
break;
}
continue;
@@ -1130,10 +1137,7 @@ void QuicSession::RetransmitFrames(const QuicFrames& frames,
bool QuicSession::IsFrameOutstanding(const QuicFrame& frame) const {
if (frame.type != STREAM_FRAME) {
- if (use_control_frame_manager()) {
- return control_frame_manager_.IsControlFrameOutstanding(frame);
- }
- return false;
+ return control_frame_manager_.IsControlFrameOutstanding(frame);
}
QuicStream* stream = GetStream(frame.stream_frame->stream_id);
return stream != nullptr &&
@@ -1160,7 +1164,7 @@ bool QuicSession::WriteStreamData(QuicStreamId id,
return stream->WriteStreamData(offset, data_length, writer);
}
-uint128 QuicSession::GetStatelessResetToken() const {
+QuicUint128 QuicSession::GetStatelessResetToken() const {
return kStatelessResetToken;
}
@@ -1180,8 +1184,7 @@ bool QuicSession::RetransmitLostData() {
streams_with_pending_retransmission_.erase(kCryptoStreamId);
}
}
- if (use_control_frame_manager() &&
- control_frame_manager_.HasPendingRetransmission()) {
+ if (control_frame_manager_.HasPendingRetransmission()) {
SetTransmissionType(LOSS_RETRANSMISSION);
control_frame_manager_.OnCanWrite();
if (control_frame_manager_.HasPendingRetransmission()) {
@@ -1229,10 +1232,6 @@ void QuicSession::SetTransmissionType(TransmissionType type) {
connection_->SetTransmissionType(type);
}
-bool QuicSession::use_control_frame_manager() const {
- return connection_->use_control_frame_manager();
-}
-
bool QuicSession::session_decides_what_to_write() const {
return connection_->session_decides_what_to_write();
}
diff --git a/chromium/net/quic/core/quic_session.h b/chromium/net/quic/core/quic_session.h
index a1db9b35a8e..c853834d134 100644
--- a/chromium/net/quic/core/quic_session.h
+++ b/chromium/net/quic/core/quic_session.h
@@ -14,7 +14,6 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "net/base/int128.h"
#include "net/quic/core/quic_connection.h"
#include "net/quic/core/quic_control_frame_manager.h"
#include "net/quic/core/quic_crypto_stream.h"
@@ -117,6 +116,7 @@ class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface,
bool HasOpenDynamicStreams() const override;
void OnPathDegrading() override;
bool AllowSelfAddressChange() const override;
+ void OnForwardProgressConfirmed() override;
// QuicStreamFrameDataProducer
bool WriteStreamData(QuicStreamId id,
@@ -200,6 +200,17 @@ class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface,
virtual void OnCryptoHandshakeMessageReceived(
const CryptoHandshakeMessage& message);
+ // Called by the stream on creation to set priority in the write blocked list.
+ virtual void RegisterStreamPriority(QuicStreamId id,
+ bool is_static,
+ SpdyPriority priority);
+ // Called by the stream on deletion to clear priority crom the write blocked
+ // list.
+ virtual void UnregisterStreamPriority(QuicStreamId id, bool is_static);
+ // Called by the stream on SetPriority to update priority on the write blocked
+ // list.
+ virtual void UpdateStreamPriority(QuicStreamId id, SpdyPriority new_priority);
+
// Returns mutable config for this session. Returned config is owned
// by QuicSession.
QuicConfig* config();
@@ -294,17 +305,10 @@ class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface,
// Returns true if this stream should yield writes to another blocked stream.
bool ShouldYield(QuicStreamId stream_id);
- // Called to cancel retransmission of unencrypted stream data.
- void NeuterUnencryptedStreamData();
-
// Set transmission type of next sending packets.
void SetTransmissionType(TransmissionType type);
- bool can_use_slices() const { return can_use_slices_; }
-
- bool session_unblocks_stream() const { return session_unblocks_stream_; }
-
- bool use_control_frame_manager() const;
+ bool register_streams_early() const { return register_streams_early_; }
bool session_decides_what_to_write() const;
@@ -424,7 +428,7 @@ class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface,
// Returns a stateless reset token which will be included in the public reset
// packet.
- virtual uint128 GetStatelessResetToken() const;
+ virtual QuicUint128 GetStatelessResetToken() const;
QuicControlFrameManager& control_frame_manager() {
return control_frame_manager_;
@@ -474,8 +478,15 @@ class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface,
// May be null.
Visitor* visitor_;
- ClosedStreams closed_streams_;
+ // Latched value of quic_reloadable_flag_quic_register_streams_early2.
+ const bool register_streams_early_;
+
+ // A list of streams which need to write more data. Stream register
+ // themselves in their constructor, and unregisterm themselves in their
+ // destructors, so the write blocked list must outlive all streams.
+ QuicWriteBlockedList write_blocked_streams_;
+ ClosedStreams closed_streams_;
// Streams which are closed, but need to be kept alive. Currently, the only
// reason is the stream's sent data (including FIN) does not get fully acked.
ZombieStreamMap zombie_streams_;
@@ -507,9 +518,6 @@ class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface,
// been consumed.
QuicUnorderedSet<QuicStreamId> draining_streams_;
- // A list of streams which need to write more data.
- QuicWriteBlockedList write_blocked_streams_;
-
QuicStreamId largest_peer_created_stream_id_;
// A counter for peer initiated streams which are in the dynamic_stream_map_.
@@ -540,18 +548,11 @@ class QUIC_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface,
QuicControlFrameManager control_frame_manager_;
- // QUIC stream can take ownership of application data provided in reference
- // counted memory to avoid data copy.
- const bool can_use_slices_;
-
// TODO(fayang): switch to linked_hash_set when chromium supports it. The bool
// is not used here.
// List of streams with pending retransmissions.
QuicLinkedHashMap<QuicStreamId, bool> streams_with_pending_retransmission_;
- // Latched value of quic_reloadable_flag_quic_streams_unblocked_by_session2.
- const bool session_unblocks_stream_;
-
DISALLOW_COPY_AND_ASSIGN(QuicSession);
};
diff --git a/chromium/net/quic/core/quic_session_test.cc b/chromium/net/quic/core/quic_session_test.cc
new file mode 100644
index 00000000000..abc67d61a8c
--- /dev/null
+++ b/chromium/net/quic/core/quic_session_test.cc
@@ -0,0 +1,1427 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/core/quic_session.h"
+
+#include <cstdint>
+#include <set>
+#include <utility>
+
+#include "base/callback.h"
+#include "base/rand_util.h"
+#include "build/build_config.h"
+#include "net/quic/core/crypto/crypto_protocol.h"
+#include "net/quic/core/crypto/null_encrypter.h"
+#include "net/quic/core/quic_crypto_stream.h"
+#include "net/quic/core/quic_data_writer.h"
+#include "net/quic/core/quic_packets.h"
+#include "net/quic/core/quic_stream.h"
+#include "net/quic/core/quic_utils.h"
+#include "net/quic/platform/api/quic_flags.h"
+#include "net/quic/platform/api/quic_map_util.h"
+#include "net/quic/platform/api/quic_ptr_util.h"
+#include "net/quic/platform/api/quic_str_cat.h"
+#include "net/quic/platform/api/quic_string.h"
+#include "net/quic/platform/api/quic_string_piece.h"
+#include "net/quic/platform/api/quic_test.h"
+#include "net/quic/test_tools/quic_config_peer.h"
+#include "net/quic/test_tools/quic_connection_peer.h"
+#include "net/quic/test_tools/quic_flow_controller_peer.h"
+#include "net/quic/test_tools/quic_session_peer.h"
+#include "net/quic/test_tools/quic_stream_peer.h"
+#include "net/quic/test_tools/quic_stream_send_buffer_peer.h"
+#include "net/quic/test_tools/quic_test_utils.h"
+#include "net/test/gtest_util.h"
+#include "testing/gmock_mutant.h"
+
+using net::kV3HighestPriority;
+using net::SpdyPriority;
+using testing::_;
+using testing::AtLeast;
+using testing::InSequence;
+using testing::Invoke;
+using testing::Return;
+using testing::StrictMock;
+
+namespace net {
+namespace test {
+namespace {
+
+class TestCryptoStream : public QuicCryptoStream, public QuicCryptoHandshaker {
+ public:
+ explicit TestCryptoStream(QuicSession* session)
+ : QuicCryptoStream(session),
+ QuicCryptoHandshaker(this, session),
+ encryption_established_(false),
+ handshake_confirmed_(false),
+ params_(new QuicCryptoNegotiatedParameters) {}
+
+ void OnHandshakeMessage(const CryptoHandshakeMessage& /*message*/) override {
+ encryption_established_ = true;
+ handshake_confirmed_ = true;
+ CryptoHandshakeMessage msg;
+ QuicString error_details;
+ session()->config()->SetInitialStreamFlowControlWindowToSend(
+ kInitialStreamFlowControlWindowForTest);
+ session()->config()->SetInitialSessionFlowControlWindowToSend(
+ kInitialSessionFlowControlWindowForTest);
+ session()->config()->ToHandshakeMessage(&msg);
+ const QuicErrorCode error =
+ session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
+ EXPECT_EQ(QUIC_NO_ERROR, error);
+ session()->OnConfigNegotiated();
+ session()->connection()->SetDefaultEncryptionLevel(
+ ENCRYPTION_FORWARD_SECURE);
+ session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
+ }
+
+ // QuicCryptoStream implementation
+ bool encryption_established() const override {
+ return encryption_established_;
+ }
+ bool handshake_confirmed() const override { return handshake_confirmed_; }
+ const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+ const override {
+ return *params_;
+ }
+ CryptoMessageParser* crypto_message_parser() override {
+ return QuicCryptoHandshaker::crypto_message_parser();
+ }
+
+ MOCK_METHOD0(OnCanWrite, void());
+
+ MOCK_CONST_METHOD0(HasPendingRetransmission, bool());
+
+ private:
+ using QuicCryptoStream::session;
+
+ bool encryption_established_;
+ bool handshake_confirmed_;
+ QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
+};
+
+class TestStream : public QuicStream {
+ public:
+ TestStream(QuicStreamId id, QuicSession* session)
+ : QuicStream(id, session, /*is_static=*/false) {
+ if (!session->register_streams_early()) {
+ session->RegisterStreamPriority(id, false, QuicStream::kDefaultPriority);
+ }
+ }
+
+ ~TestStream() override {
+ if (!session()->register_streams_early()) {
+ session()->UnregisterStreamPriority(id(), false);
+ }
+ }
+
+ using QuicStream::CloseWriteSide;
+
+ void OnDataAvailable() override {}
+
+ MOCK_METHOD0(OnCanWrite, void());
+ MOCK_METHOD3(RetransmitStreamData,
+ bool(QuicStreamOffset, QuicByteCount, bool));
+
+ MOCK_CONST_METHOD0(HasPendingRetransmission, bool());
+};
+
+class TestSession : public QuicSession {
+ public:
+ explicit TestSession(QuicConnection* connection)
+ : QuicSession(connection, nullptr, DefaultQuicConfig()),
+ crypto_stream_(this),
+ writev_consumes_all_data_(false) {
+ Initialize();
+ this->connection()->SetEncrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<NullEncrypter>(connection->perspective()));
+ }
+
+ ~TestSession() override { delete connection(); }
+
+ TestCryptoStream* GetMutableCryptoStream() override {
+ return &crypto_stream_;
+ }
+
+ const TestCryptoStream* GetCryptoStream() const override {
+ return &crypto_stream_;
+ }
+
+ TestStream* CreateOutgoingDynamicStream() override {
+ TestStream* stream = new TestStream(GetNextOutgoingStreamId(), this);
+ ActivateStream(QuicWrapUnique(stream));
+ return stream;
+ }
+
+ TestStream* CreateIncomingDynamicStream(QuicStreamId id) override {
+ // Enforce the limit on the number of open streams.
+ if (GetNumOpenIncomingStreams() + 1 > max_open_incoming_streams()) {
+ connection()->CloseConnection(
+ QUIC_TOO_MANY_OPEN_STREAMS, "Too many streams!",
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return nullptr;
+ } else {
+ TestStream* stream = new TestStream(id, this);
+ ActivateStream(QuicWrapUnique(stream));
+ return stream;
+ }
+ }
+
+ bool IsClosedStream(QuicStreamId id) {
+ return QuicSession::IsClosedStream(id);
+ }
+
+ QuicStream* GetOrCreateDynamicStream(QuicStreamId stream_id) {
+ return QuicSession::GetOrCreateDynamicStream(stream_id);
+ }
+
+ QuicConsumedData WritevData(QuicStream* stream,
+ QuicStreamId id,
+ size_t write_length,
+ QuicStreamOffset offset,
+ StreamSendingState state) override {
+ bool fin = state != NO_FIN;
+ QuicConsumedData consumed(write_length, fin);
+ if (!writev_consumes_all_data_) {
+ consumed =
+ QuicSession::WritevData(stream, id, write_length, offset, state);
+ }
+ if (fin && consumed.fin_consumed) {
+ stream->set_fin_sent(true);
+ }
+ QuicSessionPeer::GetWriteBlockedStreams(this)->UpdateBytesForStream(
+ id, consumed.bytes_consumed);
+ return consumed;
+ }
+
+ void set_writev_consumes_all_data(bool val) {
+ writev_consumes_all_data_ = val;
+ }
+
+ QuicConsumedData SendStreamData(QuicStream* stream) {
+ struct iovec iov;
+ if (stream->id() != kCryptoStreamId) {
+ this->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
+ }
+ MakeIOVector("not empty", &iov);
+ QuicStreamPeer::SendBuffer(stream).SaveStreamData(&iov, 1, 0, 9);
+ QuicConsumedData consumed = WritevData(stream, stream->id(), 9, 0, FIN);
+ QuicStreamPeer::SendBuffer(stream).OnStreamDataConsumed(
+ consumed.bytes_consumed);
+ return consumed;
+ }
+
+ bool ClearControlFrame(const QuicFrame& frame) {
+ DeleteFrame(&const_cast<QuicFrame&>(frame));
+ return true;
+ }
+
+ QuicConsumedData SendLargeFakeData(QuicStream* stream, int bytes) {
+ DCHECK(writev_consumes_all_data_);
+ return WritevData(stream, stream->id(), bytes, 0, FIN);
+ }
+
+ using QuicSession::closed_streams;
+ using QuicSession::next_outgoing_stream_id;
+ using QuicSession::PostProcessAfterData;
+ using QuicSession::zombie_streams;
+
+ private:
+ StrictMock<TestCryptoStream> crypto_stream_;
+
+ bool writev_consumes_all_data_;
+};
+
+class QuicSessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
+ protected:
+ explicit QuicSessionTestBase(Perspective perspective)
+ : connection_(
+ new StrictMock<MockQuicConnection>(&helper_,
+ &alarm_factory_,
+ perspective,
+ SupportedVersions(GetParam()))),
+ session_(connection_) {
+ session_.config()->SetInitialStreamFlowControlWindowToSend(
+ kInitialStreamFlowControlWindowForTest);
+ session_.config()->SetInitialSessionFlowControlWindowToSend(
+ kInitialSessionFlowControlWindowForTest);
+ connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
+ TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+ EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+ .Times(testing::AnyNumber());
+ }
+
+ void CheckClosedStreams() {
+ for (QuicStreamId i = kCryptoStreamId; i < 100; i++) {
+ if (!QuicContainsKey(closed_streams_, i)) {
+ EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i;
+ } else {
+ EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i;
+ }
+ }
+ }
+
+ void CloseStream(QuicStreamId id) {
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+ EXPECT_CALL(*connection_, OnStreamReset(id, _));
+ session_.CloseStream(id);
+ closed_streams_.insert(id);
+ }
+
+ QuicTransportVersion transport_version() const {
+ return connection_->transport_version();
+ }
+
+ QuicStreamId GetNthClientInitiatedId(int n) { return 3 + 2 * n; }
+
+ QuicStreamId GetNthServerInitiatedId(int n) { return 2 + 2 * n; }
+
+ MockQuicConnectionHelper helper_;
+ MockAlarmFactory alarm_factory_;
+ StrictMock<MockQuicConnection>* connection_;
+ TestSession session_;
+ std::set<QuicStreamId> closed_streams_;
+};
+
+class QuicSessionTestServer : public QuicSessionTestBase {
+ protected:
+ QuicSessionTestServer() : QuicSessionTestBase(Perspective::IS_SERVER) {}
+};
+
+INSTANTIATE_TEST_CASE_P(Tests,
+ QuicSessionTestServer,
+ ::testing::ValuesIn(AllSupportedVersions()));
+
+TEST_P(QuicSessionTestServer, PeerAddress) {
+ EXPECT_EQ(QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort),
+ session_.peer_address());
+}
+
+TEST_P(QuicSessionTestServer, SelfAddress) {
+ EXPECT_EQ(QuicSocketAddress(), session_.self_address());
+}
+
+TEST_P(QuicSessionTestServer, IsCryptoHandshakeConfirmed) {
+ EXPECT_FALSE(session_.IsCryptoHandshakeConfirmed());
+ CryptoHandshakeMessage message;
+ session_.GetMutableCryptoStream()->OnHandshakeMessage(message);
+ EXPECT_TRUE(session_.IsCryptoHandshakeConfirmed());
+}
+
+TEST_P(QuicSessionTestServer, IsClosedStreamDefault) {
+ // Ensure that no streams are initially closed.
+ for (QuicStreamId i = kCryptoStreamId; i < 100; i++) {
+ EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i;
+ }
+}
+
+TEST_P(QuicSessionTestServer, AvailableStreams) {
+ ASSERT_TRUE(session_.GetOrCreateDynamicStream(9) != nullptr);
+ // Both 5 and 7 should be available.
+ EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(&session_, 5));
+ EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(&session_, 7));
+ ASSERT_TRUE(session_.GetOrCreateDynamicStream(7) != nullptr);
+ ASSERT_TRUE(session_.GetOrCreateDynamicStream(5) != nullptr);
+}
+
+TEST_P(QuicSessionTestServer, IsClosedStreamLocallyCreated) {
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ EXPECT_EQ(GetNthServerInitiatedId(0), stream2->id());
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream();
+ EXPECT_EQ(GetNthServerInitiatedId(1), stream4->id());
+
+ CheckClosedStreams();
+ CloseStream(GetNthServerInitiatedId(0));
+ CheckClosedStreams();
+ CloseStream(GetNthServerInitiatedId(1));
+ CheckClosedStreams();
+}
+
+TEST_P(QuicSessionTestServer, IsClosedStreamPeerCreated) {
+ QuicStreamId stream_id1 = GetNthClientInitiatedId(0);
+ QuicStreamId stream_id2 = GetNthClientInitiatedId(1);
+ session_.GetOrCreateDynamicStream(stream_id1);
+ session_.GetOrCreateDynamicStream(stream_id2);
+
+ CheckClosedStreams();
+ CloseStream(stream_id1);
+ CheckClosedStreams();
+ CloseStream(stream_id2);
+ // Create a stream, and make another available.
+ QuicStream* stream3 = session_.GetOrCreateDynamicStream(stream_id2 + 4);
+ CheckClosedStreams();
+ // Close one, but make sure the other is still not closed
+ CloseStream(stream3->id());
+ CheckClosedStreams();
+}
+
+TEST_P(QuicSessionTestServer, MaximumAvailableOpenedStreams) {
+ QuicStreamId stream_id = GetNthClientInitiatedId(0);
+ session_.GetOrCreateDynamicStream(stream_id);
+ EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+ EXPECT_NE(nullptr,
+ session_.GetOrCreateDynamicStream(
+ stream_id + 2 * (session_.max_open_incoming_streams() - 1)));
+}
+
+TEST_P(QuicSessionTestServer, TooManyAvailableStreams) {
+ QuicStreamId stream_id1 = GetNthClientInitiatedId(0);
+ QuicStreamId stream_id2;
+ EXPECT_NE(nullptr, session_.GetOrCreateDynamicStream(stream_id1));
+ // A stream ID which is too large to create.
+ stream_id2 = GetNthClientInitiatedId(2 * session_.MaxAvailableStreams() + 4);
+ EXPECT_CALL(*connection_,
+ CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
+ EXPECT_EQ(nullptr, session_.GetOrCreateDynamicStream(stream_id2));
+}
+
+TEST_P(QuicSessionTestServer, ManyAvailableStreams) {
+ // When max_open_streams_ is 200, should be able to create 200 streams
+ // out-of-order, that is, creating the one with the largest stream ID first.
+ QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
+ QuicStreamId stream_id = GetNthClientInitiatedId(0);
+ // Create one stream.
+ session_.GetOrCreateDynamicStream(stream_id);
+ EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
+ // Create the largest stream ID of a threatened total of 200 streams.
+ session_.GetOrCreateDynamicStream(stream_id + 2 * (200 - 1));
+}
+
+TEST_P(QuicSessionTestServer, DebugDFatalIfMarkingClosedStreamWriteBlocked) {
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ QuicStreamId closed_stream_id = stream2->id();
+ // Close the stream.
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(closed_stream_id, _));
+ stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
+ QuicString msg =
+ QuicStrCat("Marking unknown stream ", closed_stream_id, " blocked.");
+ EXPECT_QUIC_BUG(session_.MarkConnectionLevelWriteBlocked(closed_stream_id),
+ msg);
+}
+
+TEST_P(QuicSessionTestServer, OnCanWrite) {
+ session_.set_writev_consumes_all_data(true);
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream6 = session_.CreateOutgoingDynamicStream();
+
+ session_.MarkConnectionLevelWriteBlocked(stream2->id());
+ session_.MarkConnectionLevelWriteBlocked(stream6->id());
+ session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+ InSequence s;
+
+ // Reregister, to test the loop limit.
+ EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+ session_.SendStreamData(stream2);
+ session_.MarkConnectionLevelWriteBlocked(stream2->id());
+ }));
+ // 2 will get called a second time as it didn't finish its block
+ EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+ session_.SendStreamData(stream2);
+ }));
+ EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+ session_.SendStreamData(stream6);
+ }));
+ // 4 will not get called, as we exceeded the loop limit.
+ session_.OnCanWrite();
+ EXPECT_TRUE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, TestBatchedWrites) {
+ session_.set_writev_consumes_all_data(true);
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream6 = session_.CreateOutgoingDynamicStream();
+
+ session_.set_writev_consumes_all_data(true);
+ session_.MarkConnectionLevelWriteBlocked(stream2->id());
+ session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+ // With two sessions blocked, we should get two write calls. They should both
+ // go to the first stream as it will only write 6k and mark itself blocked
+ // again.
+ InSequence s;
+ EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+ session_.SendLargeFakeData(stream2, 6000);
+ session_.MarkConnectionLevelWriteBlocked(stream2->id());
+ }));
+ EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+ session_.SendLargeFakeData(stream2, 6000);
+ session_.MarkConnectionLevelWriteBlocked(stream2->id());
+ }));
+ session_.OnCanWrite();
+
+ // We should get one more call for stream2, at which point it has used its
+ // write quota and we move over to stream 4.
+ EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+ session_.SendLargeFakeData(stream2, 6000);
+ session_.MarkConnectionLevelWriteBlocked(stream2->id());
+ }));
+ EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+ session_.SendLargeFakeData(stream4, 6000);
+ session_.MarkConnectionLevelWriteBlocked(stream4->id());
+ }));
+ session_.OnCanWrite();
+
+ // Now let stream 4 do the 2nd of its 3 writes, but add a block for a high
+ // priority stream 6. 4 should be preempted. 6 will write but *not* block so
+ // will cede back to 4.
+ stream6->SetPriority(kV3HighestPriority);
+ EXPECT_CALL(*stream4, OnCanWrite())
+ .WillOnce(Invoke([this, stream4, stream6]() {
+ session_.SendLargeFakeData(stream4, 6000);
+ session_.MarkConnectionLevelWriteBlocked(stream4->id());
+ session_.MarkConnectionLevelWriteBlocked(stream6->id());
+ }));
+ EXPECT_CALL(*stream6, OnCanWrite())
+ .WillOnce(Invoke([this, stream4, stream6]() {
+ session_.SendStreamData(stream6);
+ session_.SendLargeFakeData(stream4, 6000);
+ }));
+ session_.OnCanWrite();
+
+ // Stream4 alread did 6k worth of writes, so after doing another 12k it should
+ // cede and 2 should resume.
+ EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+ session_.SendLargeFakeData(stream4, 12000);
+ session_.MarkConnectionLevelWriteBlocked(stream4->id());
+ }));
+ EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+ session_.SendLargeFakeData(stream2, 6000);
+ session_.MarkConnectionLevelWriteBlocked(stream2->id());
+ }));
+ session_.OnCanWrite();
+}
+
+TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
+ // Encryption needs to be established before data can be sent.
+ CryptoHandshakeMessage msg;
+ MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+ QuicConnectionPeer::GetWriter(session_.connection()));
+ session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
+
+ // Drive congestion control manually.
+ MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+ QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream6 = session_.CreateOutgoingDynamicStream();
+
+ session_.MarkConnectionLevelWriteBlocked(stream2->id());
+ session_.MarkConnectionLevelWriteBlocked(stream6->id());
+ session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+ EXPECT_CALL(*send_algorithm, GetCongestionWindow())
+ .WillRepeatedly(Return(kMaxPacketSize * 10));
+ EXPECT_CALL(*send_algorithm, InRecovery()).WillRepeatedly(Return(false));
+ EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+ session_.SendStreamData(stream2);
+ }));
+ EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+ session_.SendStreamData(stream4);
+ }));
+ EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+ session_.SendStreamData(stream6);
+ }));
+
+ // Expect that we only send one packet, the writes from different streams
+ // should be bundled together.
+ EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
+ .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+ EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
+ EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+ session_.OnCanWrite();
+ EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, OnCanWriteCongestionControlBlocks) {
+ session_.set_writev_consumes_all_data(true);
+ InSequence s;
+
+ // Drive congestion control manually.
+ MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+ QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream6 = session_.CreateOutgoingDynamicStream();
+
+ session_.MarkConnectionLevelWriteBlocked(stream2->id());
+ session_.MarkConnectionLevelWriteBlocked(stream6->id());
+ session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+ EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+ session_.SendStreamData(stream2);
+ }));
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+ EXPECT_CALL(*stream6, OnCanWrite()).WillOnce(Invoke([this, stream6]() {
+ session_.SendStreamData(stream6);
+ }));
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
+ // stream4->OnCanWrite is not called.
+
+ session_.OnCanWrite();
+ EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+ // Still congestion-control blocked.
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(false));
+ session_.OnCanWrite();
+ EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+ // stream4->OnCanWrite is called once the connection stops being
+ // congestion-control blocked.
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+ EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+ session_.SendStreamData(stream4);
+ }));
+ EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+ session_.OnCanWrite();
+ EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, OnCanWriteWriterBlocks) {
+ // Drive congestion control manually in order to ensure that
+ // application-limited signaling is handled correctly.
+ MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+ QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+
+ // Drive packet writer manually.
+ MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+ QuicConnectionPeer::GetWriter(session_.connection()));
+ EXPECT_CALL(*writer, IsWriteBlocked()).WillRepeatedly(Return(true));
+ EXPECT_CALL(*writer, IsWriteBlockedDataBuffered())
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(*writer, WritePacket(_, _, _, _, _)).Times(0);
+
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+
+ session_.MarkConnectionLevelWriteBlocked(stream2->id());
+
+ EXPECT_CALL(*stream2, OnCanWrite()).Times(0);
+ EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)).Times(0);
+
+ session_.OnCanWrite();
+ EXPECT_TRUE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, BufferedHandshake) {
+ session_.set_writev_consumes_all_data(true);
+ EXPECT_FALSE(session_.HasPendingHandshake()); // Default value.
+
+ // Test that blocking other streams does not change our status.
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ session_.MarkConnectionLevelWriteBlocked(stream2->id());
+ EXPECT_FALSE(session_.HasPendingHandshake());
+
+ TestStream* stream3 = session_.CreateOutgoingDynamicStream();
+ session_.MarkConnectionLevelWriteBlocked(stream3->id());
+ EXPECT_FALSE(session_.HasPendingHandshake());
+
+ // Blocking (due to buffering of) the Crypto stream is detected.
+ session_.MarkConnectionLevelWriteBlocked(kCryptoStreamId);
+ EXPECT_TRUE(session_.HasPendingHandshake());
+
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream();
+ session_.MarkConnectionLevelWriteBlocked(stream4->id());
+ EXPECT_TRUE(session_.HasPendingHandshake());
+
+ InSequence s;
+ // Force most streams to re-register, which is common scenario when we block
+ // the Crypto stream, and only the crypto stream can "really" write.
+
+ // Due to prioritization, we *should* be asked to write the crypto stream
+ // first.
+ // Don't re-register the crypto stream (which signals complete writing).
+ TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+ EXPECT_CALL(*crypto_stream, OnCanWrite());
+
+ EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+ session_.SendStreamData(stream2);
+ }));
+ EXPECT_CALL(*stream3, OnCanWrite()).WillOnce(Invoke([this, stream3]() {
+ session_.SendStreamData(stream3);
+ }));
+ EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+ session_.SendStreamData(stream4);
+ session_.MarkConnectionLevelWriteBlocked(stream4->id());
+ }));
+
+ session_.OnCanWrite();
+ EXPECT_TRUE(session_.WillingAndAbleToWrite());
+ EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote.
+}
+
+TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) {
+ session_.set_writev_consumes_all_data(true);
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream6 = session_.CreateOutgoingDynamicStream();
+
+ session_.MarkConnectionLevelWriteBlocked(stream2->id());
+ session_.MarkConnectionLevelWriteBlocked(stream6->id());
+ session_.MarkConnectionLevelWriteBlocked(stream4->id());
+ CloseStream(stream6->id());
+
+ InSequence s;
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
+ EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
+ session_.SendStreamData(stream2);
+ }));
+ EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(Invoke([this, stream4]() {
+ session_.SendStreamData(stream4);
+ }));
+ session_.OnCanWrite();
+ EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
+ // Drive congestion control manually in order to ensure that
+ // application-limited signaling is handled correctly.
+ MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+ QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(true));
+
+ // Ensure connection level flow control blockage.
+ QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0);
+ EXPECT_TRUE(session_.flow_controller()->IsBlocked());
+ EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+ EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+
+ // Mark the crypto and headers streams as write blocked, we expect them to be
+ // allowed to write later.
+ session_.MarkConnectionLevelWriteBlocked(kCryptoStreamId);
+
+ // Create a data stream, and although it is write blocked we never expect it
+ // to be allowed to write as we are connection level flow control blocked.
+ TestStream* stream = session_.CreateOutgoingDynamicStream();
+ session_.MarkConnectionLevelWriteBlocked(stream->id());
+ EXPECT_CALL(*stream, OnCanWrite()).Times(0);
+
+ // The crypto and headers streams should be called even though we are
+ // connection flow control blocked.
+ TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+ EXPECT_CALL(*crypto_stream, OnCanWrite());
+
+ // After the crypto and header streams perform a write, the connection will be
+ // blocked by the flow control, hence it should become application-limited.
+ EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+
+ session_.OnCanWrite();
+ EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, SendGoAway) {
+ MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+ QuicConnectionPeer::GetWriter(session_.connection()));
+ EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
+ .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(
+ Invoke(connection_, &MockQuicConnection::ReallySendControlFrame));
+ session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+ EXPECT_TRUE(session_.goaway_sent());
+
+ const QuicStreamId kTestStreamId = 5u;
+ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+ EXPECT_CALL(*connection_,
+ OnStreamReset(kTestStreamId, QUIC_STREAM_PEER_GOING_AWAY))
+ .Times(0);
+ EXPECT_TRUE(session_.GetOrCreateDynamicStream(kTestStreamId));
+}
+
+TEST_P(QuicSessionTestServer, DoNotSendGoAwayTwice) {
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+ session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+ EXPECT_TRUE(session_.goaway_sent());
+ session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
+}
+
+TEST_P(QuicSessionTestServer, InvalidGoAway) {
+ QuicGoAwayFrame go_away(kInvalidControlFrameId, QUIC_PEER_GOING_AWAY,
+ session_.next_outgoing_stream_id(), "");
+ session_.OnGoAway(go_away);
+}
+
+// Test that server session will send a connectivity probe in response to a
+// connectivity probe on the same path.
+TEST_P(QuicSessionTestServer, ServerReplyToConnecitivityProbe) {
+ QuicSocketAddress old_peer_address =
+ QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
+ EXPECT_EQ(old_peer_address, session_.peer_address());
+
+ QuicSocketAddress new_peer_address =
+ QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort + 1);
+
+ MockPacketWriter* writer = static_cast<MockPacketWriter*>(
+ QuicConnectionPeer::GetWriter(session_.connection()));
+ EXPECT_CALL(*writer, WritePacket(_, _, _, new_peer_address, _))
+ .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
+ EXPECT_CALL(*connection_,
+ SendConnectivityProbingPacket(nullptr, new_peer_address))
+ .WillOnce(
+ Invoke(connection_,
+ &MockQuicConnection::ReallySendConnectivityProbingPacket));
+ session_.OnConnectivityProbeReceived(session_.self_address(),
+ new_peer_address);
+ EXPECT_EQ(old_peer_address, session_.peer_address());
+}
+
+TEST_P(QuicSessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
+ EXPECT_EQ(kInitialIdleTimeoutSecs + 3,
+ QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
+ CryptoHandshakeMessage msg;
+ session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
+ EXPECT_EQ(kMaximumIdleTimeoutSecs + 3,
+ QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
+}
+
+TEST_P(QuicSessionTestServer, OnStreamFrameFinStaticStreamId) {
+ // Send two bytes of payload.
+ QuicStreamFrame data1(kCryptoStreamId, true, 0, QuicStringPiece("HT"));
+ EXPECT_CALL(*connection_,
+ CloseConnection(
+ QUIC_INVALID_STREAM_ID, "Attempt to close a static stream",
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+ session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSessionTestServer, OnRstStreamStaticStreamId) {
+ // Send two bytes of payload.
+ QuicRstStreamFrame rst1(kInvalidControlFrameId, kCryptoStreamId,
+ QUIC_ERROR_PROCESSING_STREAM, 0);
+ EXPECT_CALL(*connection_,
+ CloseConnection(
+ QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream",
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+ session_.OnRstStream(rst1);
+}
+
+TEST_P(QuicSessionTestServer, OnStreamFrameInvalidStreamId) {
+ // Send two bytes of payload.
+ QuicStreamFrame data1(kInvalidStreamId, true, 0, QuicStringPiece("HT"));
+ EXPECT_CALL(*connection_,
+ CloseConnection(
+ QUIC_INVALID_STREAM_ID, "Recevied data for an invalid stream",
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+ session_.OnStreamFrame(data1);
+}
+
+TEST_P(QuicSessionTestServer, OnRstStreamInvalidStreamId) {
+ // Send two bytes of payload.
+ QuicRstStreamFrame rst1(kInvalidControlFrameId, kInvalidStreamId,
+ QUIC_ERROR_PROCESSING_STREAM, 0);
+ EXPECT_CALL(*connection_,
+ CloseConnection(
+ QUIC_INVALID_STREAM_ID, "Recevied data for an invalid stream",
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
+ session_.OnRstStream(rst1);
+}
+
+TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
+ // Test that if a stream is flow control blocked, then on receipt of the SHLO
+ // containing a suitable send window offset, the stream becomes unblocked.
+
+ // Ensure that Writev consumes all the data it is given (simulate no socket
+ // blocking).
+ session_.set_writev_consumes_all_data(true);
+
+ // Create a stream, and send enough data to make it flow control blocked.
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ QuicString body(kMinimumFlowControlSendWindow, '.');
+ EXPECT_FALSE(stream2->flow_controller()->IsBlocked());
+ EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+ EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1));
+ stream2->WriteOrBufferData(body, false, nullptr);
+ EXPECT_TRUE(stream2->flow_controller()->IsBlocked());
+ EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
+ EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
+
+ // Now complete the crypto handshake, resulting in an increased flow control
+ // send window.
+ CryptoHandshakeMessage msg;
+ session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
+ EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id()));
+ // Stream is now unblocked.
+ EXPECT_FALSE(stream2->flow_controller()->IsBlocked());
+ EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+ EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+}
+
+TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedCryptoStream) {
+ // Test that if the crypto stream is flow control blocked, then if the SHLO
+ // contains a larger send window offset, the stream becomes unblocked.
+ session_.set_writev_consumes_all_data(true);
+ TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+ EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked());
+ EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+ EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+ EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+ EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+ for (QuicStreamId i = 0;
+ !crypto_stream->flow_controller()->IsBlocked() && i < 1000u; i++) {
+ EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+ EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+ QuicStreamOffset offset = crypto_stream->stream_bytes_written();
+ QuicConfig config;
+ CryptoHandshakeMessage crypto_message;
+ config.ToHandshakeMessage(&crypto_message);
+ crypto_stream->SendHandshakeMessage(crypto_message);
+ char buf[1000];
+ QuicDataWriter writer(1000, buf, NETWORK_BYTE_ORDER);
+ crypto_stream->WriteStreamData(offset, crypto_message.size(), &writer);
+ }
+ EXPECT_TRUE(crypto_stream->flow_controller()->IsBlocked());
+ EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+ EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
+ EXPECT_FALSE(session_.HasDataToWrite());
+ EXPECT_TRUE(crypto_stream->HasBufferedData());
+
+ // Now complete the crypto handshake, resulting in an increased flow control
+ // send window.
+ CryptoHandshakeMessage msg;
+ session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
+ EXPECT_TRUE(
+ QuicSessionPeer::IsStreamWriteBlocked(&session_, kCryptoStreamId));
+ // Stream is now unblocked and will no longer have buffered data.
+ EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked());
+ EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
+ EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
+}
+
+TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstOutOfOrder) {
+ // Test that when we receive an out of order stream RST we correctly adjust
+ // our connection level flow control receive window.
+ // On close, the stream should mark as consumed all bytes between the highest
+ // byte consumed so far and the final byte offset from the RST frame.
+ TestStream* stream = session_.CreateOutgoingDynamicStream();
+
+ const QuicStreamOffset kByteOffset =
+ 1 + kInitialSessionFlowControlWindowForTest / 2;
+
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
+ EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+ QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
+ QUIC_STREAM_CANCELLED, kByteOffset);
+ session_.OnRstStream(rst_frame);
+ session_.PostProcessAfterData();
+ EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed());
+}
+
+TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAndLocalReset) {
+ // Test the situation where we receive a FIN on a stream, and before we fully
+ // consume all the data from the sequencer buffer we locally RST the stream.
+ // The bytes between highest consumed byte, and the final byte offset that we
+ // determined when the FIN arrived, should be marked as consumed at the
+ // connection level flow controller when the stream is reset.
+ TestStream* stream = session_.CreateOutgoingDynamicStream();
+
+ const QuicStreamOffset kByteOffset =
+ kInitialSessionFlowControlWindowForTest / 2 - 1;
+ QuicStreamFrame frame(stream->id(), true, kByteOffset, ".");
+ session_.OnStreamFrame(frame);
+ session_.PostProcessAfterData();
+ EXPECT_TRUE(connection_->connected());
+
+ EXPECT_EQ(0u, stream->flow_controller()->bytes_consumed());
+ EXPECT_EQ(kByteOffset + frame.data_length,
+ stream->flow_controller()->highest_received_byte_offset());
+
+ // Reset stream locally.
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+ stream->Reset(QUIC_STREAM_CANCELLED);
+ EXPECT_EQ(kByteOffset + frame.data_length,
+ session_.flow_controller()->bytes_consumed());
+}
+
+TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAfterRst) {
+ // Test that when we RST the stream (and tear down stream state), and then
+ // receive a FIN from the peer, we correctly adjust our connection level flow
+ // control receive window.
+
+ // Connection starts with some non-zero highest received byte offset,
+ // due to other active streams.
+ const uint64_t kInitialConnectionBytesConsumed = 567;
+ const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
+ EXPECT_LT(kInitialConnectionBytesConsumed,
+ kInitialConnectionHighestReceivedOffset);
+ session_.flow_controller()->UpdateHighestReceivedOffset(
+ kInitialConnectionHighestReceivedOffset);
+ session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
+
+ // Reset our stream: this results in the stream being closed locally.
+ TestStream* stream = session_.CreateOutgoingDynamicStream();
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+ stream->Reset(QUIC_STREAM_CANCELLED);
+
+ // Now receive a response from the peer with a FIN. We should handle this by
+ // adjusting the connection level flow control receive window to take into
+ // account the total number of bytes sent by the peer.
+ const QuicStreamOffset kByteOffset = 5678;
+ QuicString body = "hello";
+ QuicStreamFrame frame(stream->id(), true, kByteOffset, QuicStringPiece(body));
+ session_.OnStreamFrame(frame);
+
+ QuicStreamOffset total_stream_bytes_sent_by_peer =
+ kByteOffset + body.length();
+ EXPECT_EQ(kInitialConnectionBytesConsumed + total_stream_bytes_sent_by_peer,
+ session_.flow_controller()->bytes_consumed());
+ EXPECT_EQ(
+ kInitialConnectionHighestReceivedOffset + total_stream_bytes_sent_by_peer,
+ session_.flow_controller()->highest_received_byte_offset());
+}
+
+TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstAfterRst) {
+ // Test that when we RST the stream (and tear down stream state), and then
+ // receive a RST from the peer, we correctly adjust our connection level flow
+ // control receive window.
+
+ // Connection starts with some non-zero highest received byte offset,
+ // due to other active streams.
+ const uint64_t kInitialConnectionBytesConsumed = 567;
+ const uint64_t kInitialConnectionHighestReceivedOffset = 1234;
+ EXPECT_LT(kInitialConnectionBytesConsumed,
+ kInitialConnectionHighestReceivedOffset);
+ session_.flow_controller()->UpdateHighestReceivedOffset(
+ kInitialConnectionHighestReceivedOffset);
+ session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed);
+
+ // Reset our stream: this results in the stream being closed locally.
+ TestStream* stream = session_.CreateOutgoingDynamicStream();
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+ stream->Reset(QUIC_STREAM_CANCELLED);
+ EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
+
+ // Now receive a RST from the peer. We should handle this by adjusting the
+ // connection level flow control receive window to take into account the total
+ // number of bytes sent by the peer.
+ const QuicStreamOffset kByteOffset = 5678;
+ QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
+ QUIC_STREAM_CANCELLED, kByteOffset);
+ session_.OnRstStream(rst_frame);
+
+ EXPECT_EQ(kInitialConnectionBytesConsumed + kByteOffset,
+ session_.flow_controller()->bytes_consumed());
+ EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset,
+ session_.flow_controller()->highest_received_byte_offset());
+}
+
+TEST_P(QuicSessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
+ // Test that receipt of an invalid (< default) stream flow control window from
+ // the peer results in the connection being torn down.
+ const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+ QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(),
+ kInvalidWindow);
+
+ EXPECT_CALL(*connection_,
+ CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
+ session_.OnConfigNegotiated();
+}
+
+TEST_P(QuicSessionTestServer, InvalidSessionFlowControlWindowInHandshake) {
+ // Test that receipt of an invalid (< default) session flow control window
+ // from the peer results in the connection being torn down.
+ const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+ QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(),
+ kInvalidWindow);
+
+ EXPECT_CALL(*connection_,
+ CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _));
+ session_.OnConfigNegotiated();
+}
+
+// Test negotiation of custom server initial flow control window.
+TEST_P(QuicSessionTestServer, CustomFlowControlWindow) {
+ QuicTagVector copt;
+ copt.push_back(kIFW7);
+ QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
+
+ session_.OnConfigNegotiated();
+ EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
+ session_.flow_controller()));
+}
+
+TEST_P(QuicSessionTestServer, FlowControlWithInvalidFinalOffset) {
+ // Test that if we receive a stream RST with a highest byte offset that
+ // violates flow control, that we close the connection.
+ const uint64_t kLargeOffset = kInitialSessionFlowControlWindowForTest + 1;
+ EXPECT_CALL(*connection_,
+ CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _))
+ .Times(2);
+
+ // Check that stream frame + FIN results in connection close.
+ TestStream* stream = session_.CreateOutgoingDynamicStream();
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+ stream->Reset(QUIC_STREAM_CANCELLED);
+ QuicStreamFrame frame(stream->id(), true, kLargeOffset, QuicStringPiece());
+ session_.OnStreamFrame(frame);
+
+ // Check that RST results in connection close.
+ QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
+ QUIC_STREAM_CANCELLED, kLargeOffset);
+ session_.OnRstStream(rst_frame);
+}
+
+TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseServerRejectStream) {
+ // If a buggy/malicious peer creates too many streams that are not ended
+ // with a FIN or RST then we send an RST to refuse streams.
+ const QuicStreamId kMaxStreams = 5;
+ QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
+ const QuicStreamId kFirstStreamId = GetNthClientInitiatedId(0);
+ const QuicStreamId kFinalStreamId = GetNthClientInitiatedId(kMaxStreams);
+ // Create kMaxStreams data streams, and close them all without receiving a
+ // FIN or a RST_STREAM from the client.
+ for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += 2) {
+ QuicStreamFrame data1(i, false, 0, QuicStringPiece("HT"));
+ session_.OnStreamFrame(data1);
+ // EXPECT_EQ(1u, session_.GetNumOpenStreams());
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+ EXPECT_CALL(*connection_, OnStreamReset(i, _));
+ session_.CloseStream(i);
+ }
+
+ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+ EXPECT_CALL(*connection_, OnStreamReset(kFinalStreamId, QUIC_REFUSED_STREAM))
+ .Times(1);
+ // Create one more data streams to exceed limit of open stream.
+ QuicStreamFrame data1(kFinalStreamId, false, 0, QuicStringPiece("HT"));
+ session_.OnStreamFrame(data1);
+
+ // Called after any new data is received by the session, and triggers the
+ // call to close the connection.
+ session_.PostProcessAfterData();
+}
+
+TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpened) {
+ // Verify that a draining stream (which has received a FIN but not consumed
+ // it) does not count against the open quota (because it is closed from the
+ // protocol point of view).
+ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+ EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM)).Times(0);
+ const QuicStreamId kMaxStreams = 5;
+ QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
+
+ // Create kMaxStreams + 1 data streams, and mark them draining.
+ const QuicStreamId kFirstStreamId = GetNthClientInitiatedId(0);
+ const QuicStreamId kFinalStreamId =
+ GetNthClientInitiatedId(2 * kMaxStreams + 1);
+ for (QuicStreamId i = kFirstStreamId; i < kFinalStreamId; i += 2) {
+ QuicStreamFrame data1(i, true, 0, QuicStringPiece("HT"));
+ session_.OnStreamFrame(data1);
+ EXPECT_EQ(1u, session_.GetNumOpenIncomingStreams());
+ session_.StreamDraining(i);
+ EXPECT_EQ(0u, session_.GetNumOpenIncomingStreams());
+ }
+
+ // Called after any new data is received by the session, and triggers the call
+ // to close the connection.
+ session_.PostProcessAfterData();
+}
+
+TEST_P(QuicSessionTestServer, TestMaxIncomingAndOutgoingStreamsAllowed) {
+ // Tests that on server side, the value of max_open_incoming/outgoing streams
+ // are setup correctly during negotiation.
+ // The value for outgoing stream is limited to negotiated value and for
+ // incoming stream it is set to be larger than that.
+ session_.OnConfigNegotiated();
+ // The max number of open outgoing streams is less than that of incoming
+ // streams, and it should be same as negotiated value.
+ EXPECT_LT(session_.max_open_outgoing_streams(),
+ session_.max_open_incoming_streams());
+ EXPECT_EQ(session_.max_open_outgoing_streams(),
+ kDefaultMaxStreamsPerConnection);
+ EXPECT_GT(session_.max_open_incoming_streams(),
+ kDefaultMaxStreamsPerConnection);
+}
+
+class QuicSessionTestClient : public QuicSessionTestBase {
+ protected:
+ QuicSessionTestClient() : QuicSessionTestBase(Perspective::IS_CLIENT) {}
+};
+
+INSTANTIATE_TEST_CASE_P(Tests,
+ QuicSessionTestClient,
+ ::testing::ValuesIn(AllSupportedVersions()));
+
+TEST_P(QuicSessionTestClient, AvailableStreamsClient) {
+ ASSERT_TRUE(session_.GetOrCreateDynamicStream(6) != nullptr);
+ // Both 2 and 4 should be available.
+ EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(&session_, 2));
+ EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(&session_, 4));
+ ASSERT_TRUE(session_.GetOrCreateDynamicStream(2) != nullptr);
+ ASSERT_TRUE(session_.GetOrCreateDynamicStream(4) != nullptr);
+ // And 5 should be not available.
+ EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(&session_, 5));
+}
+
+TEST_P(QuicSessionTestClient, RecordFinAfterReadSideClosed) {
+ // Verify that an incoming FIN is recorded in a stream object even if the read
+ // side has been closed. This prevents an entry from being made in
+ // locally_closed_streams_highest_offset_ (which will never be deleted).
+ TestStream* stream = session_.CreateOutgoingDynamicStream();
+ QuicStreamId stream_id = stream->id();
+
+ // Close the read side manually.
+ QuicStreamPeer::CloseReadSide(stream);
+
+ // Receive a stream data frame with FIN.
+ QuicStreamFrame frame(stream_id, true, 0, QuicStringPiece());
+ session_.OnStreamFrame(frame);
+ EXPECT_TRUE(stream->fin_received());
+
+ // Reset stream locally.
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
+ stream->Reset(QUIC_STREAM_CANCELLED);
+ EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
+
+ // Allow the session to delete the stream object.
+ session_.PostProcessAfterData();
+ EXPECT_TRUE(connection_->connected());
+ EXPECT_TRUE(QuicSessionPeer::IsStreamClosed(&session_, stream_id));
+ EXPECT_FALSE(QuicSessionPeer::IsStreamCreated(&session_, stream_id));
+
+ // The stream is not waiting for the arrival of the peer's final offset as it
+ // was received with the FIN earlier.
+ EXPECT_EQ(
+ 0u,
+ QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size());
+}
+
+TEST_P(QuicSessionTestClient, TestMaxIncomingAndOutgoingStreamsAllowed) {
+ // Tests that on client side, the value of max_open_incoming/outgoing streams
+ // are setup correctly during negotiation.
+ // When flag is true, the value for outgoing stream is limited to negotiated
+ // value and for incoming stream it is set to be larger than that.
+ session_.OnConfigNegotiated();
+ EXPECT_LT(session_.max_open_outgoing_streams(),
+ session_.max_open_incoming_streams());
+ EXPECT_EQ(session_.max_open_outgoing_streams(),
+ kDefaultMaxStreamsPerConnection);
+}
+
+TEST_P(QuicSessionTestServer, ZombieStreams) {
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ QuicStreamPeer::SetStreamBytesWritten(3, stream2);
+ EXPECT_TRUE(stream2->IsWaitingForAcks());
+
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(2, _));
+ session_.CloseStream(2);
+ if (GetQuicReloadableFlag(quic_reset_stream_is_not_zombie)) {
+ EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), 2));
+ ASSERT_EQ(1u, session_.closed_streams()->size());
+ EXPECT_EQ(2u, session_.closed_streams()->front()->id());
+ } else {
+ EXPECT_TRUE(QuicContainsKey(session_.zombie_streams(), 2));
+ EXPECT_TRUE(session_.closed_streams()->empty());
+ }
+ session_.OnStreamDoneWaitingForAcks(2);
+ EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), 2));
+ EXPECT_EQ(1u, session_.closed_streams()->size());
+ EXPECT_EQ(2u, session_.closed_streams()->front()->id());
+}
+
+// Regression test of b/71548958.
+TEST_P(QuicSessionTestServer, TestZombieStreams) {
+ session_.set_writev_consumes_all_data(true);
+
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ QuicString body(100, '.');
+ stream2->WriteOrBufferData(body, false, nullptr);
+ EXPECT_TRUE(stream2->IsWaitingForAcks());
+ EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream2).size());
+
+ QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream2->id(),
+ QUIC_STREAM_CANCELLED, 1234);
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(stream2->id(), QUIC_RST_ACKNOWLEDGEMENT));
+ stream2->OnStreamReset(rst_frame);
+ if (GetQuicReloadableFlag(quic_reset_stream_is_not_zombie)) {
+ EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream2->id()));
+ ASSERT_EQ(1u, session_.closed_streams()->size());
+ EXPECT_EQ(stream2->id(), session_.closed_streams()->front()->id());
+ } else {
+ // Stream reset by peer, and it becomes zombie stream and the data will be
+ // NEVER be acked because the frames in unacked packet map are removed.
+ EXPECT_TRUE(QuicContainsKey(session_.zombie_streams(), stream2->id()));
+ EXPECT_TRUE(session_.closed_streams()->empty());
+ EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream2).size());
+ }
+
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream();
+ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+ EXPECT_CALL(*connection_,
+ OnStreamReset(stream4->id(), QUIC_STREAM_CANCELLED));
+ stream4->WriteOrBufferData(body, false, nullptr);
+ stream4->Reset(QUIC_STREAM_CANCELLED);
+ EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), stream4->id()));
+ if (GetQuicReloadableFlag(quic_reset_stream_is_not_zombie)) {
+ EXPECT_EQ(2u, session_.closed_streams()->size());
+ } else {
+ EXPECT_EQ(1u, session_.closed_streams()->size());
+ }
+}
+
+TEST_P(QuicSessionTestServer, OnStreamFrameLost) {
+ QuicConnectionPeer::SetSessionDecidesWhatToWrite(connection_);
+ InSequence s;
+
+ // Drive congestion control manually.
+ MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+ QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+
+ TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream();
+
+ QuicStreamFrame frame1(kCryptoStreamId, false, 0, 1300);
+ QuicStreamFrame frame2(stream2->id(), false, 0, 9);
+ QuicStreamFrame frame3(stream4->id(), false, 0, 9);
+
+ // Lost data on cryption stream, streams 2 and 4.
+ EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
+ EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+ .WillOnce(Return(true));
+ EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
+ session_.OnFrameLost(QuicFrame(&frame3));
+ session_.OnFrameLost(QuicFrame(&frame1));
+ session_.OnFrameLost(QuicFrame(&frame2));
+ EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+ // Mark streams 2 and 4 write blocked.
+ session_.MarkConnectionLevelWriteBlocked(stream2->id());
+ session_.MarkConnectionLevelWriteBlocked(stream4->id());
+
+ // Lost data is retransmitted before new data, and retransmissions for crypto
+ // stream go first.
+ // Do not check congestion window when crypto stream has lost data.
+ EXPECT_CALL(*send_algorithm, CanSend(_)).Times(0);
+ EXPECT_CALL(*crypto_stream, OnCanWrite());
+ EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
+ .WillOnce(Return(false));
+ // Check congestion window for non crypto streams.
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+ EXPECT_CALL(*stream4, OnCanWrite());
+ EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(false));
+ // Connection is blocked.
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillRepeatedly(Return(false));
+
+ session_.OnCanWrite();
+ EXPECT_TRUE(session_.WillingAndAbleToWrite());
+
+ // Unblock connection.
+ // Stream 2 retransmits lost data.
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+ EXPECT_CALL(*stream2, OnCanWrite());
+ EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+ // Stream 2 sends new data.
+ EXPECT_CALL(*stream2, OnCanWrite());
+ EXPECT_CALL(*send_algorithm, CanSend(_)).WillOnce(Return(true));
+ EXPECT_CALL(*stream4, OnCanWrite());
+ EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+
+ session_.OnCanWrite();
+ EXPECT_FALSE(session_.WillingAndAbleToWrite());
+}
+
+TEST_P(QuicSessionTestServer, DonotRetransmitDataOfClosedStreams) {
+ QuicConnectionPeer::SetSessionDecidesWhatToWrite(connection_);
+ InSequence s;
+
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream6 = session_.CreateOutgoingDynamicStream();
+
+ QuicStreamFrame frame1(stream2->id(), false, 0, 9);
+ QuicStreamFrame frame2(stream4->id(), false, 0, 9);
+ QuicStreamFrame frame3(stream6->id(), false, 0, 9);
+
+ EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(true));
+ EXPECT_CALL(*stream4, HasPendingRetransmission()).WillOnce(Return(true));
+ EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(true));
+ session_.OnFrameLost(QuicFrame(&frame3));
+ session_.OnFrameLost(QuicFrame(&frame2));
+ session_.OnFrameLost(QuicFrame(&frame1));
+
+ session_.MarkConnectionLevelWriteBlocked(stream2->id());
+ session_.MarkConnectionLevelWriteBlocked(stream4->id());
+ session_.MarkConnectionLevelWriteBlocked(stream6->id());
+
+ // Reset stream 4 locally.
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(stream4->id(), _));
+ stream4->Reset(QUIC_STREAM_CANCELLED);
+
+ // Verify stream 4 is removed from streams with lost data list.
+ EXPECT_CALL(*stream6, OnCanWrite());
+ EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(false));
+ EXPECT_CALL(*stream2, OnCanWrite());
+ EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
+ EXPECT_CALL(*stream2, OnCanWrite());
+ EXPECT_CALL(*stream6, OnCanWrite());
+ session_.OnCanWrite();
+}
+
+TEST_P(QuicSessionTestServer, RetransmitFrames) {
+ QuicConnectionPeer::SetSessionDecidesWhatToWrite(connection_);
+ MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
+ QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
+ InSequence s;
+
+ TestStream* stream2 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream4 = session_.CreateOutgoingDynamicStream();
+ TestStream* stream6 = session_.CreateOutgoingDynamicStream();
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+ session_.SendWindowUpdate(stream2->id(), 9);
+
+ QuicStreamFrame frame1(stream2->id(), false, 0, 9);
+ QuicStreamFrame frame2(stream4->id(), false, 0, 9);
+ QuicStreamFrame frame3(stream6->id(), false, 0, 9);
+ QuicWindowUpdateFrame window_update(1, stream2->id(), 9);
+ QuicFrames frames;
+ frames.push_back(QuicFrame(&frame1));
+ frames.push_back(QuicFrame(&window_update));
+ frames.push_back(QuicFrame(&frame2));
+ frames.push_back(QuicFrame(&frame3));
+ EXPECT_FALSE(session_.WillingAndAbleToWrite());
+
+ EXPECT_CALL(*stream2, RetransmitStreamData(_, _, _)).WillOnce(Return(true));
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+ EXPECT_CALL(*stream4, RetransmitStreamData(_, _, _)).WillOnce(Return(true));
+ EXPECT_CALL(*stream6, RetransmitStreamData(_, _, _)).WillOnce(Return(true));
+ EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
+ session_.RetransmitFrames(frames, TLP_RETRANSMISSION);
+}
+
+} // namespace
+} // namespace test
+} // namespace net
diff --git a/chromium/net/quic/core/quic_spdy_session.cc b/chromium/net/quic/core/quic_spdy_session.cc
index a64af281494..f05447305e3 100644
--- a/chromium/net/quic/core/quic_spdy_session.cc
+++ b/chromium/net/quic/core/quic_spdy_session.cc
@@ -119,7 +119,50 @@ class QuicSpdySession::SpdyFramerVisitor
QUIC_INVALID_HEADERS_STREAM_DATA);
}
- void OnSetting(SpdyKnownSettingsId id, uint32_t value) override {
+ void OnSettingOld(SpdyKnownSettingsId id, uint32_t value) override {
+ QUIC_BUG_IF(GetQuicRestartFlag(http2_propagate_unknown_settings));
+ if (!GetQuicReloadableFlag(quic_respect_http2_settings_frame)) {
+ CloseConnection("SPDY SETTINGS frame received.",
+ QUIC_INVALID_HEADERS_STREAM_DATA);
+ return;
+ }
+ switch (id) {
+ case SETTINGS_HEADER_TABLE_SIZE:
+ session_->UpdateHeaderEncoderTableSize(value);
+ break;
+ case SETTINGS_ENABLE_PUSH:
+ if (session_->perspective() == Perspective::IS_SERVER) {
+ // See rfc7540, Section 6.5.2.
+ if (value > 1) {
+ CloseConnection(
+ QuicStrCat("Invalid value for SETTINGS_ENABLE_PUSH: ", value),
+ QUIC_INVALID_HEADERS_STREAM_DATA);
+ return;
+ }
+ session_->UpdateEnableServerPush(value > 0);
+ break;
+ } else {
+ CloseConnection(
+ QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id),
+ QUIC_INVALID_HEADERS_STREAM_DATA);
+ }
+ break;
+ // TODO(fayang): Need to support SETTINGS_MAX_HEADER_LIST_SIZE when
+ // clients are actually sending it.
+ case SETTINGS_MAX_HEADER_LIST_SIZE:
+ if (GetQuicReloadableFlag(quic_send_max_header_list_size)) {
+ break;
+ }
+ QUIC_FALLTHROUGH_INTENDED;
+ default:
+ CloseConnection(
+ QuicStrCat("Unsupported field of HTTP/2 SETTINGS frame: ", id),
+ QUIC_INVALID_HEADERS_STREAM_DATA);
+ }
+ }
+
+ void OnSetting(SpdySettingsId id, uint32_t value) override {
+ QUIC_BUG_IF(!GetQuicRestartFlag(http2_propagate_unknown_settings));
if (!GetQuicReloadableFlag(quic_respect_http2_settings_frame)) {
CloseConnection("SPDY SETTINGS frame received.",
QUIC_INVALID_HEADERS_STREAM_DATA);
@@ -490,20 +533,6 @@ void QuicSpdySession::OnHeadersHeadOfLineBlocking(QuicTime::Delta delta) {
// Implemented in Chromium for stats tracking.
}
-void QuicSpdySession::RegisterStreamPriority(QuicStreamId id,
- SpdyPriority priority) {
- write_blocked_streams()->RegisterStream(id, priority);
-}
-
-void QuicSpdySession::UnregisterStreamPriority(QuicStreamId id) {
- write_blocked_streams()->UnregisterStream(id);
-}
-
-void QuicSpdySession::UpdateStreamPriority(QuicStreamId id,
- SpdyPriority new_priority) {
- write_blocked_streams()->UpdateStreamPriority(id, new_priority);
-}
-
QuicSpdyStream* QuicSpdySession::GetSpdyDataStream(
const QuicStreamId stream_id) {
return static_cast<QuicSpdyStream*>(GetOrCreateDynamicStream(stream_id));
diff --git a/chromium/net/quic/core/quic_spdy_session.h b/chromium/net/quic/core/quic_spdy_session.h
index 7268cc2ba70..fd9600a20bc 100644
--- a/chromium/net/quic/core/quic_spdy_session.h
+++ b/chromium/net/quic/core/quic_spdy_session.h
@@ -120,15 +120,6 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession : public QuicSession {
// |delta| indicates how long that piece of data has been blocked.
virtual void OnHeadersHeadOfLineBlocking(QuicTime::Delta delta);
- // Called by the stream on creation to set priority in the write blocked list.
- virtual void RegisterStreamPriority(QuicStreamId id, SpdyPriority priority);
- // Called by the stream on deletion to clear priority crom the write blocked
- // list.
- virtual void UnregisterStreamPriority(QuicStreamId id);
- // Called by the stream on SetPriority to update priority on the write blocked
- // list.
- virtual void UpdateStreamPriority(QuicStreamId id, SpdyPriority new_priority);
-
void OnConfigNegotiated() override;
bool server_push_enabled() const { return server_push_enabled_; }
diff --git a/chromium/net/quic/core/quic_spdy_session_test.cc b/chromium/net/quic/core/quic_spdy_session_test.cc
index 8267f8060ab..77b1753ceca 100644
--- a/chromium/net/quic/core/quic_spdy_session_test.cc
+++ b/chromium/net/quic/core/quic_spdy_session_test.cc
@@ -135,7 +135,7 @@ class TestSession : public QuicSpdySession {
Initialize();
this->connection()->SetEncrypter(
ENCRYPTION_FORWARD_SECURE,
- new NullEncrypter(connection->perspective()));
+ QuicMakeUnique<NullEncrypter>(connection->perspective()));
}
~TestSession() override { delete connection(); }
@@ -239,9 +239,9 @@ class TestSession : public QuicSpdySession {
bool writev_consumes_all_data_;
};
-class QuicSessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
+class QuicSpdySessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
protected:
- explicit QuicSessionTestBase(Perspective perspective)
+ explicit QuicSpdySessionTestBase(Perspective perspective)
: connection_(
new StrictMock<MockQuicConnection>(&helper_,
&alarm_factory_,
@@ -296,13 +296,9 @@ class QuicSessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
}
void CloseStream(QuicStreamId id) {
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(id, _));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(id, _, _));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+ EXPECT_CALL(*connection_, OnStreamReset(id, _));
session_.CloseStream(id);
closed_streams_.insert(id);
}
@@ -329,39 +325,40 @@ class QuicSessionTestBase : public QuicTestWithParam<ParsedQuicVersion> {
SpdyHeaderBlock headers_;
};
-class QuicSessionTestServer : public QuicSessionTestBase {
+class QuicSpdySessionTestServer : public QuicSpdySessionTestBase {
protected:
- QuicSessionTestServer() : QuicSessionTestBase(Perspective::IS_SERVER) {}
+ QuicSpdySessionTestServer()
+ : QuicSpdySessionTestBase(Perspective::IS_SERVER) {}
};
INSTANTIATE_TEST_CASE_P(Tests,
- QuicSessionTestServer,
+ QuicSpdySessionTestServer,
::testing::ValuesIn(AllSupportedVersions()));
-TEST_P(QuicSessionTestServer, PeerAddress) {
+TEST_P(QuicSpdySessionTestServer, PeerAddress) {
EXPECT_EQ(QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort),
session_.peer_address());
}
-TEST_P(QuicSessionTestServer, SelfAddress) {
+TEST_P(QuicSpdySessionTestServer, SelfAddress) {
EXPECT_EQ(QuicSocketAddress(), session_.self_address());
}
-TEST_P(QuicSessionTestServer, IsCryptoHandshakeConfirmed) {
+TEST_P(QuicSpdySessionTestServer, IsCryptoHandshakeConfirmed) {
EXPECT_FALSE(session_.IsCryptoHandshakeConfirmed());
CryptoHandshakeMessage message;
session_.GetMutableCryptoStream()->OnHandshakeMessage(message);
EXPECT_TRUE(session_.IsCryptoHandshakeConfirmed());
}
-TEST_P(QuicSessionTestServer, IsClosedStreamDefault) {
+TEST_P(QuicSpdySessionTestServer, IsClosedStreamDefault) {
// Ensure that no streams are initially closed.
for (QuicStreamId i = kCryptoStreamId; i < 100; i++) {
EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i;
}
}
-TEST_P(QuicSessionTestServer, AvailableStreams) {
+TEST_P(QuicSpdySessionTestServer, AvailableStreams) {
ASSERT_TRUE(session_.GetOrCreateDynamicStream(9) != nullptr);
// Both 5 and 7 should be available.
EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(&session_, 5));
@@ -370,7 +367,7 @@ TEST_P(QuicSessionTestServer, AvailableStreams) {
ASSERT_TRUE(session_.GetOrCreateDynamicStream(5) != nullptr);
}
-TEST_P(QuicSessionTestServer, IsClosedStreamLocallyCreated) {
+TEST_P(QuicSpdySessionTestServer, IsClosedStreamLocallyCreated) {
TestStream* stream2 = session_.CreateOutgoingDynamicStream();
EXPECT_EQ(GetNthServerInitiatedId(0), stream2->id());
QuicSpdyStream* stream4 = session_.CreateOutgoingDynamicStream();
@@ -383,7 +380,7 @@ TEST_P(QuicSessionTestServer, IsClosedStreamLocallyCreated) {
CheckClosedStreams();
}
-TEST_P(QuicSessionTestServer, IsClosedStreamPeerCreated) {
+TEST_P(QuicSpdySessionTestServer, IsClosedStreamPeerCreated) {
QuicStreamId stream_id1 = GetNthClientInitiatedId(0);
QuicStreamId stream_id2 = GetNthClientInitiatedId(1);
session_.GetOrCreateDynamicStream(stream_id1);
@@ -401,7 +398,7 @@ TEST_P(QuicSessionTestServer, IsClosedStreamPeerCreated) {
CheckClosedStreams();
}
-TEST_P(QuicSessionTestServer, MaximumAvailableOpenedStreams) {
+TEST_P(QuicSpdySessionTestServer, MaximumAvailableOpenedStreams) {
QuicStreamId stream_id = GetNthClientInitiatedId(0);
session_.GetOrCreateDynamicStream(stream_id);
EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
@@ -410,7 +407,7 @@ TEST_P(QuicSessionTestServer, MaximumAvailableOpenedStreams) {
stream_id + 2 * (session_.max_open_incoming_streams() - 1)));
}
-TEST_P(QuicSessionTestServer, TooManyAvailableStreams) {
+TEST_P(QuicSpdySessionTestServer, TooManyAvailableStreams) {
QuicStreamId stream_id1 = GetNthClientInitiatedId(0);
QuicStreamId stream_id2;
EXPECT_NE(nullptr, session_.GetOrCreateDynamicStream(stream_id1));
@@ -421,7 +418,7 @@ TEST_P(QuicSessionTestServer, TooManyAvailableStreams) {
EXPECT_EQ(nullptr, session_.GetOrCreateDynamicStream(stream_id2));
}
-TEST_P(QuicSessionTestServer, ManyAvailableStreams) {
+TEST_P(QuicSpdySessionTestServer, ManyAvailableStreams) {
// When max_open_streams_ is 200, should be able to create 200 streams
// out-of-order, that is, creating the one with the largest stream ID first.
QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, 200);
@@ -433,16 +430,13 @@ TEST_P(QuicSessionTestServer, ManyAvailableStreams) {
session_.GetOrCreateDynamicStream(stream_id + 2 * (200 - 1));
}
-TEST_P(QuicSessionTestServer, DebugDFatalIfMarkingClosedStreamWriteBlocked) {
+TEST_P(QuicSpdySessionTestServer,
+ DebugDFatalIfMarkingClosedStreamWriteBlocked) {
TestStream* stream2 = session_.CreateOutgoingDynamicStream();
QuicStreamId closed_stream_id = stream2->id();
// Close the stream.
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(closed_stream_id, _));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(closed_stream_id, _, _));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(closed_stream_id, _));
stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
QuicString msg =
QuicStrCat("Marking unknown stream ", closed_stream_id, " blocked.");
@@ -450,7 +444,7 @@ TEST_P(QuicSessionTestServer, DebugDFatalIfMarkingClosedStreamWriteBlocked) {
msg);
}
-TEST_P(QuicSessionTestServer, OnCanWrite) {
+TEST_P(QuicSpdySessionTestServer, OnCanWrite) {
session_.set_writev_consumes_all_data(true);
TestStream* stream2 = session_.CreateOutgoingDynamicStream();
TestStream* stream4 = session_.CreateOutgoingDynamicStream();
@@ -479,7 +473,7 @@ TEST_P(QuicSessionTestServer, OnCanWrite) {
EXPECT_TRUE(session_.WillingAndAbleToWrite());
}
-TEST_P(QuicSessionTestServer, TestBatchedWrites) {
+TEST_P(QuicSpdySessionTestServer, TestBatchedWrites) {
session_.set_writev_consumes_all_data(true);
TestStream* stream2 = session_.CreateOutgoingDynamicStream();
TestStream* stream4 = session_.CreateOutgoingDynamicStream();
@@ -545,7 +539,7 @@ TEST_P(QuicSessionTestServer, TestBatchedWrites) {
session_.OnCanWrite();
}
-TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
+TEST_P(QuicSpdySessionTestServer, OnCanWriteBundlesStreams) {
// Encryption needs to be established before data can be sent.
CryptoHandshakeMessage msg;
MockPacketWriter* writer = static_cast<MockPacketWriter*>(
@@ -592,7 +586,7 @@ TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) {
EXPECT_FALSE(session_.WillingAndAbleToWrite());
}
-TEST_P(QuicSessionTestServer, OnCanWriteCongestionControlBlocks) {
+TEST_P(QuicSpdySessionTestServer, OnCanWriteCongestionControlBlocks) {
session_.set_writev_consumes_all_data(true);
InSequence s;
@@ -638,7 +632,7 @@ TEST_P(QuicSessionTestServer, OnCanWriteCongestionControlBlocks) {
EXPECT_FALSE(session_.WillingAndAbleToWrite());
}
-TEST_P(QuicSessionTestServer, OnCanWriteWriterBlocks) {
+TEST_P(QuicSpdySessionTestServer, OnCanWriteWriterBlocks) {
// Drive congestion control manually in order to ensure that
// application-limited signaling is handled correctly.
MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
@@ -664,7 +658,7 @@ TEST_P(QuicSessionTestServer, OnCanWriteWriterBlocks) {
EXPECT_TRUE(session_.WillingAndAbleToWrite());
}
-TEST_P(QuicSessionTestServer, BufferedHandshake) {
+TEST_P(QuicSpdySessionTestServer, BufferedHandshake) {
session_.set_writev_consumes_all_data(true);
EXPECT_FALSE(session_.HasPendingHandshake()); // Default value.
@@ -711,7 +705,7 @@ TEST_P(QuicSessionTestServer, BufferedHandshake) {
EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote.
}
-TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) {
+TEST_P(QuicSpdySessionTestServer, OnCanWriteWithClosedStream) {
session_.set_writev_consumes_all_data(true);
TestStream* stream2 = session_.CreateOutgoingDynamicStream();
TestStream* stream4 = session_.CreateOutgoingDynamicStream();
@@ -723,10 +717,8 @@ TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) {
CloseStream(stream6->id());
InSequence s;
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
EXPECT_CALL(*stream2, OnCanWrite()).WillOnce(Invoke([this, stream2]() {
session_.SendStreamData(stream2);
}));
@@ -737,7 +729,8 @@ TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) {
EXPECT_FALSE(session_.WillingAndAbleToWrite());
}
-TEST_P(QuicSessionTestServer, OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
+TEST_P(QuicSpdySessionTestServer,
+ OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
// Drive congestion control manually in order to ensure that
// application-limited signaling is handled correctly.
MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
@@ -753,7 +746,6 @@ TEST_P(QuicSessionTestServer, OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
// Mark the crypto and headers streams as write blocked, we expect them to be
// allowed to write later.
session_.MarkConnectionLevelWriteBlocked(kCryptoStreamId);
- session_.MarkConnectionLevelWriteBlocked(kHeadersStreamId);
// Create a data stream, and although it is write blocked we never expect it
// to be allowed to write as we are connection level flow control blocked.
@@ -765,8 +757,10 @@ TEST_P(QuicSessionTestServer, OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
// connection flow control blocked.
TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream();
EXPECT_CALL(*crypto_stream, OnCanWrite());
+ QuicSpdySessionPeer::SetHeadersStream(&session_, nullptr);
TestHeadersStream* headers_stream = new TestHeadersStream(&session_);
QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream);
+ session_.MarkConnectionLevelWriteBlocked(kHeadersStreamId);
EXPECT_CALL(*headers_stream, OnCanWrite());
// After the crypto and header streams perform a write, the connection will be
@@ -777,52 +771,35 @@ TEST_P(QuicSessionTestServer, OnCanWriteLimitsNumWritesIfFlowControlBlocked) {
EXPECT_FALSE(session_.WillingAndAbleToWrite());
}
-TEST_P(QuicSessionTestServer, SendGoAway) {
+TEST_P(QuicSpdySessionTestServer, SendGoAway) {
MockPacketWriter* writer = static_cast<MockPacketWriter*>(
QuicConnectionPeer::GetWriter(session_.connection()));
EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(
- Invoke(connection_, &MockQuicConnection::ReallySendControlFrame));
- } else {
- EXPECT_CALL(*connection_, SendGoAway(_, _, _))
- .WillOnce(Invoke(connection_, &MockQuicConnection::ReallySendGoAway));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(
+ Invoke(connection_, &MockQuicConnection::ReallySendControlFrame));
session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
EXPECT_TRUE(session_.goaway_sent());
const QuicStreamId kTestStreamId = 5u;
- if (session_.use_control_frame_manager()) {
EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
EXPECT_CALL(*connection_,
OnStreamReset(kTestStreamId, QUIC_STREAM_PEER_GOING_AWAY))
.Times(0);
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(kTestStreamId, QUIC_STREAM_PEER_GOING_AWAY, 0))
- .Times(0);
- }
EXPECT_TRUE(session_.GetOrCreateDynamicStream(kTestStreamId));
}
-TEST_P(QuicSessionTestServer, DoNotSendGoAwayTwice) {
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
- } else {
- EXPECT_CALL(*connection_, SendGoAway(QUIC_PEER_GOING_AWAY, kHeadersStreamId,
- "Going Away."))
- .Times(1);
- }
+TEST_P(QuicSpdySessionTestServer, DoNotSendGoAwayTwice) {
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
EXPECT_TRUE(session_.goaway_sent());
session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away.");
}
-TEST_P(QuicSessionTestServer, InvalidGoAway) {
+TEST_P(QuicSpdySessionTestServer, InvalidGoAway) {
QuicGoAwayFrame go_away(kInvalidControlFrameId, QUIC_PEER_GOING_AWAY,
session_.next_outgoing_stream_id(), "");
session_.OnGoAway(go_away);
@@ -830,7 +807,7 @@ TEST_P(QuicSessionTestServer, InvalidGoAway) {
// Test that server session will send a connectivity probe in response to a
// connectivity probe on the same path.
-TEST_P(QuicSessionTestServer, ServerReplyToConnecitivityProbe) {
+TEST_P(QuicSpdySessionTestServer, ServerReplyToConnecitivityProbe) {
QuicSocketAddress old_peer_address =
QuicSocketAddress(QuicIpAddress::Loopback4(), kTestPort);
EXPECT_EQ(old_peer_address, session_.peer_address());
@@ -852,7 +829,7 @@ TEST_P(QuicSessionTestServer, ServerReplyToConnecitivityProbe) {
EXPECT_EQ(old_peer_address, session_.peer_address());
}
-TEST_P(QuicSessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
+TEST_P(QuicSpdySessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
EXPECT_EQ(kInitialIdleTimeoutSecs + 3,
QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
CryptoHandshakeMessage msg;
@@ -861,19 +838,15 @@ TEST_P(QuicSessionTestServer, IncreasedTimeoutAfterCryptoHandshake) {
QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
}
-TEST_P(QuicSessionTestServer, RstStreamBeforeHeadersDecompressed) {
+TEST_P(QuicSpdySessionTestServer, RstStreamBeforeHeadersDecompressed) {
// Send two bytes of payload.
QuicStreamFrame data1(GetNthClientInitiatedId(0), false, 0,
QuicStringPiece("HT"));
session_.OnStreamFrame(data1);
EXPECT_EQ(1u, session_.GetNumOpenIncomingStreams());
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0), _));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(GetNthClientInitiatedId(0), _, _));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0), _));
QuicRstStreamFrame rst1(kInvalidControlFrameId, GetNthClientInitiatedId(0),
QUIC_ERROR_PROCESSING_STREAM, 0);
session_.OnRstStream(rst1);
@@ -882,7 +855,7 @@ TEST_P(QuicSessionTestServer, RstStreamBeforeHeadersDecompressed) {
EXPECT_TRUE(connection_->connected());
}
-TEST_P(QuicSessionTestServer, OnStreamFrameFinStaticStreamId) {
+TEST_P(QuicSpdySessionTestServer, OnStreamFrameFinStaticStreamId) {
// Send two bytes of payload.
QuicStreamFrame data1(kCryptoStreamId, true, 0, QuicStringPiece("HT"));
EXPECT_CALL(*connection_,
@@ -892,7 +865,7 @@ TEST_P(QuicSessionTestServer, OnStreamFrameFinStaticStreamId) {
session_.OnStreamFrame(data1);
}
-TEST_P(QuicSessionTestServer, OnRstStreamStaticStreamId) {
+TEST_P(QuicSpdySessionTestServer, OnRstStreamStaticStreamId) {
// Send two bytes of payload.
QuicRstStreamFrame rst1(kInvalidControlFrameId, kCryptoStreamId,
QUIC_ERROR_PROCESSING_STREAM, 0);
@@ -903,7 +876,7 @@ TEST_P(QuicSessionTestServer, OnRstStreamStaticStreamId) {
session_.OnRstStream(rst1);
}
-TEST_P(QuicSessionTestServer, OnStreamFrameInvalidStreamId) {
+TEST_P(QuicSpdySessionTestServer, OnStreamFrameInvalidStreamId) {
// Send two bytes of payload.
QuicStreamFrame data1(kInvalidStreamId, true, 0, QuicStringPiece("HT"));
EXPECT_CALL(*connection_,
@@ -913,7 +886,7 @@ TEST_P(QuicSessionTestServer, OnStreamFrameInvalidStreamId) {
session_.OnStreamFrame(data1);
}
-TEST_P(QuicSessionTestServer, OnRstStreamInvalidStreamId) {
+TEST_P(QuicSpdySessionTestServer, OnRstStreamInvalidStreamId) {
// Send two bytes of payload.
QuicRstStreamFrame rst1(kInvalidControlFrameId, kInvalidStreamId,
QUIC_ERROR_PROCESSING_STREAM, 0);
@@ -924,7 +897,7 @@ TEST_P(QuicSessionTestServer, OnRstStreamInvalidStreamId) {
session_.OnRstStream(rst1);
}
-TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
+TEST_P(QuicSpdySessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
// Test that if a stream is flow control blocked, then on receipt of the SHLO
// containing a suitable send window offset, the stream becomes unblocked.
@@ -938,40 +911,25 @@ TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedStream) {
EXPECT_FALSE(stream2->flow_controller()->IsBlocked());
EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1));
- } else {
- EXPECT_CALL(*connection_, SendBlocked(_)).Times(AtLeast(1));
- EXPECT_CALL(*connection_, SendBlocked(0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1));
stream2->WriteOrBufferBody(body, false, nullptr);
EXPECT_TRUE(stream2->flow_controller()->IsBlocked());
EXPECT_TRUE(session_.IsConnectionFlowControlBlocked());
EXPECT_TRUE(session_.IsStreamFlowControlBlocked());
- if (!session_.session_unblocks_stream()) {
- // The handshake message will call OnCanWrite, so the stream can resume
- // writing.
- EXPECT_CALL(*stream2, OnCanWrite());
- }
// Now complete the crypto handshake, resulting in an increased flow control
// send window.
CryptoHandshakeMessage msg;
session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
- if (session_.session_unblocks_stream()) {
- EXPECT_TRUE(
- QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id()));
- } else {
- EXPECT_FALSE(
- QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id()));
- }
+ EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id()));
// Stream is now unblocked.
EXPECT_FALSE(stream2->flow_controller()->IsBlocked());
EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
}
-TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedCryptoStream) {
+TEST_P(QuicSpdySessionTestServer,
+ HandshakeUnblocksFlowControlBlockedCryptoStream) {
// Test that if the crypto stream is flow control blocked, then if the SHLO
// contains a larger send window offset, the stream becomes unblocked.
session_.set_writev_consumes_all_data(true);
@@ -984,13 +942,8 @@ TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedCryptoStream) {
EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked());
EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
- } else {
- // Write until the crypto stream is flow control blocked.
- EXPECT_CALL(*connection_, SendBlocked(kCryptoStreamId));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
for (QuicStreamId i = 0;
!crypto_stream->flow_controller()->IsBlocked() && i < 1000u; i++) {
EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
@@ -1011,22 +964,12 @@ TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedCryptoStream) {
EXPECT_FALSE(session_.HasDataToWrite());
EXPECT_TRUE(crypto_stream->HasBufferedData());
- if (!session_.session_unblocks_stream()) {
- // The handshake message will call OnCanWrite, so the stream can
- // resume writing.
- EXPECT_CALL(*crypto_stream, OnCanWrite());
- }
// Now complete the crypto handshake, resulting in an increased flow control
// send window.
CryptoHandshakeMessage msg;
session_.GetMutableCryptoStream()->OnHandshakeMessage(msg);
- if (session_.session_unblocks_stream()) {
- EXPECT_TRUE(
- QuicSessionPeer::IsStreamWriteBlocked(&session_, kCryptoStreamId));
- } else {
- EXPECT_FALSE(
- QuicSessionPeer::IsStreamWriteBlocked(&session_, kCryptoStreamId));
- }
+ EXPECT_TRUE(
+ QuicSessionPeer::IsStreamWriteBlocked(&session_, kCryptoStreamId));
// Stream is now unblocked and will no longer have buffered data.
EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked());
EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
@@ -1039,7 +982,7 @@ TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedCryptoStream) {
// NOTE: It's not possible to use the standard MAYBE_ convention to disable
// this test on iOS because when this test gets instantiated it ends up with
// various names that are dependent on the parameters passed.
-TEST_P(QuicSessionTestServer,
+TEST_P(QuicSpdySessionTestServer,
HandshakeUnblocksFlowControlBlockedHeadersStream) {
// Test that if the header stream is flow control blocked, then if the SHLO
// contains a larger send window offset, the stream becomes unblocked.
@@ -1055,12 +998,8 @@ TEST_P(QuicSessionTestServer,
EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
QuicStreamId stream_id = 5;
// Write until the header stream is flow control blocked.
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
- } else {
- EXPECT_CALL(*connection_, SendBlocked(kHeadersStreamId));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
SpdyHeaderBlock headers;
while (!headers_stream->flow_controller()->IsBlocked() && stream_id < 2000) {
EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
@@ -1090,19 +1029,14 @@ TEST_P(QuicSessionTestServer,
EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked());
EXPECT_FALSE(session_.IsConnectionFlowControlBlocked());
EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
- if (session_.session_unblocks_stream()) {
- EXPECT_TRUE(headers_stream->HasBufferedData());
- EXPECT_TRUE(
- QuicSessionPeer::IsStreamWriteBlocked(&session_, kHeadersStreamId));
- } else {
- EXPECT_FALSE(headers_stream->HasBufferedData());
- EXPECT_FALSE(
- QuicSessionPeer::IsStreamWriteBlocked(&session_, kHeadersStreamId));
- }
+ EXPECT_TRUE(headers_stream->HasBufferedData());
+ EXPECT_TRUE(
+ QuicSessionPeer::IsStreamWriteBlocked(&session_, kHeadersStreamId));
}
#endif // !defined(OS_IOS)
-TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstOutOfOrder) {
+TEST_P(QuicSpdySessionTestServer,
+ ConnectionFlowControlAccountingRstOutOfOrder) {
// Test that when we receive an out of order stream RST we correctly adjust
// our connection level flow control receive window.
// On close, the stream should mark as consumed all bytes between the highest
@@ -1112,21 +1046,10 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstOutOfOrder) {
const QuicStreamOffset kByteOffset =
1 + kInitialSessionFlowControlWindowForTest / 2;
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(2)
- .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
- } else {
- // Expect no stream WINDOW_UPDATE frames, as stream read side closed.
- EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0);
- // We do expect a connection level WINDOW_UPDATE when the stream is reset.
- EXPECT_CALL(*connection_,
- SendWindowUpdate(
- 0, kInitialSessionFlowControlWindowForTest + kByteOffset));
-
- EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .Times(2)
+ .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
+ EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
QUIC_STREAM_CANCELLED, kByteOffset);
session_.OnRstStream(rst_frame);
@@ -1134,7 +1057,8 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstOutOfOrder) {
EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed());
}
-TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAndLocalReset) {
+TEST_P(QuicSpdySessionTestServer,
+ ConnectionFlowControlAccountingFinAndLocalReset) {
// Test the situation where we receive a FIN on a stream, and before we fully
// consume all the data from the sequencer buffer we locally RST the stream.
// The bytes between highest consumed byte, and the final byte offset that we
@@ -1154,18 +1078,14 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAndLocalReset) {
stream->flow_controller()->highest_received_byte_offset());
// Reset stream locally.
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
stream->Reset(QUIC_STREAM_CANCELLED);
EXPECT_EQ(kByteOffset + frame.data_length,
session_.flow_controller()->bytes_consumed());
}
-TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAfterRst) {
+TEST_P(QuicSpdySessionTestServer, ConnectionFlowControlAccountingFinAfterRst) {
// Test that when we RST the stream (and tear down stream state), and then
// receive a FIN from the peer, we correctly adjust our connection level flow
// control receive window.
@@ -1182,12 +1102,8 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAfterRst) {
// Reset our stream: this results in the stream being closed locally.
TestStream* stream = session_.CreateOutgoingDynamicStream();
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
stream->Reset(QUIC_STREAM_CANCELLED);
// Now receive a response from the peer with a FIN. We should handle this by
@@ -1207,7 +1123,7 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAfterRst) {
session_.flow_controller()->highest_received_byte_offset());
}
-TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstAfterRst) {
+TEST_P(QuicSpdySessionTestServer, ConnectionFlowControlAccountingRstAfterRst) {
// Test that when we RST the stream (and tear down stream state), and then
// receive a RST from the peer, we correctly adjust our connection level flow
// control receive window.
@@ -1224,12 +1140,8 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstAfterRst) {
// Reset our stream: this results in the stream being closed locally.
TestStream* stream = session_.CreateOutgoingDynamicStream();
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
stream->Reset(QUIC_STREAM_CANCELLED);
EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
@@ -1247,7 +1159,7 @@ TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstAfterRst) {
session_.flow_controller()->highest_received_byte_offset());
}
-TEST_P(QuicSessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
+TEST_P(QuicSpdySessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
// Test that receipt of an invalid (< default) stream flow control window from
// the peer results in the connection being torn down.
const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
@@ -1259,7 +1171,7 @@ TEST_P(QuicSessionTestServer, InvalidStreamFlowControlWindowInHandshake) {
session_.OnConfigNegotiated();
}
-TEST_P(QuicSessionTestServer, InvalidSessionFlowControlWindowInHandshake) {
+TEST_P(QuicSpdySessionTestServer, InvalidSessionFlowControlWindowInHandshake) {
// Test that receipt of an invalid (< default) session flow control window
// from the peer results in the connection being torn down.
const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
@@ -1272,7 +1184,7 @@ TEST_P(QuicSessionTestServer, InvalidSessionFlowControlWindowInHandshake) {
}
// Test negotiation of custom server initial flow control window.
-TEST_P(QuicSessionTestServer, CustomFlowControlWindow) {
+TEST_P(QuicSpdySessionTestServer, CustomFlowControlWindow) {
QuicTagVector copt;
copt.push_back(kIFW7);
QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
@@ -1282,7 +1194,7 @@ TEST_P(QuicSessionTestServer, CustomFlowControlWindow) {
session_.flow_controller()));
}
-TEST_P(QuicSessionTestServer, FlowControlWithInvalidFinalOffset) {
+TEST_P(QuicSpdySessionTestServer, FlowControlWithInvalidFinalOffset) {
// Test that if we receive a stream RST with a highest byte offset that
// violates flow control, that we close the connection.
const uint64_t kLargeOffset = kInitialSessionFlowControlWindowForTest + 1;
@@ -1292,12 +1204,8 @@ TEST_P(QuicSessionTestServer, FlowControlWithInvalidFinalOffset) {
// Check that stream frame + FIN results in connection close.
TestStream* stream = session_.CreateOutgoingDynamicStream();
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
stream->Reset(QUIC_STREAM_CANCELLED);
QuicStreamFrame frame(stream->id(), true, kLargeOffset, QuicStringPiece());
session_.OnStreamFrame(frame);
@@ -1308,7 +1216,7 @@ TEST_P(QuicSessionTestServer, FlowControlWithInvalidFinalOffset) {
session_.OnRstStream(rst_frame);
}
-TEST_P(QuicSessionTestServer, WindowUpdateUnblocksHeadersStream) {
+TEST_P(QuicSpdySessionTestServer, WindowUpdateUnblocksHeadersStream) {
// Test that a flow control blocked headers stream gets unblocked on recipt of
// a WINDOW_UPDATE frame.
@@ -1331,7 +1239,8 @@ TEST_P(QuicSessionTestServer, WindowUpdateUnblocksHeadersStream) {
EXPECT_FALSE(session_.IsStreamFlowControlBlocked());
}
-TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseServerRejectStream) {
+TEST_P(QuicSpdySessionTestServer,
+ TooManyUnfinishedStreamsCauseServerRejectStream) {
// If a buggy/malicious peer creates too many streams that are not ended
// with a FIN or RST then we send an RST to refuse streams.
const QuicStreamId kMaxStreams = 5;
@@ -1345,26 +1254,15 @@ TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseServerRejectStream) {
QuicStreamFrame data1(i, false, 0, QuicStringPiece("HT"));
session_.OnStreamFrame(data1);
// EXPECT_EQ(1u, session_.GetNumOpenStreams());
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
- EXPECT_CALL(*connection_, OnStreamReset(i, _));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(i, _, _));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+ EXPECT_CALL(*connection_, OnStreamReset(i, _));
session_.CloseStream(i);
}
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
- EXPECT_CALL(*connection_,
- OnStreamReset(kFinalStreamId, QUIC_REFUSED_STREAM))
- .Times(1);
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(kFinalStreamId, QUIC_REFUSED_STREAM, _))
- .Times(1);
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+ EXPECT_CALL(*connection_, OnStreamReset(kFinalStreamId, QUIC_REFUSED_STREAM))
+ .Times(1);
// Create one more data streams to exceed limit of open stream.
QuicStreamFrame data1(kFinalStreamId, false, 0, QuicStringPiece("HT"));
session_.OnStreamFrame(data1);
@@ -1374,17 +1272,12 @@ TEST_P(QuicSessionTestServer, TooManyUnfinishedStreamsCauseServerRejectStream) {
session_.PostProcessAfterData();
}
-TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpened) {
+TEST_P(QuicSpdySessionTestServer, DrainingStreamsDoNotCountAsOpened) {
// Verify that a draining stream (which has received a FIN but not consumed
// it) does not count against the open quota (because it is closed from the
// protocol point of view).
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
- EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM)).Times(0);
- } else {
- EXPECT_CALL(*connection_, SendRstStream(_, QUIC_REFUSED_STREAM, _))
- .Times(0);
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+ EXPECT_CALL(*connection_, OnStreamReset(_, QUIC_REFUSED_STREAM)).Times(0);
const QuicStreamId kMaxStreams = 5;
QuicSessionPeer::SetMaxOpenIncomingStreams(&session_, kMaxStreams);
@@ -1405,7 +1298,7 @@ TEST_P(QuicSessionTestServer, DrainingStreamsDoNotCountAsOpened) {
session_.PostProcessAfterData();
}
-TEST_P(QuicSessionTestServer, TestMaxIncomingAndOutgoingStreamsAllowed) {
+TEST_P(QuicSpdySessionTestServer, TestMaxIncomingAndOutgoingStreamsAllowed) {
// Tests that on server side, the value of max_open_incoming/outgoing streams
// are setup correctly during negotiation.
// The value for outgoing stream is limited to negotiated value and for
@@ -1421,16 +1314,17 @@ TEST_P(QuicSessionTestServer, TestMaxIncomingAndOutgoingStreamsAllowed) {
kDefaultMaxStreamsPerConnection);
}
-class QuicSessionTestClient : public QuicSessionTestBase {
+class QuicSpdySessionTestClient : public QuicSpdySessionTestBase {
protected:
- QuicSessionTestClient() : QuicSessionTestBase(Perspective::IS_CLIENT) {}
+ QuicSpdySessionTestClient()
+ : QuicSpdySessionTestBase(Perspective::IS_CLIENT) {}
};
INSTANTIATE_TEST_CASE_P(Tests,
- QuicSessionTestClient,
+ QuicSpdySessionTestClient,
::testing::ValuesIn(AllSupportedVersions()));
-TEST_P(QuicSessionTestClient, AvailableStreamsClient) {
+TEST_P(QuicSpdySessionTestClient, AvailableStreamsClient) {
ASSERT_TRUE(session_.GetOrCreateDynamicStream(6) != nullptr);
// Both 2 and 4 should be available.
EXPECT_TRUE(QuicSessionPeer::IsStreamAvailable(&session_, 2));
@@ -1441,7 +1335,7 @@ TEST_P(QuicSessionTestClient, AvailableStreamsClient) {
EXPECT_FALSE(QuicSessionPeer::IsStreamAvailable(&session_, 5));
}
-TEST_P(QuicSessionTestClient, RecordFinAfterReadSideClosed) {
+TEST_P(QuicSpdySessionTestClient, RecordFinAfterReadSideClosed) {
// Verify that an incoming FIN is recorded in a stream object even if the read
// side has been closed. This prevents an entry from being made in
// locally_closed_streams_highest_offset_ (which will never be deleted).
@@ -1457,12 +1351,8 @@ TEST_P(QuicSessionTestClient, RecordFinAfterReadSideClosed) {
EXPECT_TRUE(stream->fin_received());
// Reset stream locally.
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
stream->Reset(QUIC_STREAM_CANCELLED);
EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream));
@@ -1479,7 +1369,7 @@ TEST_P(QuicSessionTestClient, RecordFinAfterReadSideClosed) {
QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(&session_).size());
}
-TEST_P(QuicSessionTestClient, TestMaxIncomingAndOutgoingStreamsAllowed) {
+TEST_P(QuicSpdySessionTestClient, TestMaxIncomingAndOutgoingStreamsAllowed) {
// Tests that on client side, the value of max_open_incoming/outgoing streams
// are setup correctly during negotiation.
// When flag is true, the value for outgoing stream is limited to negotiated
@@ -1491,7 +1381,7 @@ TEST_P(QuicSessionTestClient, TestMaxIncomingAndOutgoingStreamsAllowed) {
kDefaultMaxStreamsPerConnection);
}
-TEST_P(QuicSessionTestClient, EnableDHDTThroughConnectionOption) {
+TEST_P(QuicSpdySessionTestClient, EnableDHDTThroughConnectionOption) {
QuicTagVector copt;
copt.push_back(kDHDT);
QuicConfigPeer::SetConnectionOptionsToSend(session_.config(), copt);
@@ -1501,7 +1391,8 @@ TEST_P(QuicSessionTestClient, EnableDHDTThroughConnectionOption) {
0UL);
}
-TEST_P(QuicSessionTestClient, WritePriority) {
+TEST_P(QuicSpdySessionTestClient, WritePriority) {
+ QuicSpdySessionPeer::SetHeadersStream(&session_, nullptr);
TestHeadersStream* headers_stream = new TestHeadersStream(&session_);
QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream);
@@ -1536,27 +1427,29 @@ TEST_P(QuicSessionTestClient, WritePriority) {
}
}
-TEST_P(QuicSessionTestServer, ZombieStreams) {
+TEST_P(QuicSpdySessionTestServer, ZombieStreams) {
TestStream* stream2 = session_.CreateOutgoingDynamicStream();
QuicStreamPeer::SetStreamBytesWritten(3, stream2);
EXPECT_TRUE(stream2->IsWaitingForAcks());
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(2, _));
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(2, _));
+ session_.CloseStream(2);
+ if (GetQuicReloadableFlag(quic_reset_stream_is_not_zombie)) {
+ EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), 2));
+ ASSERT_EQ(1u, session_.closed_streams()->size());
+ EXPECT_EQ(2u, session_.closed_streams()->front()->id());
} else {
- EXPECT_CALL(*connection_, SendRstStream(2, _, _));
+ EXPECT_TRUE(QuicContainsKey(session_.zombie_streams(), 2));
+ EXPECT_TRUE(session_.closed_streams()->empty());
}
- session_.CloseStream(2);
- EXPECT_TRUE(QuicContainsKey(session_.zombie_streams(), 2));
- EXPECT_TRUE(session_.closed_streams()->empty());
session_.OnStreamDoneWaitingForAcks(2);
EXPECT_FALSE(QuicContainsKey(session_.zombie_streams(), 2));
EXPECT_EQ(1u, session_.closed_streams()->size());
EXPECT_EQ(2u, session_.closed_streams()->front()->id());
}
-TEST_P(QuicSessionTestServer, OnStreamFrameLost) {
+TEST_P(QuicSpdySessionTestServer, OnStreamFrameLost) {
QuicConnectionPeer::SetSessionDecidesWhatToWrite(connection_);
InSequence s;
@@ -1619,7 +1512,7 @@ TEST_P(QuicSessionTestServer, OnStreamFrameLost) {
EXPECT_FALSE(session_.WillingAndAbleToWrite());
}
-TEST_P(QuicSessionTestServer, DonotRetransmitDataOfClosedStreams) {
+TEST_P(QuicSpdySessionTestServer, DonotRetransmitDataOfClosedStreams) {
QuicConnectionPeer::SetSessionDecidesWhatToWrite(connection_);
InSequence s;
@@ -1643,12 +1536,8 @@ TEST_P(QuicSessionTestServer, DonotRetransmitDataOfClosedStreams) {
session_.MarkConnectionLevelWriteBlocked(stream6->id());
// Reset stream 4 locally.
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(stream4->id(), _));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(stream4->id(), _, _));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(stream4->id(), _));
stream4->Reset(QUIC_STREAM_CANCELLED);
// Verify stream 4 is removed from streams with lost data list.
@@ -1656,16 +1545,14 @@ TEST_P(QuicSessionTestServer, DonotRetransmitDataOfClosedStreams) {
EXPECT_CALL(*stream6, HasPendingRetransmission()).WillOnce(Return(false));
EXPECT_CALL(*stream2, OnCanWrite());
EXPECT_CALL(*stream2, HasPendingRetransmission()).WillOnce(Return(false));
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillRepeatedly(Invoke(&session_, &TestSession::ClearControlFrame));
EXPECT_CALL(*stream2, OnCanWrite());
EXPECT_CALL(*stream6, OnCanWrite());
session_.OnCanWrite();
}
-TEST_P(QuicSessionTestServer, RetransmitFrames) {
+TEST_P(QuicSpdySessionTestServer, RetransmitFrames) {
QuicConnectionPeer::SetSessionDecidesWhatToWrite(connection_);
MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>;
QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm);
@@ -1674,11 +1561,9 @@ TEST_P(QuicSessionTestServer, RetransmitFrames) {
TestStream* stream2 = session_.CreateOutgoingDynamicStream();
TestStream* stream4 = session_.CreateOutgoingDynamicStream();
TestStream* stream6 = session_.CreateOutgoingDynamicStream();
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
- session_.SendWindowUpdate(stream2->id(), 9);
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
+ session_.SendWindowUpdate(stream2->id(), 9);
QuicStreamFrame frame1(stream2->id(), false, 0, 9);
QuicStreamFrame frame2(stream4->id(), false, 0, 9);
@@ -1692,17 +1577,15 @@ TEST_P(QuicSessionTestServer, RetransmitFrames) {
EXPECT_FALSE(session_.WillingAndAbleToWrite());
EXPECT_CALL(*stream2, RetransmitStreamData(_, _, _)).WillOnce(Return(true));
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(&session_, &TestSession::ClearControlFrame));
EXPECT_CALL(*stream4, RetransmitStreamData(_, _, _)).WillOnce(Return(true));
EXPECT_CALL(*stream6, RetransmitStreamData(_, _, _)).WillOnce(Return(true));
EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
session_.RetransmitFrames(frames, TLP_RETRANSMISSION);
}
-TEST_P(QuicSessionTestServer, OnPriorityFrame) {
+TEST_P(QuicSpdySessionTestServer, OnPriorityFrame) {
QuicStreamId stream_id = GetNthClientInitiatedId(0);
TestStream* stream = session_.CreateIncomingDynamicStream(stream_id);
session_.OnPriorityFrame(stream_id, kV3HighestPriority);
diff --git a/chromium/net/quic/core/quic_spdy_stream.cc b/chromium/net/quic/core/quic_spdy_stream.cc
index 016587ca85c..48c17cdd8d5 100644
--- a/chromium/net/quic/core/quic_spdy_stream.cc
+++ b/chromium/net/quic/core/quic_spdy_stream.cc
@@ -26,23 +26,25 @@ namespace net {
" ")
QuicSpdyStream::QuicSpdyStream(QuicStreamId id, QuicSpdySession* spdy_session)
- : QuicStream(id, spdy_session),
+ : QuicStream(id, spdy_session, /*is_static=*/false),
spdy_session_(spdy_session),
visitor_(nullptr),
headers_decompressed_(false),
- priority_(kDefaultPriority),
trailers_decompressed_(false),
trailers_consumed_(false) {
DCHECK_NE(kCryptoStreamId, id);
// Don't receive any callbacks from the sequencer until headers
// are complete.
sequencer()->SetBlockedUntilFlush();
- spdy_session_->RegisterStreamPriority(id, priority_);
+ if (!session()->register_streams_early()) {
+ spdy_session_->RegisterStreamPriority(id, /*is_static=*/false, priority());
+ }
}
QuicSpdyStream::~QuicSpdyStream() {
- if (spdy_session_ != nullptr) {
- spdy_session_->UnregisterStreamPriority(id());
+ if (spdy_session_ != nullptr && !session()->register_streams_early()) {
+ spdy_session_->UnregisterStreamPriority(id(),
+ /*is_static=*/false);
}
}
@@ -51,7 +53,7 @@ size_t QuicSpdyStream::WriteHeaders(
bool fin,
QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) {
size_t bytes_written = spdy_session_->WriteHeaders(
- id(), std::move(header_block), fin, priority_, std::move(ack_listener));
+ id(), std::move(header_block), fin, priority(), std::move(ack_listener));
if (fin) {
// TODO(rch): Add test to ensure fin_sent_ is set whenever a fin is sent.
set_fin_sent(true);
@@ -87,8 +89,9 @@ size_t QuicSpdyStream::WriteTrailers(
// Write the trailing headers with a FIN, and close stream for writing:
// trailers are the last thing to be sent on a stream.
const bool kFin = true;
- size_t bytes_written = spdy_session_->WriteHeaders(
- id(), std::move(trailer_block), kFin, priority_, std::move(ack_listener));
+ size_t bytes_written =
+ spdy_session_->WriteHeaders(id(), std::move(trailer_block), kFin,
+ priority(), std::move(ack_listener));
set_fin_sent(kFin);
// Trailers are the last thing to be sent on a stream, but if there is still
@@ -137,12 +140,6 @@ void QuicSpdyStream::ConsumeHeaderList() {
}
}
-void QuicSpdyStream::SetPriority(SpdyPriority priority) {
- DCHECK_EQ(0u, stream_bytes_written());
- priority_ = priority;
- spdy_session_->UpdateStreamPriority(id(), priority);
-}
-
void QuicSpdyStream::OnStreamHeadersPriority(SpdyPriority priority) {
DCHECK_EQ(Perspective::IS_SERVER, session()->connection()->perspective());
SetPriority(priority);
@@ -308,10 +305,6 @@ bool QuicSpdyStream::FinishedReadingTrailers() const {
}
}
-SpdyPriority QuicSpdyStream::priority() const {
- return priority_;
-}
-
void QuicSpdyStream::ClearSession() {
spdy_session_ = nullptr;
}
diff --git a/chromium/net/quic/core/quic_spdy_stream.h b/chromium/net/quic/core/quic_spdy_stream.h
index 48e92200021..947b323bf5c 100644
--- a/chromium/net/quic/core/quic_spdy_stream.h
+++ b/chromium/net/quic/core/quic_spdy_stream.h
@@ -35,12 +35,6 @@ class QuicStreamPeer;
class QuicSpdySession;
-// This is somewhat arbitrary. It's possible, but unlikely, we will either fail
-// to set a priority client-side, or cancel a stream before stripping the
-// priority from the wire server-side. In either case, start out with a
-// priority in the middle.
-const SpdyPriority kDefaultPriority = 3;
-
// A QUIC stream that can send and receive HTTP2 (SPDY) headers.
class QUIC_EXPORT_PRIVATE QuicSpdyStream : public QuicStream {
public:
@@ -164,12 +158,6 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStream : public QuicStream {
// been received and there are no trailers.
bool FinishedReadingTrailers() const;
- SpdyPriority priority() const;
-
- // Sets priority_ to priority. This should only be called before bytes are
- // written to the server.
- void SetPriority(SpdyPriority priority);
-
// Called when owning session is getting deleted to avoid subsequent
// use of the spdy_session_ member.
void ClearSession();
@@ -202,8 +190,6 @@ class QUIC_EXPORT_PRIVATE QuicSpdyStream : public QuicStream {
Visitor* visitor_;
// True if the headers have been completely decompressed.
bool headers_decompressed_;
- // The priority of the stream, once parsed.
- SpdyPriority priority_;
// Contains a copy of the decompressed header (name, value) pairs until they
// are consumed via Readv.
QuicHeaderList header_list_;
diff --git a/chromium/net/quic/core/quic_spdy_stream_test.cc b/chromium/net/quic/core/quic_spdy_stream_test.cc
index 1b524942177..10b596c3880 100644
--- a/chromium/net/quic/core/quic_spdy_stream_test.cc
+++ b/chromium/net/quic/core/quic_spdy_stream_test.cc
@@ -126,6 +126,7 @@ class QuicSpdyStreamTest : public QuicTestWithParam<ParsedQuicVersion> {
SupportedVersions(GetParam()));
session_ =
QuicMakeUnique<testing::StrictMock<MockQuicSpdySession>>(connection_);
+ session_->Initialize();
stream_ = new TestStream(GetNthClientInitiatedId(0), session_.get(),
stream_should_process_data);
session_->ActivateStream(QuicWrapUnique(stream_));
@@ -436,11 +437,7 @@ TEST_P(QuicSpdyStreamTest, StreamFlowControlBlocked) {
const uint64_t kOverflow = 15;
QuicString body(kWindow + kOverflow, 'a');
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- } else {
- EXPECT_CALL(*connection_, SendBlocked(GetNthClientInitiatedId(0)));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.WillOnce(Return(QuicConsumedData(kWindow, true)));
stream_->WriteOrBufferData(body, false, nullptr);
@@ -527,15 +524,7 @@ TEST_P(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) {
// window of kWindow bytes.
QuicStreamFrame frame2(GetNthClientInitiatedId(0), false, kWindow / 3,
QuicStringPiece(body));
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- } else {
- EXPECT_CALL(*connection_,
- SendWindowUpdate(GetNthClientInitiatedId(0),
- QuicFlowControllerPeer::ReceiveWindowOffset(
- stream_->flow_controller()) +
- 2 * kWindow / 3));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
stream_->OnStreamFrame(frame2);
EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowSize(
stream_->flow_controller()));
@@ -584,18 +573,7 @@ TEST_P(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) {
// Now receive a further single byte on one stream - again this does not
// trigger a stream WINDOW_UPDATE, but now the connection flow control window
// is over half full and thus a connection WINDOW_UPDATE is sent.
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- } else {
- EXPECT_CALL(*connection_, SendWindowUpdate(GetNthClientInitiatedId(0), _))
- .Times(0);
- EXPECT_CALL(*connection_, SendWindowUpdate(GetNthClientInitiatedId(1), _))
- .Times(0);
- EXPECT_CALL(*connection_,
- SendWindowUpdate(0, QuicFlowControllerPeer::ReceiveWindowOffset(
- session_->flow_controller()) +
- 1 + kWindow / 2));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
QuicStreamFrame frame3(GetNthClientInitiatedId(0), false, (kWindow / 4),
QuicStringPiece("a"));
stream_->OnStreamFrame(frame3);
diff --git a/chromium/net/quic/core/quic_stream.cc b/chromium/net/quic/core/quic_stream.cc
index 2ca58558bef..72e15671f23 100644
--- a/chromium/net/quic/core/quic_stream.cc
+++ b/chromium/net/quic/core/quic_stream.cc
@@ -13,6 +13,8 @@
#include "net/quic/platform/api/quic_str_cat.h"
#include "net/quic/platform/api/quic_string.h"
+using net::SpdyPriority;
+
namespace net {
#define ENDPOINT \
@@ -40,10 +42,14 @@ size_t GetReceivedFlowControlWindow(QuicSession* session) {
} // namespace
-QuicStream::QuicStream(QuicStreamId id, QuicSession* session)
+// static
+const SpdyPriority QuicStream::kDefaultPriority;
+
+QuicStream::QuicStream(QuicStreamId id, QuicSession* session, bool is_static)
: sequencer_(this, session->connection()->clock()),
id_(id),
session_(session),
+ priority_(kDefaultPriority),
stream_bytes_read_(0),
stream_error_(QUIC_STREAM_NO_ERROR),
connection_error_(QUIC_NO_ERROR),
@@ -72,9 +78,12 @@ QuicStream::QuicStream(QuicStreamId id, QuicSession* session)
ack_listener_(nullptr),
send_buffer_(
session->connection()->helper()->GetStreamSendBufferAllocator()),
- buffered_data_threshold_(
- GetQuicFlag(FLAGS_quic_buffered_data_threshold)) {
+ buffered_data_threshold_(GetQuicFlag(FLAGS_quic_buffered_data_threshold)),
+ is_static_(is_static) {
SetFromConfig();
+ if (session_->register_streams_early()) {
+ session_->RegisterStreamPriority(id, is_static_, priority_);
+ }
}
QuicStream::~QuicStream() {
@@ -85,6 +94,9 @@ QuicStream::~QuicStream() {
<< send_buffer_.stream_bytes_outstanding()
<< ", fin_outstanding: " << fin_outstanding_;
}
+ if (session_ != nullptr && session_->register_streams_early()) {
+ session_->UnregisterStreamPriority(id(), is_static_);
+ }
}
void QuicStream::SetFromConfig() {}
@@ -215,6 +227,16 @@ void QuicStream::CloseConnectionWithDetails(QuicErrorCode error,
error, details, ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
}
+SpdyPriority QuicStream::priority() const {
+ return priority_;
+}
+
+void QuicStream::SetPriority(SpdyPriority priority) {
+ DCHECK_EQ(0u, stream_bytes_written());
+ priority_ = priority;
+ session_->UpdateStreamPriority(id(), priority);
+}
+
void QuicStream::WriteOrBufferData(
QuicStringPiece data,
bool fin,
@@ -263,24 +285,7 @@ void QuicStream::WriteOrBufferData(
void QuicStream::OnCanWrite() {
if (HasPendingRetransmission()) {
- const bool session_unblocks_stream = session_->session_unblocks_stream();
WritePendingRetransmission();
- if (session_unblocks_stream) {
- // Exit early to allow other streams to write pending retransmissions if
- // any.
- return;
- }
- if (HasPendingRetransmission()) {
- // Stream did not finish retransmission, session will unblock this stream
- // later.
- return;
- }
- const bool fin_only = !HasBufferedData() && fin_buffered_ && !fin_sent_;
- if ((!flow_controller_.IsBlocked() && HasBufferedData()) || fin_only) {
- // Stream finished retransmission. If there is new data which can be sent,
- // tell the session to unblock this stream later.
- session_->MarkConnectionLevelWriteBlocked(id_);
- }
// Exit early to allow other streams to write pending retransmissions if
// any.
return;
@@ -374,7 +379,6 @@ QuicConsumedData QuicStream::WritevData(const struct iovec* iov,
}
QuicConsumedData QuicStream::WriteMemSlices(QuicMemSliceSpan span, bool fin) {
- DCHECK(session_->can_use_slices());
QuicConsumedData consumed_data(0, false);
if (span.empty() && !fin) {
QUIC_BUG << "span.empty() && !fin";
@@ -448,13 +452,13 @@ void QuicStream::CloseReadSide() {
if (read_side_closed_) {
return;
}
- QUIC_DLOG(INFO) << ENDPOINT << "Done reading from stream " << id();
+ QUIC_DVLOG(1) << ENDPOINT << "Done reading from stream " << id();
read_side_closed_ = true;
sequencer_.ReleaseBuffer();
if (write_side_closed_) {
- QUIC_DLOG(INFO) << ENDPOINT << "Closing stream " << id();
+ QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << id();
session_->CloseStream(id());
}
}
@@ -463,11 +467,11 @@ void QuicStream::CloseWriteSide() {
if (write_side_closed_) {
return;
}
- QUIC_DLOG(INFO) << ENDPOINT << "Done writing to stream " << id();
+ QUIC_DVLOG(1) << ENDPOINT << "Done writing to stream " << id();
write_side_closed_ = true;
if (read_side_closed_) {
- QUIC_DLOG(INFO) << ENDPOINT << "Closing stream " << id();
+ QUIC_DVLOG(1) << ENDPOINT << "Closing stream " << id();
session_->CloseStream(id());
}
}
@@ -486,7 +490,7 @@ HandshakeProtocol QuicStream::handshake_protocol() const {
}
void QuicStream::StopReading() {
- QUIC_DLOG(INFO) << ENDPOINT << "Stop reading from stream " << id();
+ QUIC_DVLOG(1) << ENDPOINT << "Stop reading from stream " << id();
sequencer_.StopReading();
}
@@ -503,6 +507,10 @@ void QuicStream::OnClose() {
// written on this stream before termination. Done here if needed, using a
// RST_STREAM frame.
QUIC_DLOG(INFO) << ENDPOINT << "Sending RST_STREAM in OnClose: " << id();
+ if (GetQuicReloadableFlag(quic_reset_stream_is_not_zombie)) {
+ QUIC_FLAG_COUNT(quic_reloadable_flag_quic_reset_stream_is_not_zombie);
+ session_->OnStreamDoneWaitingForAcks(id_);
+ }
session_->SendRstStream(id(), QUIC_RST_ACKNOWLEDGEMENT,
stream_bytes_written());
rst_sent_ = true;
@@ -524,18 +532,8 @@ void QuicStream::OnClose() {
void QuicStream::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
if (flow_controller_.UpdateSendWindowOffset(frame.byte_offset)) {
- if (session_->session_unblocks_stream()) {
- QUIC_FLAG_COUNT(quic_reloadable_flag_quic_streams_unblocked_by_session2);
- // Let session unblock this stream.
- session_->MarkConnectionLevelWriteBlocked(id_);
- } else {
- // Writing can be done again!
- // TODO(rjshade): This does not respect priorities (e.g. multiple
- // outstanding POSTs are unblocked on arrival of
- // SHLO with initial window).
- // As long as the connection is not flow control blocked, write on!
- OnCanWrite();
- }
+ // Let session unblock this stream.
+ session_->MarkConnectionLevelWriteBlocked(id_);
}
}
@@ -578,12 +576,8 @@ void QuicStream::AddBytesConsumed(QuicByteCount bytes) {
void QuicStream::UpdateSendWindowOffset(QuicStreamOffset new_window) {
if (flow_controller_.UpdateSendWindowOffset(new_window)) {
- if (session_->session_unblocks_stream()) {
- // Let session unblock this stream.
- session_->MarkConnectionLevelWriteBlocked(id_);
- } else {
- OnCanWrite();
- }
+ // Let session unblock this stream.
+ session_->MarkConnectionLevelWriteBlocked(id_);
}
}
@@ -601,13 +595,13 @@ bool QuicStream::OnStreamFrameAcked(QuicStreamOffset offset,
QuicByteCount newly_acked_length = 0;
if (!send_buffer_.OnStreamDataAcked(offset, data_length,
&newly_acked_length)) {
- RecordInternalErrorLocation(QUIC_STREAM_1);
+ RecordInternalErrorLocation(QUIC_STREAM_ACKED_UNSENT_DATA);
CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
"Trying to ack unsent data.");
return false;
}
if (!fin_sent_ && fin_acked) {
- RecordInternalErrorLocation(QUIC_STREAM_2);
+ RecordInternalErrorLocation(QUIC_STREAM_ACKED_UNSENT_FIN);
CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
"Trying to ack unsent fin.");
return false;
diff --git a/chromium/net/quic/core/quic_stream.h b/chromium/net/quic/core/quic_stream.h
index adc027992e1..f8c75afe7da 100644
--- a/chromium/net/quic/core/quic_stream.h
+++ b/chromium/net/quic/core/quic_stream.h
@@ -34,6 +34,7 @@
#include "net/quic/platform/api/quic_reference_counted.h"
#include "net/quic/platform/api/quic_string.h"
#include "net/quic/platform/api/quic_string_piece.h"
+#include "net/spdy/core/spdy_protocol.h"
namespace net {
@@ -45,7 +46,19 @@ class QuicSession;
class QUIC_EXPORT_PRIVATE QuicStream {
public:
- QuicStream(QuicStreamId id, QuicSession* session);
+ // This is somewhat arbitrary. It's possible, but unlikely, we will either
+ // fail to set a priority client-side, or cancel a stream before stripping the
+ // priority from the wire server-side. In either case, start out with a
+ // priority in the middle.
+ static const SpdyPriority kDefaultPriority = 3;
+ static_assert(kDefaultPriority ==
+ (kV3LowestPriority + kV3HighestPriority) / 2,
+ "Unexpected value of kDefaultPriority");
+
+ // Creates a new stream with stream_id |id| associated with |session|. If
+ // |is_static| is true, then the stream will be given precedence
+ // over other streams when determing what streams should write next.
+ QuicStream(QuicStreamId id, QuicSession* session, bool is_static);
virtual ~QuicStream();
@@ -93,6 +106,12 @@ class QUIC_EXPORT_PRIVATE QuicStream {
virtual void CloseConnectionWithDetails(QuicErrorCode error,
const QuicString& details);
+ SpdyPriority priority() const;
+
+ // Sets priority_ to priority. This should only be called before bytes are
+ // written to the server.
+ void SetPriority(SpdyPriority priority);
+
// Returns true if this stream is still waiting for acks of sent data.
// This will return false if all data has been acked, or if the stream
// is no longer interested in data being acked (which happens when
@@ -338,6 +357,8 @@ class QUIC_EXPORT_PRIVATE QuicStream {
QuicStreamId id_;
// Pointer to the owning QuicSession object.
QuicSession* session_;
+ // The priority of the stream, once parsed.
+ SpdyPriority priority_;
// Bytes read refers to payload bytes only: they do not include framing,
// encryption overhead etc.
uint64_t stream_bytes_read_;
@@ -410,6 +431,10 @@ class QUIC_EXPORT_PRIVATE QuicStream {
// Latched value of FLAGS_quic_buffered_data_threshold.
const QuicByteCount buffered_data_threshold_;
+ // If true, then this stream has precedence over other streams for write
+ // scheduling.
+ const bool is_static_;
+
DISALLOW_COPY_AND_ASSIGN(QuicStream);
};
diff --git a/chromium/net/quic/core/quic_stream_send_buffer.cc b/chromium/net/quic/core/quic_stream_send_buffer.cc
index d92205c4575..ac1ab6ef1bd 100644
--- a/chromium/net/quic/core/quic_stream_send_buffer.cc
+++ b/chromium/net/quic/core/quic_stream_send_buffer.cc
@@ -15,6 +15,16 @@
namespace net {
+namespace {
+
+struct CompareOffset {
+ bool operator()(const BufferedSlice& slice, QuicStreamOffset offset) const {
+ return slice.offset + slice.slice.length() < offset;
+ }
+};
+
+} // namespace
+
BufferedSlice::BufferedSlice(QuicMemSlice mem_slice, QuicStreamOffset offset)
: slice(std::move(mem_slice)), offset(offset) {}
@@ -35,7 +45,11 @@ QuicStreamSendBuffer::QuicStreamSendBuffer(QuicBufferAllocator* allocator)
stream_bytes_written_(0),
stream_bytes_outstanding_(0),
write_index_(-1),
- use_write_index_(GetQuicReloadableFlag(quic_use_write_index)) {}
+ free_mem_slice_out_of_order_(
+ GetQuicReloadableFlag(quic_free_mem_slice_out_of_order)),
+ enable_fast_path_on_data_acked_(
+ free_mem_slice_out_of_order_ &&
+ GetQuicReloadableFlag(quic_fast_path_on_stream_data_acked)) {}
QuicStreamSendBuffer::~QuicStreamSendBuffer() {}
@@ -81,32 +95,6 @@ void QuicStreamSendBuffer::OnStreamDataConsumed(size_t bytes_consumed) {
bool QuicStreamSendBuffer::WriteStreamData(QuicStreamOffset offset,
QuicByteCount data_length,
QuicDataWriter* writer) {
- if (use_write_index_) {
- return WriteStreamDataWithIndex(offset, data_length, writer);
- }
- for (const BufferedSlice& slice : buffered_slices_) {
- if (data_length == 0 || offset < slice.offset) {
- break;
- }
- if (offset >= slice.offset + slice.slice.length()) {
- continue;
- }
- QuicByteCount slice_offset = offset - slice.offset;
- QuicByteCount copy_length =
- std::min(data_length, slice.slice.length() - slice_offset);
- if (!writer->WriteBytes(slice.slice.data() + slice_offset, copy_length)) {
- return false;
- }
- offset += copy_length;
- data_length -= copy_length;
- }
-
- return data_length == 0;
-}
-
-bool QuicStreamSendBuffer::WriteStreamDataWithIndex(QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer) {
bool write_index_hit = false;
QuicDeque<BufferedSlice>::iterator slice_it =
write_index_ == -1
@@ -121,7 +109,6 @@ bool QuicStreamSendBuffer::WriteStreamDataWithIndex(QuicStreamOffset offset,
// Determine if write actually happens at indexed slice.
if (offset >= slice_it->offset) {
write_index_hit = true;
- QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_use_write_index, 1, 2);
} else {
// Write index missed, move iterator to the beginning.
slice_it = buffered_slices_.begin();
@@ -172,6 +159,36 @@ bool QuicStreamSendBuffer::OnStreamDataAcked(
if (data_length == 0) {
return true;
}
+ if (enable_fast_path_on_data_acked_) {
+ QUIC_FLAG_COUNT(quic_reloadable_flag_quic_fast_path_on_stream_data_acked);
+ bool is_disjoint = false;
+ if (GetQuicReloadableFlag(quic_fast_is_disjoint)) {
+ is_disjoint =
+ bytes_acked_.Empty() || offset >= bytes_acked_.rbegin()->max();
+ QUIC_FLAG_COUNT(quic_reloadable_flag_quic_fast_is_disjoint);
+ }
+ if (is_disjoint || bytes_acked_.IsDisjoint(Interval<QuicStreamOffset>(
+ offset, offset + data_length))) {
+ // Optimization for the typical case, when all data is newly acked.
+ if (stream_bytes_outstanding_ < data_length) {
+ return false;
+ }
+ bytes_acked_.Add(offset, offset + data_length);
+ *newly_acked_length = data_length;
+ stream_bytes_outstanding_ -= data_length;
+ pending_retransmissions_.Difference(offset, offset + data_length);
+ if (!FreeMemSlices(offset, offset + data_length)) {
+ return false;
+ }
+ CleanUpBufferedSlices();
+ return true;
+ }
+ // Exit if no new data gets acked.
+ if (bytes_acked_.Contains(offset, offset + data_length)) {
+ return true;
+ }
+ }
+ // Execute the slow path if newly acked data fill in existing holes.
QuicIntervalSet<QuicStreamOffset> newly_acked(offset, offset + data_length);
newly_acked.Difference(bytes_acked_);
for (const auto& interval : newly_acked) {
@@ -183,25 +200,34 @@ bool QuicStreamSendBuffer::OnStreamDataAcked(
stream_bytes_outstanding_ -= *newly_acked_length;
bytes_acked_.Add(offset, offset + data_length);
pending_retransmissions_.Difference(offset, offset + data_length);
+ if (free_mem_slice_out_of_order_) {
+ QUIC_FLAG_COUNT(quic_reloadable_flag_quic_free_mem_slice_out_of_order);
+ if (newly_acked.Empty()) {
+ return true;
+ }
+ if (!FreeMemSlices(newly_acked.begin()->min(),
+ newly_acked.rbegin()->max())) {
+ return false;
+ }
+ CleanUpBufferedSlices();
+ return true;
+ }
while (!buffered_slices_.empty() &&
bytes_acked_.Contains(buffered_slices_.front().offset,
buffered_slices_.front().offset +
buffered_slices_.front().slice.length())) {
// Remove data which stops waiting for acks. Please note, data can be
// acked out of order, but send buffer is cleaned up in order.
- if (use_write_index_) {
- QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_use_write_index, 2, 2);
- QUIC_BUG_IF(write_index_ == 0)
- << "Fail to advance current_write_slice_. It points to the slice "
- "whose data has all be written and ACK'ed or ignored. "
- "current_write_slice_ offset "
- << buffered_slices_[write_index_].offset << " length "
- << buffered_slices_[write_index_].slice.length();
- if (write_index_ > 0) {
- // If write index is pointing to any slice, reduce the index as the
- // slices are all shifted to the left by one.
- --write_index_;
- }
+ QUIC_BUG_IF(write_index_ == 0)
+ << "Fail to advance current_write_slice_. It points to the slice "
+ "whose data has all be written and ACK'ed or ignored. "
+ "current_write_slice_ offset "
+ << buffered_slices_[write_index_].offset << " length "
+ << buffered_slices_[write_index_].slice.length();
+ if (write_index_ > 0) {
+ // If write index is pointing to any slice, reduce the index as the
+ // slices are all shifted to the left by one.
+ --write_index_;
}
buffered_slices_.pop_front();
}
@@ -247,6 +273,50 @@ StreamPendingRetransmission QuicStreamSendBuffer::NextPendingRetransmission()
return {0, 0};
}
+bool QuicStreamSendBuffer::FreeMemSlices(QuicStreamOffset start,
+ QuicStreamOffset end) {
+ DCHECK(free_mem_slice_out_of_order_);
+ // Find it, such that buffered_slices_[it - 1].end < start <=
+ // buffered_slices_[it].end.
+ auto it = std::lower_bound(buffered_slices_.begin(), buffered_slices_.end(),
+ start, CompareOffset());
+ if (it == buffered_slices_.end() || it->slice.empty()) {
+ QUIC_DLOG(ERROR) << "Offset " << start
+ << " does not exist or it has already been acked.";
+ return false;
+ }
+ for (; it != buffered_slices_.end(); ++it) {
+ if (it->offset >= end) {
+ break;
+ }
+ if (!it->slice.empty() &&
+ bytes_acked_.Contains(it->offset, it->offset + it->slice.length())) {
+ it->slice.Reset();
+ }
+ }
+ return true;
+}
+
+void QuicStreamSendBuffer::CleanUpBufferedSlices() {
+ DCHECK(free_mem_slice_out_of_order_);
+ while (!buffered_slices_.empty() && buffered_slices_.front().slice.empty()) {
+ // Remove data which stops waiting for acks. Please note, mem slices can
+ // be released out of order, but send buffer is cleaned up in order.
+ QUIC_BUG_IF(write_index_ == 0)
+ << "Fail to advance current_write_slice_. It points to the slice "
+ "whose data has all be written and ACK'ed or ignored. "
+ "current_write_slice_ offset "
+ << buffered_slices_[write_index_].offset << " length "
+ << buffered_slices_[write_index_].slice.length();
+ if (write_index_ > 0) {
+ // If write index is pointing to any slice, reduce the index as the
+ // slices are all shifted to the left by one.
+ --write_index_;
+ }
+ buffered_slices_.pop_front();
+ }
+}
+
bool QuicStreamSendBuffer::IsStreamDataOutstanding(
QuicStreamOffset offset,
QuicByteCount data_length) const {
diff --git a/chromium/net/quic/core/quic_stream_send_buffer.h b/chromium/net/quic/core/quic_stream_send_buffer.h
index 30a12700f11..ff8d552b83c 100644
--- a/chromium/net/quic/core/quic_stream_send_buffer.h
+++ b/chromium/net/quic/core/quic_stream_send_buffer.h
@@ -123,14 +123,13 @@ class QUIC_EXPORT_PRIVATE QuicStreamSendBuffer {
friend class test::QuicStreamSendBufferPeer;
friend class test::QuicStreamPeer;
- // Another version of WriteStreamData() to be able to start writing from
- // write_index_ points to instead of searching through the slices to find the
- // place to write.
- // TODO(danzh): inline this method into WriteStreamData() after
- // quic_reloadable_flag_quic_use_write_index is deprecated.
- bool WriteStreamDataWithIndex(QuicStreamOffset offset,
- QuicByteCount data_length,
- QuicDataWriter* writer);
+ // Called when data within offset [start, end) gets acked. Frees fully
+ // acked buffered slices if any. Returns false if the corresponding data does
+ // not exist or has been acked.
+ bool FreeMemSlices(QuicStreamOffset start, QuicStreamOffset end);
+
+ // Cleanup empty slices in order from buffered_slices_.
+ void CleanUpBufferedSlices();
QuicDeque<BufferedSlice> buffered_slices_;
@@ -155,8 +154,12 @@ class QUIC_EXPORT_PRIVATE QuicStreamSendBuffer {
// time. -1 if send buffer is empty or all data has been written.
int32_t write_index_;
- // Latched value of quic_reloadable_flag_quic_stream_send_buffer_write_index.
- const bool use_write_index_;
+ // Latched value of quic_reloadable_flag_quic_free_mem_slice_out_of_order.
+ const bool free_mem_slice_out_of_order_;
+
+ // Latched value of quic_reloadable_flag_quic_free_mem_slice_out_of_order and
+ // quic_reloadable_flag_quic_fast_path_on_stream_data_acked.
+ const bool enable_fast_path_on_data_acked_;
};
} // namespace net
diff --git a/chromium/net/quic/core/quic_stream_send_buffer_test.cc b/chromium/net/quic/core/quic_stream_send_buffer_test.cc
index fc7abc262b8..a83f5260888 100644
--- a/chromium/net/quic/core/quic_stream_send_buffer_test.cc
+++ b/chromium/net/quic/core/quic_stream_send_buffer_test.cc
@@ -105,12 +105,8 @@ TEST_F(QuicStreamSendBufferTest, CopyDataToBuffer) {
// Invalid data copy.
QuicDataWriter writer3(4000, buf, HOST_BYTE_ORDER);
EXPECT_FALSE(send_buffer_.WriteStreamData(3000, 1024, &writer3));
- if (GetQuicReloadableFlag(quic_use_write_index)) {
- EXPECT_DFATAL(send_buffer_.WriteStreamData(0, 4000, &writer3),
- "Writer fails to write.");
- } else {
- EXPECT_FALSE(send_buffer_.WriteStreamData(0, 4000, &writer3));
- }
+ EXPECT_DFATAL(send_buffer_.WriteStreamData(0, 4000, &writer3),
+ "Writer fails to write.");
send_buffer_.OnStreamDataConsumed(3840);
EXPECT_EQ(3840u, send_buffer_.stream_bytes_written());
@@ -188,6 +184,40 @@ TEST_F(QuicStreamSendBufferTest, AckStreamDataMultipleTimes) {
EXPECT_FALSE(send_buffer_.OnStreamDataAcked(4000, 100, &newly_acked_length));
}
+TEST_F(QuicStreamSendBufferTest, AckStreamDataOutOfOrder) {
+ WriteAllData();
+ QuicByteCount newly_acked_length;
+ EXPECT_TRUE(send_buffer_.OnStreamDataAcked(500, 1000, &newly_acked_length));
+ EXPECT_EQ(1000u, newly_acked_length);
+ EXPECT_EQ(4u, send_buffer_.size());
+ EXPECT_EQ(3840u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
+
+ EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1200, 1000, &newly_acked_length));
+ EXPECT_EQ(700u, newly_acked_length);
+ EXPECT_EQ(4u, send_buffer_.size());
+ if (GetQuicReloadableFlag(quic_free_mem_slice_out_of_order)) {
+ // Slice 2 gets fully acked.
+ EXPECT_EQ(2816u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
+ } else {
+ EXPECT_EQ(3840u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
+ }
+
+ EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2000, 1840, &newly_acked_length));
+ EXPECT_EQ(1640u, newly_acked_length);
+ EXPECT_EQ(4u, send_buffer_.size());
+ if (GetQuicReloadableFlag(quic_free_mem_slice_out_of_order)) {
+ // Slices 3 and 4 get fully acked.
+ EXPECT_EQ(1024u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
+ } else {
+ EXPECT_EQ(3840u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
+ }
+
+ EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1000, &newly_acked_length));
+ EXPECT_EQ(500u, newly_acked_length);
+ EXPECT_EQ(0u, send_buffer_.size());
+ EXPECT_EQ(0u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
+}
+
TEST_F(QuicStreamSendBufferTest, PendingRetransmission) {
WriteAllData();
EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(0, 3840));
@@ -230,9 +260,6 @@ TEST_F(QuicStreamSendBufferTest, PendingRetransmission) {
}
TEST_F(QuicStreamSendBufferTest, CurrentWriteIndex) {
- if (!GetQuicReloadableFlag(quic_use_write_index)) {
- return;
- }
char buf[4000];
QuicDataWriter writer(4000, buf, HOST_BYTE_ORDER);
// With data buffered, index points to the 1st slice of data.
diff --git a/chromium/net/quic/core/quic_stream_sequencer_buffer.cc b/chromium/net/quic/core/quic_stream_sequencer_buffer.cc
index f978b59a588..ac3a42e73dd 100644
--- a/chromium/net/quic/core/quic_stream_sequencer_buffer.cc
+++ b/chromium/net/quic/core/quic_stream_sequencer_buffer.cc
@@ -103,7 +103,40 @@ QuicErrorCode QuicStreamSequencerBuffer::OnStreamData(
RecordInternalErrorLocation(QUIC_STREAM_SEQUENCER_BUFFER);
return QUIC_INTERNAL_ERROR;
}
-
+ if (GetQuicReloadableFlag(quic_fast_path_on_stream_data) &&
+ (bytes_received_.Empty() ||
+ starting_offset >= bytes_received_.rbegin()->max() ||
+ bytes_received_.IsDisjoint(Interval<QuicStreamOffset>(
+ starting_offset, starting_offset + size)))) {
+ // Optimization for the typical case, when all data is newly received.
+ QUIC_FLAG_COUNT(quic_reloadable_flag_quic_fast_path_on_stream_data);
+ if (!bytes_received_.Empty() &&
+ starting_offset == bytes_received_.rbegin()->max()) {
+ // Extend the right edge of last interval.
+ // TODO(fayang): Encapsulate this into a future version of QuicIntervalSet
+ // if this is more efficient than Add.
+ const_cast<Interval<QuicPacketNumber>*>(&(*bytes_received_.rbegin()))
+ ->SetMax(starting_offset + size);
+ } else {
+ bytes_received_.Add(starting_offset, starting_offset + size);
+ if (bytes_received_.Size() >= kMaxNumDataIntervalsAllowed) {
+ // This frame is going to create more intervals than allowed. Stop
+ // processing.
+ *error_details = "Too many data intervals received for this stream.";
+ return QUIC_TOO_MANY_STREAM_DATA_INTERVALS;
+ }
+ }
+ size_t bytes_copy = 0;
+ if (!CopyStreamData(starting_offset, data, &bytes_copy, error_details)) {
+ return QUIC_STREAM_SEQUENCER_INVALID_STATE;
+ }
+ *bytes_buffered += bytes_copy;
+ frame_arrival_time_map_.insert(
+ std::make_pair(starting_offset, FrameInfo(size, timestamp)));
+ num_bytes_buffered_ += *bytes_buffered;
+ return QUIC_NO_ERROR;
+ }
+ // Slow path, received data overlaps with received data.
QuicIntervalSet<QuicStreamOffset> newly_received(starting_offset,
starting_offset + size);
newly_received.Difference(bytes_received_);
diff --git a/chromium/net/quic/core/quic_stream_sequencer_test.cc b/chromium/net/quic/core/quic_stream_sequencer_test.cc
index 4ec52a03d16..3d608e4ff45 100644
--- a/chromium/net/quic/core/quic_stream_sequencer_test.cc
+++ b/chromium/net/quic/core/quic_stream_sequencer_test.cc
@@ -34,7 +34,8 @@ namespace test {
class MockStream : public QuicStream {
public:
- MockStream(QuicSession* session, QuicStreamId id) : QuicStream(id, session) {}
+ MockStream(QuicSession* session, QuicStreamId id)
+ : QuicStream(id, session, /*is_static=*/false) {}
MOCK_METHOD0(OnFinRead, void());
MOCK_METHOD0(OnDataAvailable, void());
diff --git a/chromium/net/quic/core/quic_stream_test.cc b/chromium/net/quic/core/quic_stream_test.cc
index af56b2effae..7b7d1a5429c 100644
--- a/chromium/net/quic/core/quic_stream_test.cc
+++ b/chromium/net/quic/core/quic_stream_test.cc
@@ -50,7 +50,7 @@ const bool kShouldNotProcessData = false;
class TestStream : public QuicStream {
public:
TestStream(QuicStreamId id, QuicSession* session, bool should_process_data)
- : QuicStream(id, session) {}
+ : QuicStream(id, session, /*is_static=*/false) {}
void OnDataAvailable() override {}
@@ -123,7 +123,11 @@ class QuicStreamTest : public QuicTestWithParam<bool> {
.Times(AnyNumber());
write_blocked_list_ =
QuicSessionPeer::GetWriteBlockedStreams(session_.get());
- write_blocked_list_->RegisterStream(kTestStreamId, kV3HighestPriority);
+ if (!session_->register_streams_early()) {
+ write_blocked_list_->RegisterStream(kTestStreamId,
+ /*is_static_stream=*/false,
+ kV3HighestPriority);
+ }
}
bool fin_sent() { return QuicStreamPeer::FinSent(stream_); }
@@ -134,7 +138,7 @@ class QuicStreamTest : public QuicTestWithParam<bool> {
}
bool HasWriteBlockedStreams() {
- return write_blocked_list_->HasWriteBlockedCryptoOrHeadersStream() ||
+ return write_blocked_list_->HasWriteBlockedSpecialStream() ||
write_blocked_list_->HasWriteBlockedDataStreams();
}
@@ -173,7 +177,7 @@ TEST_F(QuicStreamTest, WriteAllData) {
1 + QuicPacketCreator::StreamFramePacketOverhead(
connection_->transport_version(), PACKET_8BYTE_CONNECTION_ID,
!kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_6BYTE_PACKET_NUMBER, 0u);
+ PACKET_4BYTE_PACKET_NUMBER, 0u);
connection_->SetMaxPacketLength(length);
EXPECT_CALL(*session_, WritevData(stream_, kTestStreamId, _, _, _))
@@ -254,7 +258,7 @@ TEST_F(QuicStreamTest, WriteOrBufferData) {
1 + QuicPacketCreator::StreamFramePacketOverhead(
connection_->transport_version(), PACKET_8BYTE_CONNECTION_ID,
!kIncludeVersion, !kIncludeDiversificationNonce,
- PACKET_6BYTE_PACKET_NUMBER, 0u);
+ PACKET_4BYTE_PACKET_NUMBER, 0u);
connection_->SetMaxPacketLength(length);
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
@@ -457,13 +461,9 @@ TEST_F(QuicStreamTest, StopReadingSendsFlowControl) {
EXPECT_CALL(*connection_,
CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _))
.Times(0);
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(AtLeast(1))
- .WillRepeatedly(Invoke(this, &QuicStreamTest::ClearControlFrame));
- } else {
- EXPECT_CALL(*connection_, SendWindowUpdate(_, _)).Times(AtLeast(1));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .Times(AtLeast(1))
+ .WillRepeatedly(Invoke(this, &QuicStreamTest::ClearControlFrame));
QuicString data(1000, 'x');
for (QuicStreamOffset offset = 0;
@@ -821,7 +821,7 @@ TEST_F(QuicStreamTest, RstFrameReceivedStreamFinishSending) {
QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream_->id(),
QUIC_STREAM_CANCELLED, 1234);
stream_->OnStreamReset(rst_frame);
- // Stream stops waiting for acks as it has unacked data.
+ // Stream still waits for acks as it finishes sending and has unacked data.
EXPECT_TRUE(stream_->IsWaitingForAcks());
EXPECT_EQ(1u, QuicStreamPeer::SendBuffer(stream_).size());
}
@@ -969,9 +969,6 @@ TEST_F(QuicStreamTest, WriteMemSlices) {
set_initial_flow_control_window_bytes(500000);
Initialize(kShouldProcessData);
- if (!session_->can_use_slices()) {
- return;
- }
char data[1024];
std::vector<std::pair<char*, size_t>> buffers;
buffers.push_back(std::make_pair(data, QUIC_ARRAYSIZE(data)));
@@ -1034,9 +1031,6 @@ TEST_F(QuicStreamTest, WriteMemSlices) {
TEST_F(QuicStreamTest, WriteMemSlicesReachStreamLimit) {
SetQuicReloadableFlag(quic_stream_too_long, true);
Initialize(kShouldProcessData);
- if (!session_->can_use_slices()) {
- return;
- }
QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - 5u, stream_);
char data[5];
std::vector<std::pair<char*, size_t>> buffers;
@@ -1215,12 +1209,8 @@ TEST_F(QuicStreamTest, MarkConnectionLevelWriteBlockedOnWindowUpdateFrame) {
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(this, &QuicStreamTest::ClearControlFrame));
- } else {
- EXPECT_CALL(*connection_, SendBlocked(stream_->id()));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(this, &QuicStreamTest::ClearControlFrame));
QuicString data(1024, '.');
stream_->WriteOrBufferData(data, false, nullptr);
EXPECT_FALSE(HasWriteBlockedStreams());
@@ -1229,20 +1219,14 @@ TEST_F(QuicStreamTest, MarkConnectionLevelWriteBlockedOnWindowUpdateFrame) {
1234);
stream_->OnWindowUpdateFrame(window_update);
- if (session_->session_unblocks_stream()) {
- // Verify stream is marked connection level write blocked.
- EXPECT_TRUE(HasWriteBlockedStreams());
- EXPECT_TRUE(stream_->HasBufferedData());
- } else {
- EXPECT_FALSE(HasWriteBlockedStreams());
- EXPECT_FALSE(stream_->HasBufferedData());
- }
+ // Verify stream is marked connection level write blocked.
+ EXPECT_TRUE(HasWriteBlockedStreams());
+ EXPECT_TRUE(stream_->HasBufferedData());
}
// Regression test for b/73282665.
TEST_F(QuicStreamTest,
MarkConnectionLevelWriteBlockedOnWindowUpdateFrameWithNoBufferedData) {
- SetQuicReloadableFlag(quic_streams_unblocked_by_session2, true);
// Set a small initial flow control window size.
const uint32_t kSmallWindow = 100;
set_initial_flow_control_window_bytes(kSmallWindow);
@@ -1251,12 +1235,8 @@ TEST_F(QuicStreamTest,
QuicString data(kSmallWindow, '.');
EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
.WillRepeatedly(Invoke(MockQuicSession::ConsumeData));
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(this, &QuicStreamTest::ClearControlFrame));
- } else {
- EXPECT_CALL(*connection_, SendBlocked(stream_->id()));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(this, &QuicStreamTest::ClearControlFrame));
stream_->WriteOrBufferData(data, false, nullptr);
EXPECT_FALSE(HasWriteBlockedStreams());
diff --git a/chromium/net/quic/core/quic_types.h b/chromium/net/quic/core/quic_types.h
index d237227e047..9671b45eaed 100644
--- a/chromium/net/quic/core/quic_types.h
+++ b/chromium/net/quic/core/quic_types.h
@@ -33,6 +33,12 @@ typedef uint64_t QuicIetfStreamDataLength;
typedef uint64_t QuicIetfStreamId;
typedef uint64_t QuicIetfStreamOffset;
+const size_t kQuicPathFrameBufferSize = 8;
+typedef std::array<uint8_t, kQuicPathFrameBufferSize> QuicPathFrameBuffer;
+
+// Application error code used in the QUIC Stop Sending frame.
+typedef uint16_t QuicApplicationErrorCode;
+
// A struct for functions which consume data payloads and fins.
struct QUIC_EXPORT_PRIVATE QuicConsumedData {
QuicConsumedData(size_t bytes_consumed, bool fin_consumed);
@@ -66,9 +72,17 @@ enum QuicAsyncStatus {
enum WriteStatus {
WRITE_STATUS_OK,
WRITE_STATUS_BLOCKED,
+ // To make the IsWriteError(WriteStatus) function work properly:
+ // - Non-errors MUST be added before WRITE_STATUS_ERROR.
+ // - Errors MUST be added after WRITE_STATUS_ERROR.
WRITE_STATUS_ERROR,
+ WRITE_STATUS_MSG_TOO_BIG,
};
+inline bool IsWriteError(WriteStatus status) {
+ return status >= WRITE_STATUS_ERROR;
+}
+
// A struct used to return the result of write calls including either the number
// of bytes written or the error code, depending upon the status.
struct QUIC_EXPORT_PRIVATE WriteResult {
@@ -156,8 +170,9 @@ enum QuicIetfFrameType : int8_t {
IETF_STREAM_ID_BLOCKED = 0x0a,
IETF_NEW_CONNECTION_ID = 0x0b,
IETF_STOP_SENDING = 0x0c,
- IETF_PONG = 0x0d,
- IETF_ACK = 0x0e,
+ IETF_ACK = 0x0d,
+ IETF_PATH_CHALLENGE = 0x0e,
+ IETF_PATH_RESPONSE = 0x0f,
// the low-3 bits of the stream frame type value are actually flags
// declaring what parts of the frame are/are-not present, as well as
// some other control information. The code would then do something
diff --git a/chromium/net/quic/core/quic_unacked_packet_map.cc b/chromium/net/quic/core/quic_unacked_packet_map.cc
index 678bc5334b8..a70ac7f3b4e 100644
--- a/chromium/net/quic/core/quic_unacked_packet_map.cc
+++ b/chromium/net/quic/core/quic_unacked_packet_map.cc
@@ -17,6 +17,7 @@ QuicUnackedPacketMap::QuicUnackedPacketMap()
least_unacked_(1),
bytes_in_flight_(0),
pending_crypto_packet_count_(0),
+ last_crypto_packet_sent_time_(QuicTime::Zero()),
session_notifier_(nullptr),
session_decides_what_to_write_(false) {}
@@ -63,6 +64,7 @@ void QuicUnackedPacketMap::AddSentPacket(SerializedPacket* packet,
if (old_packet_number == 0) {
if (has_crypto_handshake) {
++pending_crypto_packet_count_;
+ last_crypto_packet_sent_time_ = sent_time;
}
packet->retransmittable_frames.swap(
@@ -302,6 +304,10 @@ QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const {
return QuicTime::Zero();
}
+QuicTime QuicUnackedPacketMap::GetLastCryptoPacketSentTime() const {
+ return last_crypto_packet_sent_time_;
+}
+
size_t QuicUnackedPacketMap::GetNumUnackedPacketsDebugOnly() const {
size_t unacked_packet_count = 0;
QuicPacketNumber packet_number = least_unacked_;
diff --git a/chromium/net/quic/core/quic_unacked_packet_map.h b/chromium/net/quic/core/quic_unacked_packet_map.h
index 0bafe98f6b1..30091975f5d 100644
--- a/chromium/net/quic/core/quic_unacked_packet_map.h
+++ b/chromium/net/quic/core/quic_unacked_packet_map.h
@@ -128,6 +128,9 @@ class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap {
// Returns the time that the last unacked packet was sent.
QuicTime GetLastPacketSentTime() const;
+ // Returns the time that the last unacked crypto packet was sent.
+ QuicTime GetLastCryptoPacketSentTime() const;
+
// Returns the number of unacked packets.
size_t GetNumUnackedPacketsDebugOnly() const;
@@ -213,6 +216,9 @@ class QUIC_EXPORT_PRIVATE QuicUnackedPacketMap {
// Number of retransmittable crypto handshake packets.
size_t pending_crypto_packet_count_;
+ // Time that the last unacked crypto packet was sent.
+ QuicTime last_crypto_packet_sent_time_;
+
// Receives notifications of frames being retransmitted or acknowledged.
SessionNotifierInterface* session_notifier_;
diff --git a/chromium/net/quic/core/quic_utils.cc b/chromium/net/quic/core/quic_utils.cc
index 49ec2198baa..c5c00e77d61 100644
--- a/chromium/net/quic/core/quic_utils.cc
+++ b/chromium/net/quic/core/quic_utils.cc
@@ -13,6 +13,7 @@
#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_prefetch.h"
#include "net/quic/platform/api/quic_string.h"
+#include "net/quic/platform/api/quic_uint128.h"
namespace net {
namespace {
@@ -27,9 +28,9 @@ namespace {
#endif
#ifdef QUIC_UTIL_HAS_UINT128
-uint128 IncrementalHashFast(uint128 uhash, QuicStringPiece data) {
+QuicUint128 IncrementalHashFast(QuicUint128 uhash, QuicStringPiece data) {
// This code ends up faster than the naive implementation for 2 reasons:
- // 1. uint128 from base/int128.h is sufficiently complicated that the compiler
+ // 1. QuicUint128 is sufficiently complicated that the compiler
// cannot transform the multiplication by kPrime into a shift-multiply-add;
// it has go through all of the instructions for a 128-bit multiply.
// 2. Because there are so fewer instructions (around 13), the hot loop fits
@@ -37,13 +38,14 @@ uint128 IncrementalHashFast(uint128 uhash, QuicStringPiece data) {
// kPrime = 309485009821345068724781371
static const __uint128_t kPrime =
(static_cast<__uint128_t>(16777216) << 64) + 315;
- __uint128_t xhash = (static_cast<__uint128_t>(Uint128High64(uhash)) << 64) +
- Uint128Low64(uhash);
+ auto hi = QuicUint128High64(uhash);
+ auto lo = QuicUint128Low64(uhash);
+ __uint128_t xhash = (static_cast<__uint128_t>(hi) << 64) + lo;
const uint8_t* octets = reinterpret_cast<const uint8_t*>(data.data());
for (size_t i = 0; i < data.length(); ++i) {
xhash = (xhash ^ octets[i]) * kPrime;
}
- return MakeUint128(
+ return MakeQuicUint128(
static_cast<uint64_t>(xhash >> 64),
static_cast<uint64_t>(xhash & UINT64_C(0xFFFFFFFFFFFFFFFF)));
}
@@ -51,19 +53,19 @@ uint128 IncrementalHashFast(uint128 uhash, QuicStringPiece data) {
#ifndef QUIC_UTIL_HAS_UINT128
// Slow implementation of IncrementalHash. In practice, only used by Chromium.
-uint128 IncrementalHashSlow(uint128 hash, QuicStringPiece data) {
+QuicUint128 IncrementalHashSlow(QuicUint128 hash, QuicStringPiece data) {
// kPrime = 309485009821345068724781371
- static const uint128 kPrime = MakeUint128(16777216, 315);
+ static const uint128 kPrime = MakeQuicUint128(16777216, 315);
const uint8_t* octets = reinterpret_cast<const uint8_t*>(data.data());
for (size_t i = 0; i < data.length(); ++i) {
- hash = hash ^ MakeUint128(0, octets[i]);
+ hash = hash ^ MakeQuicUint128(0, octets[i]);
hash = hash * kPrime;
}
return hash;
}
#endif
-uint128 IncrementalHash(uint128 hash, QuicStringPiece data) {
+QuicUint128 IncrementalHash(QuicUint128 hash, QuicStringPiece data) {
#ifdef QUIC_UTIL_HAS_UINT128
return IncrementalHashFast(hash, data);
#else
@@ -91,27 +93,27 @@ uint64_t QuicUtils::FNV1a_64_Hash(QuicStringPiece data) {
}
// static
-uint128 QuicUtils::FNV1a_128_Hash(QuicStringPiece data) {
+QuicUint128 QuicUtils::FNV1a_128_Hash(QuicStringPiece data) {
return FNV1a_128_Hash_Three(data, QuicStringPiece(), QuicStringPiece());
}
// static
-uint128 QuicUtils::FNV1a_128_Hash_Two(QuicStringPiece data1,
- QuicStringPiece data2) {
+QuicUint128 QuicUtils::FNV1a_128_Hash_Two(QuicStringPiece data1,
+ QuicStringPiece data2) {
return FNV1a_128_Hash_Three(data1, data2, QuicStringPiece());
}
// static
-uint128 QuicUtils::FNV1a_128_Hash_Three(QuicStringPiece data1,
- QuicStringPiece data2,
- QuicStringPiece data3) {
+QuicUint128 QuicUtils::FNV1a_128_Hash_Three(QuicStringPiece data1,
+ QuicStringPiece data2,
+ QuicStringPiece data3) {
// The two constants are defined as part of the hash algorithm.
// see http://www.isthe.com/chongo/tech/comp/fnv/
// kOffset = 144066263297769815596495629667062367629
- const uint128 kOffset =
- MakeUint128(UINT64_C(7809847782465536322), UINT64_C(7113472399480571277));
+ const QuicUint128 kOffset = MakeQuicUint128(UINT64_C(7809847782465536322),
+ UINT64_C(7113472399480571277));
- uint128 hash = IncrementalHash(kOffset, data1);
+ QuicUint128 hash = IncrementalHash(kOffset, data1);
if (data2.empty()) {
return hash;
}
@@ -124,9 +126,9 @@ uint128 QuicUtils::FNV1a_128_Hash_Three(QuicStringPiece data1,
}
// static
-void QuicUtils::SerializeUint128Short(uint128 v, uint8_t* out) {
- const uint64_t lo = Uint128Low64(v);
- const uint64_t hi = Uint128High64(v);
+void QuicUtils::SerializeUint128Short(QuicUint128 v, uint8_t* out) {
+ const uint64_t lo = QuicUint128Low64(v);
+ const uint64_t hi = QuicUint128High64(v);
// This assumes that the system is little-endian.
memcpy(out, &lo, sizeof(lo));
memcpy(out + sizeof(lo), &hi, sizeof(hi) / 2);
@@ -175,6 +177,21 @@ QuicString QuicUtils::AddressChangeTypeToString(AddressChangeType type) {
return "INVALID_ADDRESS_CHANGE_TYPE";
}
+const char* QuicUtils::SentPacketStateToString(SentPacketState state) {
+ switch (state) {
+ RETURN_STRING_LITERAL(OUTSTANDING);
+ RETURN_STRING_LITERAL(NEVER_SENT);
+ RETURN_STRING_LITERAL(ACKED);
+ RETURN_STRING_LITERAL(UNACKABLE);
+ RETURN_STRING_LITERAL(HANDSHAKE_RETRANSMITTED);
+ RETURN_STRING_LITERAL(LOST);
+ RETURN_STRING_LITERAL(TLP_RETRANSMITTED);
+ RETURN_STRING_LITERAL(RTO_RETRANSMITTED);
+ RETURN_STRING_LITERAL(PROBE_RETRANSMITTED);
+ }
+ return "INVALID_SENT_PACKET_STATE";
+}
+
// static
AddressChangeType QuicUtils::DetermineAddressChangeType(
const QuicSocketAddress& old_address,
diff --git a/chromium/net/quic/core/quic_utils.h b/chromium/net/quic/core/quic_utils.h
index 9790c41f727..a891beba292 100644
--- a/chromium/net/quic/core/quic_utils.h
+++ b/chromium/net/quic/core/quic_utils.h
@@ -9,7 +9,6 @@
#include <cstdint>
#include "base/macros.h"
-#include "net/base/int128.h"
#include "net/base/iovec.h"
#include "net/quic/core/quic_error_codes.h"
#include "net/quic/core/quic_types.h"
@@ -17,6 +16,7 @@
#include "net/quic/platform/api/quic_socket_address.h"
#include "net/quic/platform/api/quic_string.h"
#include "net/quic/platform/api/quic_string_piece.h"
+#include "net/quic/platform/api/quic_uint128.h"
namespace net {
@@ -28,22 +28,22 @@ class QUIC_EXPORT_PRIVATE QuicUtils {
// Returns the 128 bit FNV1a hash of the data. See
// http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
- static uint128 FNV1a_128_Hash(QuicStringPiece data);
+ static QuicUint128 FNV1a_128_Hash(QuicStringPiece data);
// Returns the 128 bit FNV1a hash of the two sequences of data. See
// http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
- static uint128 FNV1a_128_Hash_Two(QuicStringPiece data1,
- QuicStringPiece data2);
+ static QuicUint128 FNV1a_128_Hash_Two(QuicStringPiece data1,
+ QuicStringPiece data2);
// Returns the 128 bit FNV1a hash of the three sequences of data. See
// http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-param
- static uint128 FNV1a_128_Hash_Three(QuicStringPiece data1,
- QuicStringPiece data2,
- QuicStringPiece data3);
+ static QuicUint128 FNV1a_128_Hash_Three(QuicStringPiece data1,
+ QuicStringPiece data2,
+ QuicStringPiece data3);
// SerializeUint128 writes the first 96 bits of |v| in little-endian form
// to |out|.
- static void SerializeUint128Short(uint128 v, uint8_t* out);
+ static void SerializeUint128Short(QuicUint128 v, uint8_t* out);
// Returns the level of encryption as a char*
static const char* EncryptionLevelToString(EncryptionLevel level);
@@ -54,6 +54,9 @@ class QUIC_EXPORT_PRIVATE QuicUtils {
// Returns AddressChangeType as a std::string.
static QuicString AddressChangeTypeToString(AddressChangeType type);
+ // Returns SentPacketState as a char*.
+ static const char* SentPacketStateToString(SentPacketState state);
+
// Determines and returns change type of address change from |old_address| to
// |new_address|.
static AddressChangeType DetermineAddressChangeType(
diff --git a/chromium/net/quic/core/quic_utils_test.cc b/chromium/net/quic/core/quic_utils_test.cc
index a27f90f145f..c797937742c 100644
--- a/chromium/net/quic/core/quic_utils_test.cc
+++ b/chromium/net/quic/core/quic_utils_test.cc
@@ -73,17 +73,17 @@ TEST_F(QuicUtilsTest, DetermineAddressChangeType) {
QuicUtils::DetermineAddressChangeType(old_address, new_address));
}
-uint128 IncrementalHashReference(const void* data, size_t len) {
+QuicUint128 IncrementalHashReference(const void* data, size_t len) {
// The two constants are defined as part of the hash algorithm.
// see http://www.isthe.com/chongo/tech/comp/fnv/
// hash = 144066263297769815596495629667062367629
- uint128 hash =
- MakeUint128(UINT64_C(7809847782465536322), UINT64_C(7113472399480571277));
+ QuicUint128 hash = MakeQuicUint128(UINT64_C(7809847782465536322),
+ UINT64_C(7113472399480571277));
// kPrime = 309485009821345068724781371
- const uint128 kPrime = MakeUint128(16777216, 315);
+ const QuicUint128 kPrime = MakeQuicUint128(16777216, 315);
const uint8_t* octets = reinterpret_cast<const uint8_t*>(data);
for (size_t i = 0; i < len; ++i) {
- hash = hash ^ MakeUint128(0, octets[i]);
+ hash = hash ^ MakeQuicUint128(0, octets[i]);
hash = hash * kPrime;
}
return hash;
diff --git a/chromium/net/quic/core/quic_versions.cc b/chromium/net/quic/core/quic_versions.cc
index bac51f16959..f3094a1497e 100644
--- a/chromium/net/quic/core/quic_versions.cc
+++ b/chromium/net/quic/core/quic_versions.cc
@@ -25,6 +25,16 @@ QuicVersionLabel MakeVersionLabel(char a, char b, char c, char d) {
} // namespace
+ParsedQuicVersion::ParsedQuicVersion(HandshakeProtocol handshake_protocol,
+ QuicTransportVersion transport_version)
+ : handshake_protocol(handshake_protocol),
+ transport_version(transport_version) {
+ if (handshake_protocol == PROTOCOL_TLS1_3 &&
+ !FLAGS_quic_supports_tls_handshake) {
+ QUIC_BUG << "TLS use attempted when not enabled";
+ }
+}
+
std::ostream& operator<<(std::ostream& os, const ParsedQuicVersion& version) {
os << ParsedQuicVersionToString(version);
return os;
@@ -37,9 +47,6 @@ QuicVersionLabel CreateQuicVersionLabel(ParsedQuicVersion parsed_version) {
proto = 'Q';
break;
case PROTOCOL_TLS1_3:
- if (!FLAGS_quic_supports_tls_handshake) {
- QUIC_BUG << "TLS use attempted when not enabled";
- }
proto = 'T';
break;
default:
diff --git a/chromium/net/quic/core/quic_versions.h b/chromium/net/quic/core/quic_versions.h
index e2b45fece26..2f97db34a62 100644
--- a/chromium/net/quic/core/quic_versions.h
+++ b/chromium/net/quic/core/quic_versions.h
@@ -52,14 +52,12 @@ enum HandshakeProtocol {
// A parsed QUIC version label which determines that handshake protocol
// and the transport version.
-struct ParsedQuicVersion {
+struct QUIC_EXPORT_PRIVATE ParsedQuicVersion {
HandshakeProtocol handshake_protocol;
QuicTransportVersion transport_version;
ParsedQuicVersion(HandshakeProtocol handshake_protocol,
- QuicTransportVersion transport_version)
- : handshake_protocol(handshake_protocol),
- transport_version(transport_version) {}
+ QuicTransportVersion transport_version);
ParsedQuicVersion(const ParsedQuicVersion& other)
: handshake_protocol(other.handshake_protocol),
diff --git a/chromium/net/quic/core/quic_write_blocked_list.cc b/chromium/net/quic/core/quic_write_blocked_list.cc
index 32f23cf3eb9..f5e9775df80 100644
--- a/chromium/net/quic/core/quic_write_blocked_list.cc
+++ b/chromium/net/quic/core/quic_write_blocked_list.cc
@@ -4,12 +4,15 @@
#include "net/quic/core/quic_write_blocked_list.h"
+#include "net/quic/platform/api/quic_flags.h"
+
namespace net {
-QuicWriteBlockedList::QuicWriteBlockedList()
+QuicWriteBlockedList::QuicWriteBlockedList(bool register_static_streams)
: last_priority_popped_(0),
crypto_stream_blocked_(false),
- headers_stream_blocked_(false) {
+ headers_stream_blocked_(false),
+ register_static_streams_(register_static_streams) {
memset(batch_write_stream_id_, 0, sizeof(batch_write_stream_id_));
memset(bytes_left_for_batch_write_, 0, sizeof(bytes_left_for_batch_write_));
}
diff --git a/chromium/net/quic/core/quic_write_blocked_list.h b/chromium/net/quic/core/quic_write_blocked_list.h
index a2b6033d1a4..1a5b3d4b354 100644
--- a/chromium/net/quic/core/quic_write_blocked_list.h
+++ b/chromium/net/quic/core/quic_write_blocked_list.h
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "net/quic/core/quic_packets.h"
#include "net/quic/platform/api/quic_export.h"
+#include "net/quic/platform/api/quic_map_util.h"
#include "net/spdy/core/priority_write_scheduler.h"
namespace net {
@@ -23,57 +24,100 @@ class QUIC_EXPORT_PRIVATE QuicWriteBlockedList {
typedef PriorityWriteScheduler<QuicStreamId> QuicPriorityWriteScheduler;
public:
- QuicWriteBlockedList();
+ explicit QuicWriteBlockedList(bool register_static_streams);
~QuicWriteBlockedList();
bool HasWriteBlockedDataStreams() const {
return priority_write_scheduler_.HasReadyStreams();
}
- bool HasWriteBlockedCryptoOrHeadersStream() const {
+ bool HasWriteBlockedSpecialStream() const {
+ if (register_static_streams_) {
+ for (const auto& stream : static_streams_) {
+ if (stream.second) {
+ return true;
+ }
+ }
+ return false;
+ }
return crypto_stream_blocked_ || headers_stream_blocked_;
}
- size_t NumBlockedStreams() const {
- size_t num_blocked = priority_write_scheduler_.NumReadyStreams();
- if (crypto_stream_blocked_) {
- ++num_blocked;
- }
- if (headers_stream_blocked_) {
- ++num_blocked;
+ size_t NumBlockedSpecialStreams() const {
+ size_t num_blocked = 0;
+ if (register_static_streams_) {
+ for (const auto& stream : static_streams_) {
+ if (stream.second) {
+ ++num_blocked;
+ }
+ }
+ } else {
+ if (crypto_stream_blocked_) {
+ ++num_blocked;
+ }
+ if (headers_stream_blocked_) {
+ ++num_blocked;
+ }
}
-
return num_blocked;
}
+ size_t NumBlockedStreams() const {
+ return NumBlockedSpecialStreams() +
+ priority_write_scheduler_.NumReadyStreams();
+ }
+
bool ShouldYield(QuicStreamId id) const {
- if (id == kCryptoStreamId) {
- return false; // The crypto stream yields to none.
- }
- if (crypto_stream_blocked_) {
- return true; // If the crypto stream is blocked, all other streams yield.
- }
- if (id == kHeadersStreamId) {
- return false; // The crypto stream isn't blocked so headers won't yield.
+ if (register_static_streams_) {
+ for (const auto& stream : static_streams_) {
+ if (stream.first == id) {
+ // Static streams should never yield to data streams, or to lower
+ // priority static stream.
+ return false;
+ }
+ if (stream.second) {
+ return true; // All data streams yield to static streams.
+ }
+ }
+ } else {
+ if (id == kCryptoStreamId) {
+ return false; // The crypto stream yields to none.
+ }
+ if (crypto_stream_blocked_) {
+ return true; // If the crypto stream is blocked, all other streams
+ // yield.
+ }
+ if (id == kHeadersStreamId) {
+ return false; // The crypto stream isn't blocked so headers won't
+ // yield.
+ }
+ if (headers_stream_blocked_) {
+ return true; // All data streams yield to the headers stream.
+ }
}
- if (headers_stream_blocked_) {
- return true; // All data streams yield to the headers stream.
- }
-
return priority_write_scheduler_.ShouldYield(id);
}
// Pops the highest priorty stream, special casing crypto and headers streams.
// Latches the most recently popped data stream for batch writing purposes.
QuicStreamId PopFront() {
- if (crypto_stream_blocked_) {
- crypto_stream_blocked_ = false;
- return kCryptoStreamId;
- }
-
- if (headers_stream_blocked_) {
- headers_stream_blocked_ = false;
- return kHeadersStreamId;
+ if (register_static_streams_) {
+ for (auto& stream : static_streams_) {
+ if (stream.second) {
+ stream.second = false;
+ return stream.first;
+ }
+ }
+ } else {
+ if (crypto_stream_blocked_) {
+ crypto_stream_blocked_ = false;
+ return kCryptoStreamId;
+ }
+
+ if (headers_stream_blocked_) {
+ headers_stream_blocked_ = false;
+ return kHeadersStreamId;
+ }
}
const auto id_and_precedence =
@@ -97,16 +141,34 @@ class QUIC_EXPORT_PRIVATE QuicWriteBlockedList {
return id;
}
- void RegisterStream(QuicStreamId stream_id, SpdyPriority priority) {
+ void RegisterStream(QuicStreamId stream_id,
+ bool is_static_stream,
+ SpdyPriority priority) {
+ if (register_static_streams_ && is_static_stream) {
+ DCHECK(!priority_write_scheduler_.StreamRegistered(stream_id));
+ DCHECK(!QuicContainsKey(static_streams_, stream_id));
+ DCHECK(static_streams_.empty() ||
+ stream_id > static_streams_.back().first)
+ << "stream_id: " << stream_id
+ << " last static stream: " << static_streams_.back().first;
+ static_streams_[stream_id] = false;
+ return;
+ }
+ DCHECK(!priority_write_scheduler_.StreamRegistered(stream_id));
priority_write_scheduler_.RegisterStream(stream_id,
SpdyStreamPrecedence(priority));
}
- void UnregisterStream(QuicStreamId stream_id) {
+ void UnregisterStream(QuicStreamId stream_id, bool is_static) {
+ if (register_static_streams_ && is_static) {
+ static_streams_.erase(stream_id);
+ return;
+ }
priority_write_scheduler_.UnregisterStream(stream_id);
}
void UpdateStreamPriority(QuicStreamId stream_id, SpdyPriority new_priority) {
+ DCHECK(!QuicContainsKey(static_streams_, stream_id));
priority_write_scheduler_.UpdateStreamPrecedence(
stream_id, SpdyStreamPrecedence(new_priority));
}
@@ -125,16 +187,24 @@ class QUIC_EXPORT_PRIVATE QuicWriteBlockedList {
// the list for its priority level.
// Headers and crypto streams are special cased to always resume first.
void AddStream(QuicStreamId stream_id) {
- if (stream_id == kCryptoStreamId) {
- // TODO(avd) Add DCHECK(!crypto_stream_blocked_)
- crypto_stream_blocked_ = true;
- return;
- }
-
- if (stream_id == kHeadersStreamId) {
- // TODO(avd) Add DCHECK(!headers_stream_blocked_);
- headers_stream_blocked_ = true;
- return;
+ if (register_static_streams_) {
+ auto it = static_streams_.find(stream_id);
+ if (it != static_streams_.end()) {
+ it->second = true;
+ return;
+ }
+ } else {
+ if (stream_id == kCryptoStreamId) {
+ // TODO(avd) Add DCHECK(!crypto_stream_blocked_)
+ crypto_stream_blocked_ = true;
+ return;
+ }
+
+ if (stream_id == kHeadersStreamId) {
+ // TODO(avd) Add DCHECK(!headers_stream_blocked_);
+ headers_stream_blocked_ = true;
+ return;
+ }
}
bool push_front =
stream_id == batch_write_stream_id_[last_priority_popped_] &&
@@ -145,19 +215,25 @@ class QUIC_EXPORT_PRIVATE QuicWriteBlockedList {
// This function is used for debugging and test only. Returns true if stream
// with |stream_id| is write blocked.
bool IsStreamBlocked(QuicStreamId stream_id) const {
- if (stream_id == kCryptoStreamId) {
- return crypto_stream_blocked_;
- }
-
- if (stream_id == kHeadersStreamId) {
- return headers_stream_blocked_;
+ if (register_static_streams_) {
+ auto it = static_streams_.find(stream_id);
+ if (it != static_streams_.end()) {
+ return it->second;
+ }
+ } else {
+ if (stream_id == kCryptoStreamId) {
+ return crypto_stream_blocked_;
+ }
+
+ if (stream_id == kHeadersStreamId) {
+ return headers_stream_blocked_;
+ }
}
return priority_write_scheduler_.IsStreamReady(stream_id);
}
- bool crypto_stream_blocked() const { return crypto_stream_blocked_; }
- bool headers_stream_blocked() const { return headers_stream_blocked_; }
+ bool register_static_streams() const { return register_static_streams_; }
private:
QuicPriorityWriteScheduler priority_write_scheduler_;
@@ -177,6 +253,10 @@ class QUIC_EXPORT_PRIVATE QuicWriteBlockedList {
bool crypto_stream_blocked_;
bool headers_stream_blocked_;
+ // Latched value of quic_reloadable_flag_quic_register_static_streams.
+ const bool register_static_streams_;
+ QuicLinkedHashMapImpl<QuicStreamId, bool> static_streams_;
+
DISALLOW_COPY_AND_ASSIGN(QuicWriteBlockedList);
};
diff --git a/chromium/net/quic/core/quic_write_blocked_list_test.cc b/chromium/net/quic/core/quic_write_blocked_list_test.cc
index 91d0313b3ff..44da95eeb37 100644
--- a/chromium/net/quic/core/quic_write_blocked_list_test.cc
+++ b/chromium/net/quic/core/quic_write_blocked_list_test.cc
@@ -7,25 +7,27 @@
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/quic_test_utils.h"
-using net::kV3LowestPriority;
-using net::kV3HighestPriority;
+// using kV3HighestPriority;
+// using kV3LowestPriority;
namespace net {
namespace test {
namespace {
-class QuicWriteBlockedListTest : public QuicTest {};
+class QuicWriteBlockedListTest : public QuicTestWithParam<bool> {};
-TEST_F(QuicWriteBlockedListTest, PriorityOrder) {
- QuicWriteBlockedList write_blocked_list;
+INSTANTIATE_TEST_CASE_P(Tests, QuicWriteBlockedListTest, testing::Bool());
+
+TEST_P(QuicWriteBlockedListTest, PriorityOrder) {
+ QuicWriteBlockedList write_blocked_list(GetParam());
// Mark streams blocked in roughly reverse priority order, and
// verify that streams are sorted.
- write_blocked_list.RegisterStream(40, kV3LowestPriority);
- write_blocked_list.RegisterStream(23, kV3HighestPriority);
- write_blocked_list.RegisterStream(17, kV3HighestPriority);
- write_blocked_list.RegisterStream(kHeadersStreamId, kV3HighestPriority);
- write_blocked_list.RegisterStream(kCryptoStreamId, kV3HighestPriority);
+ write_blocked_list.RegisterStream(40, false, kV3LowestPriority);
+ write_blocked_list.RegisterStream(23, false, kV3HighestPriority);
+ write_blocked_list.RegisterStream(17, false, kV3HighestPriority);
+ write_blocked_list.RegisterStream(kCryptoStreamId, true, kV3HighestPriority);
+ write_blocked_list.RegisterStream(kHeadersStreamId, true, kV3HighestPriority);
write_blocked_list.AddStream(40);
EXPECT_TRUE(write_blocked_list.IsStreamBlocked(40));
@@ -39,13 +41,16 @@ TEST_F(QuicWriteBlockedListTest, PriorityOrder) {
EXPECT_TRUE(write_blocked_list.IsStreamBlocked(kCryptoStreamId));
EXPECT_EQ(5u, write_blocked_list.NumBlockedStreams());
- EXPECT_TRUE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
+ EXPECT_TRUE(write_blocked_list.HasWriteBlockedSpecialStream());
+ EXPECT_EQ(2u, write_blocked_list.NumBlockedSpecialStreams());
EXPECT_TRUE(write_blocked_list.HasWriteBlockedDataStreams());
// The Crypto stream is highest priority.
EXPECT_EQ(kCryptoStreamId, write_blocked_list.PopFront());
+ EXPECT_EQ(1u, write_blocked_list.NumBlockedSpecialStreams());
EXPECT_FALSE(write_blocked_list.IsStreamBlocked(kCryptoStreamId));
// Followed by the Headers stream.
EXPECT_EQ(kHeadersStreamId, write_blocked_list.PopFront());
+ EXPECT_EQ(0u, write_blocked_list.NumBlockedSpecialStreams());
EXPECT_FALSE(write_blocked_list.IsStreamBlocked(kHeadersStreamId));
// Streams with same priority are popped in the order they were inserted.
EXPECT_EQ(23u, write_blocked_list.PopFront());
@@ -57,61 +62,61 @@ TEST_F(QuicWriteBlockedListTest, PriorityOrder) {
EXPECT_FALSE(write_blocked_list.IsStreamBlocked(40));
EXPECT_EQ(0u, write_blocked_list.NumBlockedStreams());
- EXPECT_FALSE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
+ EXPECT_FALSE(write_blocked_list.HasWriteBlockedSpecialStream());
EXPECT_FALSE(write_blocked_list.HasWriteBlockedDataStreams());
}
-TEST_F(QuicWriteBlockedListTest, CryptoStream) {
- QuicWriteBlockedList write_blocked_list;
- write_blocked_list.RegisterStream(kCryptoStreamId, kV3HighestPriority);
+TEST_P(QuicWriteBlockedListTest, CryptoStream) {
+ QuicWriteBlockedList write_blocked_list(GetParam());
+ write_blocked_list.RegisterStream(kCryptoStreamId, true, kV3HighestPriority);
write_blocked_list.AddStream(kCryptoStreamId);
EXPECT_EQ(1u, write_blocked_list.NumBlockedStreams());
- EXPECT_TRUE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
+ EXPECT_TRUE(write_blocked_list.HasWriteBlockedSpecialStream());
EXPECT_EQ(kCryptoStreamId, write_blocked_list.PopFront());
EXPECT_EQ(0u, write_blocked_list.NumBlockedStreams());
- EXPECT_FALSE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
+ EXPECT_FALSE(write_blocked_list.HasWriteBlockedSpecialStream());
}
-TEST_F(QuicWriteBlockedListTest, HeadersStream) {
- QuicWriteBlockedList write_blocked_list;
- write_blocked_list.RegisterStream(kHeadersStreamId, kV3HighestPriority);
+TEST_P(QuicWriteBlockedListTest, HeadersStream) {
+ QuicWriteBlockedList write_blocked_list(GetParam());
+ write_blocked_list.RegisterStream(kHeadersStreamId, true, kV3HighestPriority);
write_blocked_list.AddStream(kHeadersStreamId);
EXPECT_EQ(1u, write_blocked_list.NumBlockedStreams());
- EXPECT_TRUE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
+ EXPECT_TRUE(write_blocked_list.HasWriteBlockedSpecialStream());
EXPECT_EQ(kHeadersStreamId, write_blocked_list.PopFront());
EXPECT_EQ(0u, write_blocked_list.NumBlockedStreams());
- EXPECT_FALSE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
+ EXPECT_FALSE(write_blocked_list.HasWriteBlockedSpecialStream());
}
-TEST_F(QuicWriteBlockedListTest, VerifyHeadersStream) {
- QuicWriteBlockedList write_blocked_list;
- write_blocked_list.RegisterStream(5, kV3HighestPriority);
- write_blocked_list.RegisterStream(kHeadersStreamId, kV3HighestPriority);
+TEST_P(QuicWriteBlockedListTest, VerifyHeadersStream) {
+ QuicWriteBlockedList write_blocked_list(GetParam());
+ write_blocked_list.RegisterStream(5, false, kV3HighestPriority);
+ write_blocked_list.RegisterStream(kHeadersStreamId, true, kV3HighestPriority);
write_blocked_list.AddStream(5);
write_blocked_list.AddStream(kHeadersStreamId);
EXPECT_EQ(2u, write_blocked_list.NumBlockedStreams());
- EXPECT_TRUE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
+ EXPECT_TRUE(write_blocked_list.HasWriteBlockedSpecialStream());
EXPECT_TRUE(write_blocked_list.HasWriteBlockedDataStreams());
// In newer QUIC versions, there is a headers stream which is
// higher priority than data streams.
EXPECT_EQ(kHeadersStreamId, write_blocked_list.PopFront());
EXPECT_EQ(5u, write_blocked_list.PopFront());
EXPECT_EQ(0u, write_blocked_list.NumBlockedStreams());
- EXPECT_FALSE(write_blocked_list.HasWriteBlockedCryptoOrHeadersStream());
+ EXPECT_FALSE(write_blocked_list.HasWriteBlockedSpecialStream());
EXPECT_FALSE(write_blocked_list.HasWriteBlockedDataStreams());
}
-TEST_F(QuicWriteBlockedListTest, NoDuplicateEntries) {
+TEST_P(QuicWriteBlockedListTest, NoDuplicateEntries) {
// Test that QuicWriteBlockedList doesn't allow duplicate entries.
- QuicWriteBlockedList write_blocked_list;
+ QuicWriteBlockedList write_blocked_list(GetParam());
// Try to add a stream to the write blocked list multiple times at the same
// priority.
const QuicStreamId kBlockedId = kHeadersStreamId + 2;
- write_blocked_list.RegisterStream(kBlockedId, kV3HighestPriority);
+ write_blocked_list.RegisterStream(kBlockedId, false, kV3HighestPriority);
write_blocked_list.AddStream(kBlockedId);
write_blocked_list.AddStream(kBlockedId);
write_blocked_list.AddStream(kBlockedId);
@@ -126,15 +131,15 @@ TEST_F(QuicWriteBlockedListTest, NoDuplicateEntries) {
EXPECT_FALSE(write_blocked_list.HasWriteBlockedDataStreams());
}
-TEST_F(QuicWriteBlockedListTest, BatchingWrites) {
- QuicWriteBlockedList write_blocked_list;
+TEST_P(QuicWriteBlockedListTest, BatchingWrites) {
+ QuicWriteBlockedList write_blocked_list(GetParam());
const QuicStreamId id1 = kHeadersStreamId + 2;
const QuicStreamId id2 = id1 + 2;
const QuicStreamId id3 = id2 + 2;
- write_blocked_list.RegisterStream(id1, kV3LowestPriority);
- write_blocked_list.RegisterStream(id2, kV3LowestPriority);
- write_blocked_list.RegisterStream(id3, kV3HighestPriority);
+ write_blocked_list.RegisterStream(id1, false, kV3LowestPriority);
+ write_blocked_list.RegisterStream(id2, false, kV3LowestPriority);
+ write_blocked_list.RegisterStream(id3, false, kV3HighestPriority);
write_blocked_list.AddStream(id1);
write_blocked_list.AddStream(id2);
@@ -179,16 +184,16 @@ TEST_F(QuicWriteBlockedListTest, BatchingWrites) {
EXPECT_EQ(id1, write_blocked_list.PopFront());
}
-TEST_F(QuicWriteBlockedListTest, Ceding) {
- QuicWriteBlockedList write_blocked_list;
+TEST_P(QuicWriteBlockedListTest, Ceding) {
+ QuicWriteBlockedList write_blocked_list(GetParam());
- write_blocked_list.RegisterStream(15, kV3HighestPriority);
- write_blocked_list.RegisterStream(16, kV3HighestPriority);
- write_blocked_list.RegisterStream(5, 5);
- write_blocked_list.RegisterStream(4, 5);
- write_blocked_list.RegisterStream(7, 7);
- write_blocked_list.RegisterStream(kHeadersStreamId, kV3HighestPriority);
- write_blocked_list.RegisterStream(kCryptoStreamId, kV3HighestPriority);
+ write_blocked_list.RegisterStream(15, false, kV3HighestPriority);
+ write_blocked_list.RegisterStream(16, false, kV3HighestPriority);
+ write_blocked_list.RegisterStream(5, false, 5);
+ write_blocked_list.RegisterStream(4, false, 5);
+ write_blocked_list.RegisterStream(7, false, 7);
+ write_blocked_list.RegisterStream(kCryptoStreamId, true, kV3HighestPriority);
+ write_blocked_list.RegisterStream(kHeadersStreamId, true, kV3HighestPriority);
// When nothing is on the list, nothing yields.
EXPECT_FALSE(write_blocked_list.ShouldYield(5));
diff --git a/chromium/net/quic/core/tls_client_handshaker.cc b/chromium/net/quic/core/tls_client_handshaker.cc
index 76bf14622ff..eb5c40d5985 100644
--- a/chromium/net/quic/core/tls_client_handshaker.cc
+++ b/chromium/net/quic/core/tls_client_handshaker.cc
@@ -60,6 +60,13 @@ bssl::UniquePtr<SSL_CTX> TlsClientHandshaker::CreateSslCtx() {
}
bool TlsClientHandshaker::CryptoConnect() {
+ CrypterPair crypters;
+ CryptoUtils::CreateTlsInitialCrypters(Perspective::IS_CLIENT,
+ session()->connection_id(), &crypters);
+ session()->connection()->SetEncrypter(ENCRYPTION_NONE,
+ std::move(crypters.encrypter));
+ session()->connection()->SetDecrypter(ENCRYPTION_NONE,
+ std::move(crypters.decrypter));
state_ = STATE_HANDSHAKE_RUNNING;
// Configure certificate verification.
// TODO(nharper): This only verifies certs on initial connection, not on
@@ -180,16 +187,21 @@ void TlsClientHandshaker::FinishHandshake() {
}
QUIC_LOG(INFO) << "Client: setting crypters";
- QuicEncrypter* initial_encrypter = CreateEncrypter(client_secret);
- session()->connection()->SetEncrypter(ENCRYPTION_INITIAL, initial_encrypter);
- QuicEncrypter* encrypter = CreateEncrypter(client_secret);
- session()->connection()->SetEncrypter(ENCRYPTION_FORWARD_SECURE, encrypter);
-
- QuicDecrypter* initial_decrypter = CreateDecrypter(server_secret);
- session()->connection()->SetDecrypter(ENCRYPTION_INITIAL, initial_decrypter);
- QuicDecrypter* decrypter = CreateDecrypter(server_secret);
+ std::unique_ptr<QuicEncrypter> initial_encrypter =
+ CreateEncrypter(client_secret);
+ session()->connection()->SetEncrypter(ENCRYPTION_INITIAL,
+ std::move(initial_encrypter));
+ std::unique_ptr<QuicEncrypter> encrypter = CreateEncrypter(client_secret);
+ session()->connection()->SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+ std::move(encrypter));
+
+ std::unique_ptr<QuicDecrypter> initial_decrypter =
+ CreateDecrypter(server_secret);
+ session()->connection()->SetDecrypter(ENCRYPTION_INITIAL,
+ std::move(initial_decrypter));
+ std::unique_ptr<QuicDecrypter> decrypter = CreateDecrypter(server_secret);
session()->connection()->SetAlternativeDecrypter(ENCRYPTION_FORWARD_SECURE,
- decrypter, true);
+ std::move(decrypter), true);
session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
diff --git a/chromium/net/quic/core/tls_handshaker.cc b/chromium/net/quic/core/tls_handshaker.cc
index 06b95ec5090..032dece493f 100644
--- a/chromium/net/quic/core/tls_handshaker.cc
+++ b/chromium/net/quic/core/tls_handshaker.cc
@@ -7,8 +7,8 @@
#include "base/no_destructor.h"
#include "net/quic/core/quic_crypto_stream.h"
#include "net/quic/core/tls_client_handshaker.h"
-#include "net/quic/core/tls_server_handshaker.h"
#include "net/quic/platform/api/quic_arraysize.h"
+#include "net/quic/platform/api/quic_singleton.h"
namespace net {
@@ -23,9 +23,8 @@ namespace {
class SslIndexSingleton {
public:
- static const SslIndexSingleton* GetInstance() {
- static const base::NoDestructor<SslIndexSingleton> instance;
- return instance.get();
+ static SslIndexSingleton* GetInstance() {
+ return QuicSingleton<SslIndexSingleton>::get();
}
int HandshakerIndex() const { return ssl_ex_data_index_handshaker_; }
@@ -37,7 +36,7 @@ class SslIndexSingleton {
CHECK_LE(0, ssl_ex_data_index_handshaker_);
}
- friend class base::NoDestructor<SslIndexSingleton>;
+ friend QuicSingletonFriend<SslIndexSingleton>;
int ssl_ex_data_index_handshaker_;
@@ -70,37 +69,21 @@ bool TlsHandshaker::DeriveSecrets(std::vector<uint8_t>* client_secret_out,
QUIC_ARRAYSIZE(kServerLabel) - 1, nullptr, 0, 0) == 1);
}
-namespace {
-
-template <class QuicCrypter>
-void SetKeyAndIV(const EVP_MD* prf,
- const std::vector<uint8_t>& pp_secret,
- QuicCrypter* crypter) {
- std::vector<uint8_t> key = CryptoUtils::HkdfExpandLabel(
- prf, pp_secret, "key", crypter->GetKeySize());
- std::vector<uint8_t> iv =
- CryptoUtils::HkdfExpandLabel(prf, pp_secret, "iv", crypter->GetIVSize());
- crypter->SetKey(
- QuicStringPiece(reinterpret_cast<char*>(key.data()), key.size()));
- crypter->SetIV(
- QuicStringPiece(reinterpret_cast<char*>(iv.data()), iv.size()));
-}
-
-} // namespace
-
-QuicEncrypter* TlsHandshaker::CreateEncrypter(
+std::unique_ptr<QuicEncrypter> TlsHandshaker::CreateEncrypter(
const std::vector<uint8_t>& pp_secret) {
- QuicEncrypter* encrypter = QuicEncrypter::CreateFromCipherSuite(
- SSL_CIPHER_get_id(SSL_get_current_cipher(ssl())));
- SetKeyAndIV(Prf(), pp_secret, encrypter);
+ std::unique_ptr<QuicEncrypter> encrypter =
+ QuicEncrypter::CreateFromCipherSuite(
+ SSL_CIPHER_get_id(SSL_get_current_cipher(ssl())));
+ CryptoUtils::SetKeyAndIV(Prf(), pp_secret, encrypter.get());
return encrypter;
}
-QuicDecrypter* TlsHandshaker::CreateDecrypter(
+std::unique_ptr<QuicDecrypter> TlsHandshaker::CreateDecrypter(
const std::vector<uint8_t>& pp_secret) {
- QuicDecrypter* decrypter = QuicDecrypter::CreateFromCipherSuite(
- SSL_CIPHER_get_id(SSL_get_current_cipher(ssl())));
- SetKeyAndIV(Prf(), pp_secret, decrypter);
+ std::unique_ptr<QuicDecrypter> decrypter =
+ QuicDecrypter::CreateFromCipherSuite(
+ SSL_CIPHER_get_id(SSL_get_current_cipher(ssl())));
+ CryptoUtils::SetKeyAndIV(Prf(), pp_secret, decrypter.get());
return decrypter;
}
diff --git a/chromium/net/quic/core/tls_handshaker.h b/chromium/net/quic/core/tls_handshaker.h
index c542be36aff..963f129f953 100644
--- a/chromium/net/quic/core/tls_handshaker.h
+++ b/chromium/net/quic/core/tls_handshaker.h
@@ -65,8 +65,10 @@ class QUIC_EXPORT_PRIVATE TlsHandshaker : public QuicTlsAdapter::Visitor {
bool DeriveSecrets(std::vector<uint8_t>* client_secret_out,
std::vector<uint8_t>* server_secret_out);
- QuicEncrypter* CreateEncrypter(const std::vector<uint8_t>& pp_secret);
- QuicDecrypter* CreateDecrypter(const std::vector<uint8_t>& pp_secret);
+ std::unique_ptr<QuicEncrypter> CreateEncrypter(
+ const std::vector<uint8_t>& pp_secret);
+ std::unique_ptr<QuicDecrypter> CreateDecrypter(
+ const std::vector<uint8_t>& pp_secret);
SSL* ssl() { return ssl_.get(); }
QuicCryptoStream* stream() { return stream_; }
diff --git a/chromium/net/quic/core/tls_handshaker_test.cc b/chromium/net/quic/core/tls_handshaker_test.cc
index 27821c30999..de84861321d 100644
--- a/chromium/net/quic/core/tls_handshaker_test.cc
+++ b/chromium/net/quic/core/tls_handshaker_test.cc
@@ -251,13 +251,15 @@ class TlsHandshakerTest : public QuicTest {
server_conn_(new MockQuicConnection(&conn_helper_,
&alarm_factory_,
Perspective::IS_SERVER)),
- client_session_(client_conn_),
- server_session_(server_conn_),
- client_stream_(&client_session_),
- server_stream_(
- new TestQuicCryptoServerStream(&server_session_, &proof_source_)) {
- EXPECT_FALSE(client_stream_.encryption_established());
- EXPECT_FALSE(client_stream_.handshake_confirmed());
+ client_session_(client_conn_, /*create_mock_crypto_stream=*/false),
+ server_session_(server_conn_, /*create_mock_crypto_stream=*/false) {
+ client_stream_ = new TestQuicCryptoClientStream(&client_session_);
+ client_session_.SetCryptoStream(client_stream_);
+ server_stream_ =
+ new TestQuicCryptoServerStream(&server_session_, &proof_source_);
+ server_session_.SetCryptoStream(server_stream_);
+ EXPECT_FALSE(client_stream_->encryption_established());
+ EXPECT_FALSE(client_stream_->handshake_confirmed());
EXPECT_FALSE(server_stream_->encryption_established());
EXPECT_FALSE(server_stream_->handshake_confirmed());
}
@@ -269,19 +271,19 @@ class TlsHandshakerTest : public QuicTest {
MockQuicSession client_session_;
MockQuicSession server_session_;
- TestQuicCryptoClientStream client_stream_;
FakeProofSource proof_source_;
- std::unique_ptr<TestQuicCryptoServerStream> server_stream_;
+ TestQuicCryptoClientStream* client_stream_;
+ TestQuicCryptoServerStream* server_stream_;
};
TEST_F(TlsHandshakerTest, CryptoHandshake) {
EXPECT_CALL(*client_conn_, CloseConnection(_, _, _)).Times(0);
EXPECT_CALL(*server_conn_, CloseConnection(_, _, _)).Times(0);
- client_stream_.CryptoConnect();
- MoveStreamFrames(&client_stream_, server_stream_.get());
+ client_stream_->CryptoConnect();
+ MoveStreamFrames(client_stream_, server_stream_);
- EXPECT_TRUE(client_stream_.handshake_confirmed());
- EXPECT_TRUE(client_stream_.encryption_established());
+ EXPECT_TRUE(client_stream_->handshake_confirmed());
+ EXPECT_TRUE(client_stream_->encryption_established());
EXPECT_TRUE(server_stream_->handshake_confirmed());
EXPECT_TRUE(server_stream_->encryption_established());
}
@@ -295,16 +297,16 @@ TEST_F(TlsHandshakerTest, HandshakeWithAsyncProofSource) {
proof_source->Activate();
// Start handshake.
- client_stream_.CryptoConnect();
- MoveStreamFrames(&client_stream_, server_stream_.get());
+ client_stream_->CryptoConnect();
+ MoveStreamFrames(client_stream_, server_stream_);
ASSERT_EQ(proof_source->NumPendingCallbacks(), 1);
proof_source->InvokePendingCallback(0);
- MoveStreamFrames(&client_stream_, server_stream_.get());
+ MoveStreamFrames(client_stream_, server_stream_);
- EXPECT_TRUE(client_stream_.handshake_confirmed());
- EXPECT_TRUE(client_stream_.encryption_established());
+ EXPECT_TRUE(client_stream_->handshake_confirmed());
+ EXPECT_TRUE(client_stream_->encryption_established());
EXPECT_TRUE(server_stream_->handshake_confirmed());
EXPECT_TRUE(server_stream_->encryption_established());
}
@@ -318,11 +320,11 @@ TEST_F(TlsHandshakerTest, CancelPendingProofSource) {
proof_source->Activate();
// Start handshake.
- client_stream_.CryptoConnect();
- MoveStreamFrames(&client_stream_, server_stream_.get());
+ client_stream_->CryptoConnect();
+ MoveStreamFrames(client_stream_, server_stream_);
ASSERT_EQ(proof_source->NumPendingCallbacks(), 1);
- server_stream_.reset();
+ server_stream_ = nullptr;
proof_source->InvokePendingCallback(0);
}
@@ -332,27 +334,27 @@ TEST_F(TlsHandshakerTest, HandshakeWithAsyncProofVerifier) {
EXPECT_CALL(*server_conn_, CloseConnection(_, _, _)).Times(0);
// Enable FakeProofVerifier to capture call to VerifyCertChain and run it
// asynchronously.
- FakeProofVerifier* proof_verifier = client_stream_.GetFakeProofVerifier();
+ FakeProofVerifier* proof_verifier = client_stream_->GetFakeProofVerifier();
proof_verifier->Activate();
// Start handshake.
- client_stream_.CryptoConnect();
- MoveStreamFrames(&client_stream_, server_stream_.get());
+ client_stream_->CryptoConnect();
+ MoveStreamFrames(client_stream_, server_stream_);
ASSERT_EQ(proof_verifier->NumPendingCallbacks(), 1u);
proof_verifier->InvokePendingCallback(0);
- MoveStreamFrames(&client_stream_, server_stream_.get());
+ MoveStreamFrames(client_stream_, server_stream_);
- EXPECT_TRUE(client_stream_.handshake_confirmed());
- EXPECT_TRUE(client_stream_.encryption_established());
+ EXPECT_TRUE(client_stream_->handshake_confirmed());
+ EXPECT_TRUE(client_stream_->encryption_established());
EXPECT_TRUE(server_stream_->handshake_confirmed());
EXPECT_TRUE(server_stream_->encryption_established());
}
TEST_F(TlsHandshakerTest, ClientConnectionClosedOnTlsAlert) {
// Have client send ClientHello.
- client_stream_.CryptoConnect();
+ client_stream_->CryptoConnect();
EXPECT_CALL(*client_conn_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
// Send fake "internal_error" fatal TLS alert from server to client.
@@ -366,11 +368,11 @@ TEST_F(TlsHandshakerTest, ClientConnectionClosedOnTlsAlert) {
80, // AlertDescription internal_error
};
QuicStreamFrame alert(kCryptoStreamId, false,
- client_stream_.stream_bytes_read(),
+ client_stream_->stream_bytes_read(),
QuicStringPiece(alert_msg, QUIC_ARRAYSIZE(alert_msg)));
- client_stream_.OnStreamFrame(alert);
+ client_stream_->OnStreamFrame(alert);
- EXPECT_FALSE(client_stream_.handshake_confirmed());
+ EXPECT_FALSE(client_stream_->handshake_confirmed());
}
TEST_F(TlsHandshakerTest, ServerConnectionClosedOnTlsAlert) {
diff --git a/chromium/net/quic/core/tls_server_handshaker.cc b/chromium/net/quic/core/tls_server_handshaker.cc
index f0f6a4e5fbc..17db9f02f47 100644
--- a/chromium/net/quic/core/tls_server_handshaker.cc
+++ b/chromium/net/quic/core/tls_server_handshaker.cc
@@ -60,6 +60,13 @@ TlsServerHandshaker::TlsServerHandshaker(QuicCryptoStream* stream,
: TlsHandshaker(stream, session, ssl_ctx),
proof_source_(proof_source),
crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {
+ CrypterPair crypters;
+ CryptoUtils::CreateTlsInitialCrypters(Perspective::IS_SERVER,
+ session->connection_id(), &crypters);
+ session->connection()->SetEncrypter(ENCRYPTION_NONE,
+ std::move(crypters.encrypter));
+ session->connection()->SetDecrypter(ENCRYPTION_NONE,
+ std::move(crypters.decrypter));
// Set callback to provide SNI.
// SSL_CTX_set_tlsext_servername_callback(ssl_ctx, SelectCertificateCallback);
@@ -195,16 +202,21 @@ void TlsServerHandshaker::FinishHandshake() {
}
QUIC_LOG(INFO) << "Server: setting crypters";
- QuicEncrypter* initial_encrypter = CreateEncrypter(server_secret);
- session()->connection()->SetEncrypter(ENCRYPTION_INITIAL, initial_encrypter);
- QuicEncrypter* encrypter = CreateEncrypter(server_secret);
- session()->connection()->SetEncrypter(ENCRYPTION_FORWARD_SECURE, encrypter);
-
- QuicDecrypter* initial_decrypter = CreateDecrypter(client_secret);
- session()->connection()->SetDecrypter(ENCRYPTION_INITIAL, initial_decrypter);
- QuicDecrypter* decrypter = CreateDecrypter(client_secret);
+ std::unique_ptr<QuicEncrypter> initial_encrypter =
+ CreateEncrypter(server_secret);
+ session()->connection()->SetEncrypter(ENCRYPTION_INITIAL,
+ std::move(initial_encrypter));
+ std::unique_ptr<QuicEncrypter> encrypter = CreateEncrypter(server_secret);
+ session()->connection()->SetEncrypter(ENCRYPTION_FORWARD_SECURE,
+ std::move(encrypter));
+
+ std::unique_ptr<QuicDecrypter> initial_decrypter =
+ CreateDecrypter(client_secret);
+ session()->connection()->SetDecrypter(ENCRYPTION_INITIAL,
+ std::move(initial_decrypter));
+ std::unique_ptr<QuicDecrypter> decrypter = CreateDecrypter(client_secret);
session()->connection()->SetAlternativeDecrypter(ENCRYPTION_FORWARD_SECURE,
- decrypter, true);
+ std::move(decrypter), true);
session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
diff --git a/chromium/net/quic/http/decoder/quic_http_frame_decoder_adapter.cc b/chromium/net/quic/http/decoder/quic_http_frame_decoder_adapter.cc
index 7bbfc68e9c3..6f70e0c9c71 100644
--- a/chromium/net/quic/http/decoder/quic_http_frame_decoder_adapter.cc
+++ b/chromium/net/quic/http/decoder/quic_http_frame_decoder_adapter.cc
@@ -22,6 +22,7 @@
#include "net/quic/http/decoder/quic_http_frame_decoder_listener.h"
#include "net/quic/http/quic_http_constants.h"
#include "net/quic/http/quic_http_structures.h"
+#include "net/quic/platform/api/quic_flags.h"
#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/platform/api/quic_string_utils.h"
#include "net/spdy/core/hpack/hpack_decoder_adapter.h"
@@ -450,7 +451,13 @@ void QuicHttpDecoderAdapter::OnSetting(
}
return;
}
- visitor()->OnSetting(setting_id, setting_fields.value);
+ // TODO(quic): Consider whether to add support for handling unknown SETTINGS
+ // IDs, which currently cause a connection close.
+ if (GetQuicRestartFlag(http2_propagate_unknown_settings)) {
+ visitor()->OnSetting(setting_id, setting_fields.value);
+ } else {
+ visitor()->OnSettingOld(setting_id, setting_fields.value);
+ }
}
void QuicHttpDecoderAdapter::OnSettingsEnd() {
diff --git a/chromium/net/quic/http/quic_http_structures.h b/chromium/net/quic/http/quic_http_structures.h
index 10c7d9e0d44..eb3f7a91ecb 100644
--- a/chromium/net/quic/http/quic_http_structures.h
+++ b/chromium/net/quic/http/quic_http_structures.h
@@ -249,7 +249,6 @@ QUIC_EXPORT_PRIVATE std::ostream& operator<<(
struct QuicHttpPingFields {
static constexpr size_t EncodedSize() { return 8; }
- // TODO(jamessynge): Rename opaque_bytes to opaque_bytes.
uint8_t opaque_bytes[8];
};
diff --git a/chromium/net/quic/http/tools/quic_http_random_util.cc b/chromium/net/quic/http/tools/quic_http_random_util.cc
index 7e7b259ba8d..afe4d064ce3 100644
--- a/chromium/net/quic/http/tools/quic_http_random_util.cc
+++ b/chromium/net/quic/http/tools/quic_http_random_util.cc
@@ -51,22 +51,6 @@ size_t GenerateUniformInRange(size_t lo, size_t hi, QuicTestRandomBase* rng) {
return lo + rng->Rand64() % (hi - lo);
}
-// Here "word" means something that starts with a lower-case letter, and has
-// zero or more additional characters that are numbers or lower-case letters.
-QuicString GenerateQuicHttpHeaderName(size_t len, QuicTestRandomBase* rng) {
- QuicStringPiece alpha_lc = "abcdefghijklmnopqrstuvwxyz";
- // If the name is short, just make it one word.
- if (len < 8) {
- return RandomString(rng, len, alpha_lc);
- }
- // If the name is longer, ensure it starts with a word, and after that may
- // have any character in alphanumdash_lc. 4 is arbitrary, could be as low
- // as 1.
- QuicStringPiece alphanumdash_lc = "abcdefghijklmnopqrstuvwxyz0123456789-";
- return RandomString(rng, 4, alpha_lc) +
- RandomString(rng, len - 4, alphanumdash_lc);
-}
-
QuicString GenerateWebSafeString(size_t len, QuicTestRandomBase* rng) {
return RandomString(rng, len, kWebsafe64);
}
diff --git a/chromium/net/quic/http/tools/quic_http_random_util.h b/chromium/net/quic/http/tools/quic_http_random_util.h
index da0245a4da5..1d6788a6ffd 100644
--- a/chromium/net/quic/http/tools/quic_http_random_util.h
+++ b/chromium/net/quic/http/tools/quic_http_random_util.h
@@ -16,15 +16,10 @@ namespace test {
// Returns a random integer in the range [lo, hi).
size_t GenerateUniformInRange(size_t lo, size_t hi, QuicTestRandomBase* rng);
-// Generate a std::string with the allowed character set for HTTP/2 /
-// HPQUIC_HTTP_ACK header names.
-QuicString GenerateQuicHttpHeaderName(size_t len, QuicTestRandomBase* rng);
-
-// Generate a std::string with the web-safe std::string character set of
-// specified len.
+// Generate a string with the web-safe string character set of specified len.
QuicString GenerateWebSafeString(size_t len, QuicTestRandomBase* rng);
-// Generate a std::string with the web-safe std::string character set of length
+// Generate a string with the web-safe string character set of length
// [lo, hi).
QuicString GenerateWebSafeString(size_t lo, size_t hi, QuicTestRandomBase* rng);
diff --git a/chromium/net/quic/platform/api/quic_logging.h b/chromium/net/quic/platform/api/quic_logging.h
index 14b1bffa3d6..798bfbf8252 100644
--- a/chromium/net/quic/platform/api/quic_logging.h
+++ b/chromium/net/quic/platform/api/quic_logging.h
@@ -13,6 +13,8 @@
// they would simply be translated to LOG.
#define QUIC_DVLOG(verbose_level) QUIC_DVLOG_IMPL(verbose_level)
+#define QUIC_DVLOG_IF(verbose_level, condition) \
+ QUIC_DVLOG_IF_IMPL(verbose_level, condition)
#define QUIC_DLOG(severity) QUIC_DLOG_IMPL(severity)
#define QUIC_DLOG_IF(severity, condition) QUIC_DLOG_IF_IMPL(severity, condition)
#define QUIC_VLOG(verbose_level) QUIC_VLOG_IMPL(verbose_level)
diff --git a/chromium/net/quic/platform/api/quic_mem_slice.h b/chromium/net/quic/platform/api/quic_mem_slice.h
index 11205af5c1d..ba0c03bb17a 100644
--- a/chromium/net/quic/platform/api/quic_mem_slice.h
+++ b/chromium/net/quic/platform/api/quic_mem_slice.h
@@ -41,6 +41,10 @@ class QUIC_EXPORT_PRIVATE QuicMemSlice {
~QuicMemSlice() = default;
+ // Release the underlying reference. Further access the memory will result in
+ // undefined behavior.
+ void Reset() { impl_.Reset(); }
+
// Returns a const char pointer to underlying data buffer.
const char* data() const { return impl_.data(); }
// Returns the length of underlying data buffer.
diff --git a/chromium/net/quic/platform/api/quic_singleton.h b/chromium/net/quic/platform/api/quic_singleton.h
new file mode 100644
index 00000000000..f9d393f8a89
--- /dev/null
+++ b/chromium/net/quic/platform/api/quic_singleton.h
@@ -0,0 +1,48 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_PLATFORM_API_QUIC_SINGLETON_H_
+#define NET_QUIC_PLATFORM_API_QUIC_SINGLETON_H_
+
+#include "net/quic/platform/impl/quic_singleton_impl.h"
+
+namespace net {
+
+// Singleton utility. Example usage:
+//
+// In your header:
+// #include "net/quic/platform/api/quic_singleton.h"
+// class Foo {
+// public:
+// static Foo* GetInstance();
+// void Bar() { ... }
+// private:
+// Foo() { ... }
+// friend net::QuicSingletonFriend<Foo>;
+// };
+//
+// In your source file:
+// Foo* Foo::GetInstance() {
+// return net::QuicSingleton<Foo>::get();
+// }
+//
+// To use the singleton:
+// Foo::GetInstance()->Bar();
+//
+// NOTE: The method accessing Singleton<T>::get() has to be named as GetInstance
+// and it is important that Foo::GetInstance() is not inlined in the
+// header. This makes sure that when source files from multiple targets include
+// this header they don't end up with different copies of the inlined code
+// creating multiple copies of the singleton.
+template <typename T>
+using QuicSingleton = QuicSingletonImpl<T>;
+
+// Type that a class using QuicSingleton must declare as a friend, in order for
+// QuicSingleton to be able to access the class's private constructor.
+template <typename T>
+using QuicSingletonFriend = QuicSingletonFriendImpl<T>;
+
+} // namespace net
+
+#endif // NET_QUIC_PLATFORM_API_QUIC_SINGLETON_H_
diff --git a/chromium/net/quic/platform/api/quic_singleton_test.cc b/chromium/net/quic/platform/api/quic_singleton_test.cc
new file mode 100644
index 00000000000..e6a2ec5e628
--- /dev/null
+++ b/chromium/net/quic/platform/api/quic_singleton_test.cc
@@ -0,0 +1,32 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/platform/api/quic_singleton.h"
+
+#include "net/quic/platform/api/quic_test.h"
+
+namespace net {
+namespace test {
+namespace {
+
+class Foo {
+ public:
+ static Foo* GetInstance() { return net::QuicSingleton<Foo>::get(); }
+
+ private:
+ Foo() = default;
+ friend net::QuicSingletonFriend<Foo>;
+};
+
+class QuicSingletonTest : public QuicTest {};
+
+TEST_F(QuicSingletonTest, Get) {
+ Foo* f1 = Foo::GetInstance();
+ Foo* f2 = Foo::GetInstance();
+ EXPECT_EQ(f1, f2);
+}
+
+} // namespace
+} // namespace test
+} // namespace net
diff --git a/chromium/net/quic/platform/api/quic_test.h b/chromium/net/quic/platform/api/quic_test.h
index b976b452a52..ca0b71e6564 100644
--- a/chromium/net/quic/platform/api/quic_test.h
+++ b/chromium/net/quic/platform/api/quic_test.h
@@ -7,6 +7,8 @@
#include "net/quic/platform/impl/quic_test_impl.h"
+using QuicFlagSaver = QuicFlagSaverImpl;
+
// Defines the base classes to be used in QUIC tests.
using QuicTest = QuicTestImpl;
template <class T>
diff --git a/chromium/net/quic/platform/api/quic_uint128.h b/chromium/net/quic/platform/api/quic_uint128.h
new file mode 100644
index 00000000000..afe252c3ba0
--- /dev/null
+++ b/chromium/net/quic/platform/api/quic_uint128.h
@@ -0,0 +1,19 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_PLATFORM_API_QUIC_UINT128_H_
+#define NET_QUIC_PLATFORM_API_QUIC_UINT128_H_
+
+#include "net/quic/platform/impl/quic_uint128_impl.h"
+
+namespace net {
+
+using QuicUint128 = QuicUint128Impl;
+#define MakeQuicUint128(hi, lo) MakeQuicUint128Impl(hi, lo);
+#define QuicUint128Low64(x) QuicUint128Low64Impl(x);
+#define QuicUint128High64(x) QuicUint128High64Impl(x);
+
+} // namespace net
+
+#endif // NET_QUIC_PLATFORM_API_QUIC_UINT128_H_
diff --git a/chromium/net/quic/platform/impl/quic_logging_impl.h b/chromium/net/quic/platform/impl/quic_logging_impl.h
index 37aa990b365..fb9add316fb 100644
--- a/chromium/net/quic/platform/impl/quic_logging_impl.h
+++ b/chromium/net/quic/platform/impl/quic_logging_impl.h
@@ -42,6 +42,8 @@
#define QUIC_CHROMIUM_DLOG_IF_DFATAL(condition) DLOG_IF(DFATAL, condition)
#define QUIC_DVLOG_IMPL(verbose_level) DVLOG(verbose_level)
+#define QUIC_DVLOG_IF_IMPL(verbose_level, condition) \
+ DVLOG_IF(verbose_level, condition)
#if defined(OS_WIN)
// wingdi.h defines ERROR to be 0. When we call QUIC_DLOG(ERROR), it gets
diff --git a/chromium/net/quic/platform/impl/quic_mem_slice_impl.cc b/chromium/net/quic/platform/impl/quic_mem_slice_impl.cc
index 5fdeb24a408..e82fcf1493c 100644
--- a/chromium/net/quic/platform/impl/quic_mem_slice_impl.cc
+++ b/chromium/net/quic/platform/impl/quic_mem_slice_impl.cc
@@ -34,6 +34,11 @@ QuicMemSliceImpl& QuicMemSliceImpl::operator=(QuicMemSliceImpl&& other) {
QuicMemSliceImpl::~QuicMemSliceImpl() = default;
+void QuicMemSliceImpl::Reset() {
+ io_buffer_ = nullptr;
+ length_ = 0;
+}
+
const char* QuicMemSliceImpl::data() const {
if (io_buffer_ == nullptr) {
return nullptr;
diff --git a/chromium/net/quic/platform/impl/quic_mem_slice_impl.h b/chromium/net/quic/platform/impl/quic_mem_slice_impl.h
index 43b9aad460a..1acf9f7b3f9 100644
--- a/chromium/net/quic/platform/impl/quic_mem_slice_impl.h
+++ b/chromium/net/quic/platform/impl/quic_mem_slice_impl.h
@@ -34,6 +34,10 @@ class QUIC_EXPORT_PRIVATE QuicMemSliceImpl {
~QuicMemSliceImpl();
+ // Release the underlying reference. Further access the memory will result in
+ // undefined behavior.
+ void Reset();
+
// Returns a char pointer to underlying data buffer.
const char* data() const;
// Returns the length of underlying data buffer.
diff --git a/chromium/net/quic/platform/impl/quic_singleton_impl.h b/chromium/net/quic/platform/impl/quic_singleton_impl.h
new file mode 100644
index 00000000000..9c02071cc53
--- /dev/null
+++ b/chromium/net/quic/platform/impl/quic_singleton_impl.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_PLATFORM_IMPL_QUIC_SINGLETON_IMPL_H_
+#define NET_QUIC_PLATFORM_IMPL_QUIC_SINGLETON_IMPL_H_
+
+#include "base/memory/singleton.h"
+
+namespace net {
+
+template <typename T>
+using QuicSingletonImpl = base::Singleton<T, base::DefaultSingletonTraits<T>>;
+
+template <typename T>
+using QuicSingletonFriendImpl = base::DefaultSingletonTraits<T>;
+
+} // namespace net
+
+#endif // NET_QUIC_PLATFORM_IMPL_QUIC_SINGLETON_IMPL_H_
diff --git a/chromium/net/quic/platform/impl/quic_test_impl.cc b/chromium/net/quic/platform/impl/quic_test_impl.cc
index dc1709b2856..6e22a9f5922 100644
--- a/chromium/net/quic/platform/impl/quic_test_impl.cc
+++ b/chromium/net/quic/platform/impl/quic_test_impl.cc
@@ -4,20 +4,14 @@
#include "net/quic/platform/impl/quic_test_impl.h"
-#include "base/logging.h"
-#include "net/quic/platform/api/quic_flags.h"
-
-QuicFlagSaver::QuicFlagSaver() {
-#define QUIC_FLAG(type, flag, value) \
- CHECK_EQ(value, flag) \
- << "Flag set to an unexpected value. A prior test is likely " \
- << "setting a flag without using a QuicFlagSaver";
+QuicFlagSaverImpl::QuicFlagSaverImpl() {
+#define QUIC_FLAG(type, flag, value) saved_##flag##_ = flag;
#include "net/quic/core/quic_flags_list.h"
#undef QUIC_FLAG
}
-QuicFlagSaver::~QuicFlagSaver() {
-#define QUIC_FLAG(type, flag, value) flag = value;
+QuicFlagSaverImpl::~QuicFlagSaverImpl() {
+#define QUIC_FLAG(type, flag, value) flag = saved_##flag##_;
#include "net/quic/core/quic_flags_list.h"
#undef QUIC_FLAG
}
diff --git a/chromium/net/quic/platform/impl/quic_test_impl.h b/chromium/net/quic/platform/impl/quic_test_impl.h
index 6be16527516..98ae8760cc2 100644
--- a/chromium/net/quic/platform/impl/quic_test_impl.h
+++ b/chromium/net/quic/platform/impl/quic_test_impl.h
@@ -5,26 +5,49 @@
#ifndef NET_QUIC_PLATFORM_IMPL_QUIC_TEST_IMPL_H_
#define NET_QUIC_PLATFORM_IMPL_QUIC_TEST_IMPL_H_
+#include "base/logging.h"
+#include "net/quic/platform/api/quic_flags.h"
#include "testing/gmock/include/gmock/gmock.h" // IWYU pragma: export
#include "testing/gtest/include/gtest/gtest.h" // IWYU pragma: export
-// When constructed, checks that all QUIC flags have their correct default
-// values and when destructed, restores those values.
-class QuicFlagSaver {
+// When constructed, saves the current values of all QUIC flags. When
+// destructed, restores all QUIC flags to the saved values.
+class QuicFlagSaverImpl {
public:
- QuicFlagSaver();
- ~QuicFlagSaver();
+ QuicFlagSaverImpl();
+ ~QuicFlagSaverImpl();
+
+ private:
+#define QUIC_FLAG(type, flag, value) type saved_##flag##_;
+#include "net/quic/core/quic_flags_list.h"
+#undef QUIC_FLAG
+};
+
+// Checks if all QUIC flags are on their default values on construction.
+class QuicFlagChecker {
+ public:
+ QuicFlagChecker() {
+#define QUIC_FLAG(type, flag, value) \
+ CHECK_EQ(value, flag) \
+ << "Flag set to an unexpected value. A prior test is likely " \
+ << "setting a flag without using a QuicFlagSaver. Use QuicTest to " \
+ "avoid this issue.";
+#include "net/quic/core/quic_flags_list.h"
+#undef QUIC_FLAG
+ }
};
class QuicTestImpl : public ::testing::Test {
private:
- QuicFlagSaver flags_; // Save/restore all QUIC flag values.
+ QuicFlagChecker checker_;
+ QuicFlagSaverImpl saver_; // Save/restore all QUIC flag values.
};
template <class T>
class QuicTestWithParamImpl : public ::testing::TestWithParam<T> {
private:
- QuicFlagSaver flags_; // Save/restore all QUIC flag values.
+ QuicFlagChecker checker_;
+ QuicFlagSaverImpl saver_; // Save/restore all QUIC flag values.
};
#endif // NET_QUIC_PLATFORM_IMPL_QUIC_TEST_IMPL_H_
diff --git a/chromium/net/quic/platform/impl/quic_uint128_impl.h b/chromium/net/quic/platform/impl/quic_uint128_impl.h
new file mode 100644
index 00000000000..cad9a6eea7d
--- /dev/null
+++ b/chromium/net/quic/platform/impl/quic_uint128_impl.h
@@ -0,0 +1,19 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_PLATFORM_IMPL_QUIC_UINT128_IMPL_H_
+#define NET_QUIC_PLATFORM_IMPL_QUIC_UINT128_IMPL_H_
+
+#include "net/base/int128.h"
+
+namespace net {
+
+using QuicUint128Impl = uint128;
+#define MakeQuicUint128Impl(hi, lo) MakeUint128(hi, lo)
+#define QuicUint128Low64Impl(x) Uint128Low64(x);
+#define QuicUint128High64Impl(x) Uint128High64(x);
+
+} // namespace net
+
+#endif // NET_QUIC_PLATFORM_IMPL_QUIC_UINT128_IMPL_H_
diff --git a/chromium/net/quic/quartc/quartc_factory.cc b/chromium/net/quic/quartc/quartc_factory.cc
index 3e182fa99e1..68912accf47 100644
--- a/chromium/net/quic/quartc/quartc_factory.cc
+++ b/chromium/net/quic/quartc/quartc_factory.cc
@@ -106,6 +106,8 @@ QuartcFactory::~QuartcFactory() {}
std::unique_ptr<QuartcSessionInterface> QuartcFactory::CreateQuartcSession(
const QuartcSessionConfig& quartc_session_config) {
DCHECK(quartc_session_config.packet_transport);
+ SetQuicReloadableFlag(quic_better_crypto_retransmission, true);
+ SetQuicReloadableFlag(quic_is_write_blocked, true);
Perspective perspective = quartc_session_config.is_server
? Perspective::IS_SERVER
@@ -121,6 +123,7 @@ std::unique_ptr<QuartcSessionInterface> QuartcFactory::CreateQuartcSession(
// Note: These settings have no effect for Exoblaze builds since
// SetQuicReloadableFlag() gets stubbed out.
SetQuicReloadableFlag(quic_bbr_less_probe_rtt, true);
+ SetQuicReloadableFlag(quic_unified_iw_options, true);
for (const auto option : quartc_session_config.bbr_options) {
switch (option) {
case (QuartcBbrOptions::kSlowerStartup):
@@ -141,6 +144,24 @@ std::unique_ptr<QuartcSessionInterface> QuartcFactory::CreateQuartcSession(
case (QuartcBbrOptions::kFillUpLinkDuringProbing):
quic_connection->set_fill_up_link_during_probing(true);
break;
+ case (QuartcBbrOptions::kInitialWindow3):
+ copt.push_back(kIW03);
+ break;
+ case (QuartcBbrOptions::kInitialWindow10):
+ copt.push_back(kIW10);
+ break;
+ case (QuartcBbrOptions::kInitialWindow20):
+ copt.push_back(kIW20);
+ break;
+ case (QuartcBbrOptions::kInitialWindow50):
+ copt.push_back(kIW50);
+ break;
+ case (QuartcBbrOptions::kStartup1RTT):
+ copt.push_back(k1RTT);
+ break;
+ case (QuartcBbrOptions::kStartup2RTT):
+ copt.push_back(k2RTT);
+ break;
}
}
}
diff --git a/chromium/net/quic/quartc/quartc_factory_interface.h b/chromium/net/quic/quartc/quartc_factory_interface.h
index 33dd6aa15ee..1007509ce45 100644
--- a/chromium/net/quic/quartc/quartc_factory_interface.h
+++ b/chromium/net/quic/quartc/quartc_factory_interface.h
@@ -37,6 +37,12 @@ enum class QuartcBbrOptions {
// once.
kFillUpLinkDuringProbing, // Sends probing retransmissions whenever we
// become application limited.
+ kInitialWindow3, // Use a 3-packet initial congestion window.
+ kInitialWindow10, // Use a 10-packet initial congestion window.
+ kInitialWindow20, // Use a 20-packet initial congestion window.
+ kInitialWindow50, // Use a 50-packet initial congestion window.
+ kStartup1RTT, // Stay in STARTUP for 1 RTT.
+ kStartup2RTT, // Stay in STARTUP for 2 RTTs.
};
// Used to create instances for Quartc objects such as QuartcSession.
diff --git a/chromium/net/quic/quartc/quartc_session.cc b/chromium/net/quic/quartc/quartc_session.cc
index 5bb483b297d..097f165d740 100644
--- a/chromium/net/quic/quartc/quartc_session.cc
+++ b/chromium/net/quic/quartc/quartc_session.cc
@@ -14,10 +14,6 @@ namespace net {
namespace {
-// Default priority for incoming QUIC streams.
-// TODO(zhihuang): Determine if this value is correct.
-static const SpdyPriority kDefaultPriority = 3;
-
// Arbitrary server port number for net::QuicCryptoClientConfig.
const int kQuicServerPort = 0;
@@ -165,8 +161,10 @@ QuicCryptoStream* QuartcSession::GetMutableCryptoStream() {
}
QuartcStream* QuartcSession::CreateOutgoingDynamicStream() {
- return ActivateDataStream(
- CreateDataStream(GetNextOutgoingStreamId(), kDefaultPriority));
+ // Use default priority for incoming QUIC streams.
+ // TODO(zhihuang): Determine if this value is correct.
+ return ActivateDataStream(CreateDataStream(GetNextOutgoingStreamId(),
+ QuicStream::kDefaultPriority));
}
void QuartcSession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) {
@@ -186,7 +184,9 @@ void QuartcSession::CloseStream(QuicStreamId stream_id) {
// QuicStream::OnClose), the stream is already closed so return.
return;
}
- write_blocked_streams()->UnregisterStream(stream_id);
+ if (!register_streams_early()) {
+ write_blocked_streams()->UnregisterStream(stream_id, /*is_static=*/false);
+ }
QuicSession::CloseStream(stream_id);
}
@@ -284,6 +284,11 @@ void QuartcSession::SetDelegate(
DCHECK(session_delegate_);
}
+void QuartcSession::SetSessionVisitor(QuartcSessionVisitor* debug_visitor) {
+ debug_visitor->SetQuicConnection(connection_.get());
+ connection_->set_debug_visitor(debug_visitor->GetConnectionVisitor());
+}
+
void QuartcSession::OnTransportCanWrite() {
connection()->writer()->SetWritable();
if (HasDataToWrite()) {
@@ -319,7 +324,7 @@ void QuartcSession::SetServerCryptoConfig(
}
QuicStream* QuartcSession::CreateIncomingDynamicStream(QuicStreamId id) {
- return ActivateDataStream(CreateDataStream(id, kDefaultPriority));
+ return ActivateDataStream(CreateDataStream(id, QuicStream::kDefaultPriority));
}
std::unique_ptr<QuartcStream> QuartcSession::CreateDataStream(
@@ -334,7 +339,12 @@ std::unique_ptr<QuartcStream> QuartcSession::CreateDataStream(
// Register the stream to the QuicWriteBlockedList. |priority| is clamped
// between 0 and 7, with 0 being the highest priority and 7 the lowest
// priority.
- write_blocked_streams()->RegisterStream(stream->id(), priority);
+ if (!register_streams_early()) {
+ write_blocked_streams()->RegisterStream(
+ stream->id(), /* is_static_stream= */ false, priority);
+ } else {
+ write_blocked_streams()->UpdateStreamPriority(stream->id(), priority);
+ }
if (IsIncomingStream(id)) {
DCHECK(session_delegate_);
diff --git a/chromium/net/quic/quartc/quartc_session.h b/chromium/net/quic/quartc/quartc_session.h
index a07bf22a8b2..5ead026632e 100644
--- a/chromium/net/quic/quartc/quartc_session.h
+++ b/chromium/net/quic/quartc/quartc_session.h
@@ -80,6 +80,8 @@ class QUIC_EXPORT_PRIVATE QuartcSession
void SetDelegate(QuartcSessionInterface::Delegate* session_delegate) override;
+ void SetSessionVisitor(QuartcSessionVisitor* debug_visitor) override;
+
void OnTransportCanWrite() override;
// Decrypts an incoming QUIC packet to a data stream.
diff --git a/chromium/net/quic/quartc/quartc_session_interface.h b/chromium/net/quic/quartc/quartc_session_interface.h
index 59233839d52..3ea50d980fd 100644
--- a/chromium/net/quic/quartc/quartc_session_interface.h
+++ b/chromium/net/quic/quartc/quartc_session_interface.h
@@ -14,6 +14,7 @@
#include "net/quic/core/quic_time.h"
#include "net/quic/core/quic_types.h"
#include "net/quic/platform/api/quic_export.h"
+#include "net/quic/quartc/quartc_session_visitor_interface.h"
#include "net/quic/quartc/quartc_stream_interface.h"
namespace net {
@@ -130,6 +131,9 @@ class QUIC_EXPORT_PRIVATE QuartcSessionInterface {
// The |delegate| is not owned by QuartcSession.
virtual void SetDelegate(Delegate* delegate) = 0;
+
+ // Sets a visitor for the session.
+ virtual void SetSessionVisitor(QuartcSessionVisitor* debug_visitor) = 0;
};
} // namespace net
diff --git a/chromium/net/quic/quartc/quartc_session_test.cc b/chromium/net/quic/quartc/quartc_session_test.cc
index 6117233e92f..c49d710a230 100644
--- a/chromium/net/quic/quartc/quartc_session_test.cc
+++ b/chromium/net/quic/quartc/quartc_session_test.cc
@@ -10,6 +10,7 @@
#include "net/quic/core/tls_client_handshaker.h"
#include "net/quic/core/tls_server_handshaker.h"
#include "net/quic/platform/api/quic_ptr_util.h"
+#include "net/quic/platform/api/quic_test_mem_slice_vector.h"
#include "net/quic/quartc/quartc_factory.h"
#include "net/quic/quartc/quartc_factory_interface.h"
#include "net/quic/quartc/quartc_packet_writer.h"
@@ -351,7 +352,7 @@ class FakeQuartcStreamDelegate : public QuartcStreamInterface::Delegate {
void OnClose(QuartcStreamInterface* stream) override {}
- void OnCanWrite(QuartcStreamInterface* stream) override {}
+ void OnBufferChanged(QuartcStreamInterface* stream) override {}
string data() { return last_received_data_; }
@@ -531,9 +532,10 @@ class QuartcSessionTest : public ::testing::Test,
outgoing_stream->SetDelegate(server_peer_->stream_delegate());
// Send a test message from peer 1 to peer 2.
- const char kTestMessage[] = "Hello";
- outgoing_stream->Write(kTestMessage, strlen(kTestMessage),
- kDefaultWriteParam);
+ char kTestMessage[] = "Hello";
+ test::QuicTestMemSliceVector data(
+ {std::make_pair(kTestMessage, strlen(kTestMessage))});
+ outgoing_stream->Write(data.span(), kDefaultWriteParam);
RunTasks();
// Wait for peer 2 to receive messages.
@@ -546,8 +548,10 @@ class QuartcSessionTest : public ::testing::Test,
EXPECT_EQ(client_peer_->data(), kTestMessage);
// Send a test message from peer 2 to peer 1.
- const char kTestResponse[] = "Response";
- incoming->Write(kTestResponse, strlen(kTestResponse), kDefaultWriteParam);
+ char kTestResponse[] = "Response";
+ test::QuicTestMemSliceVector response(
+ {std::make_pair(kTestResponse, strlen(kTestResponse))});
+ incoming->Write(response.span(), kDefaultWriteParam);
RunTasks();
// Wait for peer 1 to receive messages.
ASSERT_TRUE(server_peer_->has_data());
diff --git a/chromium/net/quic/quartc/quartc_session_visitor_interface.h b/chromium/net/quic/quartc/quartc_session_visitor_interface.h
new file mode 100644
index 00000000000..48d4521ac3b
--- /dev/null
+++ b/chromium/net/quic/quartc/quartc_session_visitor_interface.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_QUARTC_QUARTC_SESSION_VISITOR_INTERFACE_H_
+#define NET_QUIC_QUARTC_QUARTC_SESSION_VISITOR_INTERFACE_H_
+
+#include "net/quic/core/quic_connection.h"
+#include "net/quic/platform/api/quic_export.h"
+
+namespace net {
+
+class QUIC_EXPORT_PRIVATE QuartcSessionVisitor {
+ public:
+ virtual ~QuartcSessionVisitor() {}
+
+ // Sets the |QuicConnection| for this debug visitor. Called before
+ // |GetConnectionVisitor|.
+ virtual void SetQuicConnection(QuicConnection* connection) = 0;
+
+ // Gets the |QuicConnectionDebugVisitor| associated with this Quartc visitor.
+ virtual QuicConnectionDebugVisitor* GetConnectionVisitor() const = 0;
+};
+
+} // namespace net
+
+#endif // NET_QUIC_QUARTC_QUARTC_SESSION_VISITOR_INTERFACE_H_
diff --git a/chromium/net/quic/quartc/quartc_stream.cc b/chromium/net/quic/quartc/quartc_stream.cc
index 8aa818edb5a..adf936847a3 100644
--- a/chromium/net/quic/quartc/quartc_stream.cc
+++ b/chromium/net/quic/quartc/quartc_stream.cc
@@ -9,7 +9,7 @@
namespace net {
QuartcStream::QuartcStream(QuicStreamId id, QuicSession* session)
- : QuicStream(id, session) {}
+ : QuicStream(id, session, /*is_static=*/false) {}
QuartcStream::~QuartcStream() {}
void QuartcStream::OnDataAvailable() {
@@ -35,22 +35,27 @@ void QuartcStream::OnClose() {
delegate_->OnClose(this);
}
-void QuartcStream::OnCanWrite() {
- QuicStream::OnCanWrite();
+void QuartcStream::OnStreamDataConsumed(size_t bytes_consumed) {
+ QuicStream::OnStreamDataConsumed(bytes_consumed);
+
DCHECK(delegate_);
- // Don't call the delegate if the write-side is closed or a fin is buffered.
- // It is already done with this stream.
- if (!write_side_closed() && !fin_buffered()) {
- delegate_->OnCanWrite(this);
- }
+ delegate_->OnBufferChanged(this);
+}
+
+void QuartcStream::OnDataBuffered(
+ QuicStreamOffset offset,
+ QuicByteCount data_length,
+ const QuicReferenceCountedPointer<QuicAckListenerInterface>& ack_listener) {
+ DCHECK(delegate_);
+ delegate_->OnBufferChanged(this);
}
uint32_t QuartcStream::stream_id() {
return id();
}
-uint64_t QuartcStream::bytes_written() {
- return stream_bytes_written();
+uint64_t QuartcStream::bytes_buffered() {
+ return BufferedDataBytes();
}
bool QuartcStream::fin_sent() {
@@ -61,15 +66,8 @@ int QuartcStream::stream_error() {
return QuicStream::stream_error();
}
-int QuartcStream::connection_error() {
- return QuicStream::connection_error();
-}
-
-void QuartcStream::Write(const char* data,
- size_t size,
- const WriteParameters& param) {
- struct iovec iov = {const_cast<char*>(data), size};
- WritevData(&iov, 1, param.fin);
+void QuartcStream::Write(QuicMemSliceSpan data, const WriteParameters& param) {
+ WriteMemSlices(data, param.fin);
}
void QuartcStream::FinishWriting() {
diff --git a/chromium/net/quic/quartc/quartc_stream.h b/chromium/net/quic/quartc/quartc_stream.h
index 8b7a777fa89..a33a176b7d2 100644
--- a/chromium/net/quic/quartc/quartc_stream.h
+++ b/chromium/net/quic/quartc/quartc_stream.h
@@ -25,22 +25,24 @@ class QUIC_EXPORT_PRIVATE QuartcStream : public QuicStream,
void OnClose() override;
- void OnCanWrite() override;
+ void OnStreamDataConsumed(size_t bytes_consumed) override;
+
+ void OnDataBuffered(
+ QuicStreamOffset offset,
+ QuicByteCount data_length,
+ const QuicReferenceCountedPointer<QuicAckListenerInterface>& ack_listener)
+ override;
// QuartcStreamInterface overrides.
uint32_t stream_id() override;
- uint64_t bytes_written() override;
+ uint64_t bytes_buffered() override;
bool fin_sent() override;
int stream_error() override;
- int connection_error() override;
-
- void Write(const char* data,
- size_t size,
- const WriteParameters& param) override;
+ void Write(QuicMemSliceSpan data, const WriteParameters& param) override;
void FinishWriting() override;
diff --git a/chromium/net/quic/quartc/quartc_stream_interface.h b/chromium/net/quic/quartc/quartc_stream_interface.h
index 304190aa662..cae57f69c44 100644
--- a/chromium/net/quic/quartc/quartc_stream_interface.h
+++ b/chromium/net/quic/quartc/quartc_stream_interface.h
@@ -9,6 +9,7 @@
#include <stdint.h>
#include "net/quic/platform/api/quic_export.h"
+#include "net/quic/platform/api/quic_mem_slice_span.h"
namespace net {
@@ -23,8 +24,8 @@ class QUIC_EXPORT_PRIVATE QuartcStreamInterface {
// The QUIC stream ID.
virtual uint32_t stream_id() = 0;
- // The amount of data sent on this stream.
- virtual uint64_t bytes_written() = 0;
+ // The amount of data buffered on this stream.
+ virtual uint64_t bytes_buffered() = 0;
// Return true if the FIN has been sent. Used by the outgoing streams to
// determine if all the data has been sent
@@ -32,21 +33,16 @@ class QUIC_EXPORT_PRIVATE QuartcStreamInterface {
virtual int stream_error() = 0;
- virtual int connection_error() = 0;
-
struct WriteParameters {
- WriteParameters() : fin(false) {}
// |fin| is set to be true when there is no more data need to be send
// through a particular stream. The receiving side will used it to determine
// if the sender finish sending data.
- bool fin;
+ bool fin = false;
};
// Sends data reliably and in-order. Returns the amount sent.
// Does not buffer data.
- virtual void Write(const char* data,
- size_t size,
- const WriteParameters& param) = 0;
+ virtual void Write(QuicMemSliceSpan data, const WriteParameters& param) = 0;
// Marks this stream as finished writing. Asynchronously sends a FIN and
// closes the write-side. The stream will no longer call OnCanWrite().
@@ -83,8 +79,8 @@ class QUIC_EXPORT_PRIVATE QuartcStreamInterface {
// error code.
virtual void OnClose(QuartcStreamInterface* stream) = 0;
- // Called when more data may be written to a stream.
- virtual void OnCanWrite(QuartcStreamInterface* stream) = 0;
+ // Called when the contents of the stream's buffer changes.
+ virtual void OnBufferChanged(QuartcStreamInterface* stream) = 0;
};
// The |delegate| is not owned by QuartcStream.
diff --git a/chromium/net/quic/quartc/quartc_stream_test.cc b/chromium/net/quic/quartc/quartc_stream_test.cc
index 27065ada2d8..5ab681beb43 100644
--- a/chromium/net/quic/quartc/quartc_stream_test.cc
+++ b/chromium/net/quic/quartc/quartc_stream_test.cc
@@ -9,6 +9,7 @@
#include "net/quic/core/quic_session.h"
#include "net/quic/core/quic_simple_buffer_allocator.h"
#include "net/quic/platform/api/quic_ptr_util.h"
+#include "net/quic/platform/api/quic_test_mem_slice_vector.h"
#include "net/quic/quartc/quartc_clock_interface.h"
#include "net/quic/quartc/quartc_factory.h"
#include "net/quic/test_tools/mock_clock.h"
@@ -20,7 +21,6 @@ namespace net {
namespace {
-static const SpdyPriority kDefaultPriority = 3;
static const QuicStreamId kStreamId = 5;
static const QuartcStreamInterface::WriteParameters kDefaultParam;
@@ -78,7 +78,9 @@ class MockQuicSession : public QuicSession {
// Tracks whether the stream is write blocked and its priority.
void RegisterReliableStream(QuicStreamId stream_id, SpdyPriority priority) {
- write_blocked_streams()->RegisterStream(stream_id, priority);
+ write_blocked_streams()->RegisterStream(stream_id,
+ /*is_static_stream=*/false,
+ priority);
}
// The session take ownership of the stream.
@@ -125,8 +127,8 @@ class MockQuartcStreamDelegate : public QuartcStreamInterface::Delegate {
MockQuartcStreamDelegate(int id, std::string* read_buffer)
: id_(id), read_buffer_(read_buffer) {}
- void OnCanWrite(QuartcStreamInterface* stream) override {
- ++on_can_write_callbacks_;
+ void OnBufferChanged(QuartcStreamInterface* stream) override {
+ last_bytes_buffered_ = stream->bytes_buffered();
}
void OnReceived(QuartcStreamInterface* stream,
@@ -140,7 +142,7 @@ class MockQuartcStreamDelegate : public QuartcStreamInterface::Delegate {
bool closed() { return closed_; }
- int32_t on_can_write_callbacks() { return on_can_write_callbacks_; }
+ uint64_t last_bytes_buffered() { return last_bytes_buffered_; }
protected:
uint32_t id_;
@@ -148,8 +150,9 @@ class MockQuartcStreamDelegate : public QuartcStreamInterface::Delegate {
std::string* read_buffer_;
// Whether the QuicStream is closed.
bool closed_ = false;
- // How many times OnCanWrite has been called.
- int32_t on_can_write_callbacks_ = 0;
+
+ // Last amount of data observed as buffered.
+ uint64_t last_bytes_buffered_ = 0;
};
class QuartcStreamTest : public ::testing::Test,
@@ -177,7 +180,10 @@ class QuartcStreamTest : public ::testing::Test,
QuicMakeUnique<MockQuartcStreamDelegate>(kStreamId, &read_buffer_);
stream_ = new QuartcStream(kStreamId, session_.get());
stream_->SetDelegate(mock_stream_delegate_.get());
- session_->RegisterReliableStream(stream_->stream_id(), kDefaultPriority);
+ if (!session_->register_streams_early()) {
+ session_->RegisterReliableStream(stream_->stream_id(),
+ QuicStream::kDefaultPriority);
+ }
session_->ActivateReliableStream(std::unique_ptr<QuartcStream>(stream_));
}
@@ -212,42 +218,67 @@ class QuartcStreamTest : public ::testing::Test,
// Write an entire string.
TEST_F(QuartcStreamTest, WriteDataWhole) {
CreateReliableQuicStream();
- stream_->Write("Foo bar", 7, kDefaultParam);
+ char message[] = "Foo bar";
+ test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
+ stream_->Write(data.span(), kDefaultParam);
EXPECT_EQ("Foo bar", write_buffer_);
}
// Write part of a string.
TEST_F(QuartcStreamTest, WriteDataPartial) {
CreateReliableQuicStream();
- stream_->Write("Foo bar", 5, kDefaultParam);
+ char message[] = "Foo bar";
+ test::QuicTestMemSliceVector data({std::make_pair(message, 5)});
+ stream_->Write(data.span(), kDefaultParam);
EXPECT_EQ("Foo b", write_buffer_);
}
-// Test that strings are not buffered.
-TEST_F(QuartcStreamTest, NoBuffer) {
+// Test that a QuartcStream buffers writes correctly.
+TEST_F(QuartcStreamTest, StreamBuffersData) {
CreateReliableQuicStream();
+ char message[] = "Foo bar";
+ test::QuicTestMemSliceVector data({std::make_pair(message, 7)});
+
+ // The stream is not yet writable, so data will be buffered.
session_->set_writable(false);
- stream_->Write("Foo bar", 7, kDefaultParam);
- // The data will not be buffered.
+ stream_->Write(data.span(), kDefaultParam);
+
+ // Check that data is buffered.
+ EXPECT_TRUE(stream_->HasBufferedData());
+ EXPECT_EQ(7u, stream_->bytes_buffered());
+
+ // Check that the stream told its delegate about the buffer change.
+ EXPECT_EQ(7u, mock_stream_delegate_->last_bytes_buffered());
+
+ // Check that none of the data was written yet.
+ // Note that |write_buffer_| actually holds data written by the QuicSession
+ // (not data buffered by the stream).
EXPECT_EQ(0ul, write_buffer_.size());
+
+ char message1[] = "xyzzy";
+ test::QuicTestMemSliceVector data1({std::make_pair(message1, 5)});
+
+ // More writes go into the buffer.
+ stream_->Write(data1.span(), kDefaultParam);
+
EXPECT_TRUE(stream_->HasBufferedData());
- EXPECT_EQ(0u, stream_->bytes_written());
- // The stream is writable, but there's nothing to send.
+ EXPECT_EQ(12u, stream_->bytes_buffered());
+ EXPECT_EQ(12u, mock_stream_delegate_->last_bytes_buffered());
+ EXPECT_EQ(0ul, write_buffer_.size());
+
+ // The stream becomes writable, so it sends the buffered data.
session_->set_writable(true);
stream_->OnCanWrite();
- EXPECT_EQ(7u, stream_->bytes_written());
- EXPECT_EQ(7ul, write_buffer_.size());
- EXPECT_FALSE(stream_->HasBufferedData());
- stream_->Write("xyzzy", 5, kDefaultParam);
+ EXPECT_FALSE(stream_->HasBufferedData());
+ EXPECT_EQ(0u, stream_->bytes_buffered());
+ EXPECT_EQ(0u, mock_stream_delegate_->last_bytes_buffered());
EXPECT_EQ("Foo barxyzzy", write_buffer_);
- EXPECT_EQ(12u, stream_->bytes_written());
}
// Finish writing to a stream.
-// The stream no longer calls OnCanWrite(). It delivers the fin bit and closes
-// the write-side as soon as possible.
+// It delivers the fin bit and closes the write-side as soon as possible.
TEST_F(QuartcStreamTest, FinishWriting) {
CreateReliableQuicStream();
@@ -255,16 +286,11 @@ TEST_F(QuartcStreamTest, FinishWriting) {
stream_->FinishWriting();
EXPECT_FALSE(stream_->fin_sent());
- // Fin is buffered, no callback to OnCanWrite.
- stream_->OnCanWrite();
- EXPECT_EQ(0, mock_stream_delegate_->on_can_write_callbacks());
- EXPECT_FALSE(stream_->fin_sent());
-
- // Fin is sent, no callback to OnCanWrite.
+ // Fin is sent as soon as the stream becomes writable.
session_->set_writable(true);
stream_->OnCanWrite();
- EXPECT_EQ(0, mock_stream_delegate_->on_can_write_callbacks());
EXPECT_TRUE(stream_->fin_sent());
+ EXPECT_TRUE(stream_->write_side_closed());
}
// Read an entire string.
@@ -319,7 +345,8 @@ TEST_F(QuartcStreamTest, CloseOnFins) {
QuartcStreamInterface::WriteParameters param;
param.fin = true;
- stream_->Write(nullptr, 0, param);
+ test::QuicTestMemSliceVector data({});
+ stream_->Write(data.span(), param);
// Check that the OnClose() callback occurred.
EXPECT_TRUE(mock_stream_delegate_->closed());
diff --git a/chromium/net/quic/test_tools/crypto_test_utils.cc b/chromium/net/quic/test_tools/crypto_test_utils.cc
index d2e4147b5e1..e451532f08e 100644
--- a/chromium/net/quic/test_tools/crypto_test_utils.cc
+++ b/chromium/net/quic/test_tools/crypto_test_utils.cc
@@ -623,7 +623,7 @@ uint64_t LeafCertHashForTesting() {
class MockCommonCertSets : public CommonCertSets {
public:
MockCommonCertSets(QuicStringPiece cert, uint64_t hash, uint32_t index)
- : cert_(cert.as_string()), hash_(hash), index_(index) {}
+ : cert_(cert), hash_(hash), index_(index) {}
QuicStringPiece GetCommonHashes() const override {
QUIC_BUG << "not implemented";
@@ -901,7 +901,7 @@ CryptoHandshakeMessage CreateCHLO(
CryptoFramer::ConstructHandshakeMessage(msg, Perspective::IS_CLIENT));
std::unique_ptr<CryptoHandshakeMessage> parsed(CryptoFramer::ParseMessage(
bytes->AsStringPiece(), Perspective::IS_CLIENT));
- CHECK(parsed.get());
+ CHECK(parsed);
return *parsed;
}
@@ -916,6 +916,13 @@ void MovePacketsForTlsHandshake(PacketSavingConnection* source_conn,
PacketSavingConnection* dest_conn,
Perspective dest_perspective) {
SimpleQuicFramer framer(source_conn->supported_versions(), dest_perspective);
+ std::vector<std::unique_ptr<QuicStreamFrame>> stream_frames;
+ std::vector<std::vector<char>> buffers;
+
+ QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
+
+ SimpleQuicFramer null_encryption_framer(source_conn->supported_versions(),
+ dest_perspective);
size_t index = *inout_packet_index;
for (; index < source_conn->encrypted_packets_.size(); index++) {
if (!framer.ProcessPacket(*source_conn->encrypted_packets_[index])) {
@@ -923,12 +930,37 @@ void MovePacketsForTlsHandshake(PacketSavingConnection* source_conn,
// the handshake is complete. Don't treat them as handshake packets.
break;
}
+ // Try to process the packet with a framer that only has the NullDecrypter
+ // for decryption. If ProcessPacket succeeds, that means the packet was
+ // encrypted with the NullEncrypter. With the TLS handshaker in use, no
+ // packets should ever be encrypted with the NullEncrypter, instead they're
+ // encrypted with an obfuscation cipher based on QUIC version and connection
+ // ID.
+ ASSERT_FALSE(null_encryption_framer.ProcessPacket(
+ *source_conn->encrypted_packets_[index]))
+ << "No TLS packets should be encrypted with the NullEncrypter";
for (const auto& stream_frame : framer.stream_frames()) {
- dest_conn->OnStreamFrame(*stream_frame);
+ // The stream frames from SimpleQuicFramer::stream_frames() are only valid
+ // until the next call to ProcessPacket. This copies the stream frames to
+ // |stream_frames|, including making a copy of the data buffer, since a
+ // QuicStreamFrame does not own the data it points to.
+ std::vector<char> buffer(stream_frame->data_length);
+ memcpy(buffer.data(), stream_frame->data_buffer,
+ stream_frame->data_length);
+ auto frame = QuicMakeUnique<QuicStreamFrame>(
+ stream_frame->stream_id, stream_frame->fin, stream_frame->offset,
+ QuicStringPiece(buffer.data(), buffer.size()));
+ stream_frames.push_back(std::move(frame));
+ buffers.push_back(std::move(buffer));
}
}
*inout_packet_index = index;
+ QuicConnectionPeer::SwapCrypters(dest_conn, framer.framer());
+
+ for (const auto& stream_frame : stream_frames) {
+ dest_conn->OnStreamFrame(*stream_frame);
+ }
}
void MovePackets(PacketSavingConnection* source_conn,
diff --git a/chromium/net/quic/test_tools/mock_crypto_client_stream.cc b/chromium/net/quic/test_tools/mock_crypto_client_stream.cc
index 2ccd8f06eb6..d0ecd118e60 100644
--- a/chromium/net/quic/test_tools/mock_crypto_client_stream.cc
+++ b/chromium/net/quic/test_tools/mock_crypto_client_stream.cc
@@ -9,6 +9,7 @@
#include "net/quic/core/crypto/quic_decrypter.h"
#include "net/quic/core/crypto/quic_encrypter.h"
#include "net/quic/core/quic_spdy_client_session_base.h"
+#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/test_tools/mock_decrypter.h"
#include "net/quic/test_tools/mock_encrypter.h"
#include "net/quic/test_tools/quic_config_peer.h"
@@ -77,14 +78,18 @@ bool MockCryptoClientStream::CryptoConnect() {
}
if (use_mock_crypter_) {
session()->connection()->SetDecrypter(
- ENCRYPTION_INITIAL, new MockDecrypter(Perspective::IS_CLIENT));
+ ENCRYPTION_INITIAL,
+ QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
session()->connection()->SetEncrypter(
- ENCRYPTION_INITIAL, new MockEncrypter(Perspective::IS_CLIENT));
+ ENCRYPTION_INITIAL,
+ QuicMakeUnique<MockEncrypter>(Perspective::IS_CLIENT));
} else {
session()->connection()->SetDecrypter(
- ENCRYPTION_INITIAL, new NullDecrypter(Perspective::IS_CLIENT));
+ ENCRYPTION_INITIAL,
+ QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
session()->connection()->SetEncrypter(
- ENCRYPTION_INITIAL, new NullEncrypter(Perspective::IS_CLIENT));
+ ENCRYPTION_INITIAL,
+ QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
}
session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
session()->OnCryptoHandshakeEvent(
@@ -105,17 +110,17 @@ bool MockCryptoClientStream::CryptoConnect() {
if (use_mock_crypter_) {
session()->connection()->SetDecrypter(
ENCRYPTION_FORWARD_SECURE,
- new MockDecrypter(Perspective::IS_CLIENT));
+ QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
session()->connection()->SetEncrypter(
ENCRYPTION_FORWARD_SECURE,
- new MockEncrypter(Perspective::IS_CLIENT));
+ QuicMakeUnique<MockEncrypter>(Perspective::IS_CLIENT));
} else {
session()->connection()->SetDecrypter(
ENCRYPTION_FORWARD_SECURE,
- new NullDecrypter(Perspective::IS_CLIENT));
+ QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
session()->connection()->SetEncrypter(
ENCRYPTION_FORWARD_SECURE,
- new NullEncrypter(Perspective::IS_CLIENT));
+ QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
}
session()->connection()->SetDefaultEncryptionLevel(
ENCRYPTION_FORWARD_SECURE);
@@ -163,14 +168,18 @@ void MockCryptoClientStream::SendOnCryptoHandshakeEvent(
SetConfigNegotiated();
if (use_mock_crypter_) {
session()->connection()->SetDecrypter(
- ENCRYPTION_FORWARD_SECURE, new MockDecrypter(Perspective::IS_CLIENT));
+ ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<MockDecrypter>(Perspective::IS_CLIENT));
session()->connection()->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE, new MockEncrypter(Perspective::IS_CLIENT));
+ ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<MockEncrypter>(Perspective::IS_CLIENT));
} else {
session()->connection()->SetDecrypter(
- ENCRYPTION_FORWARD_SECURE, new NullDecrypter(Perspective::IS_CLIENT));
+ ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
session()->connection()->SetEncrypter(
- ENCRYPTION_FORWARD_SECURE, new NullEncrypter(Perspective::IS_CLIENT));
+ ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
}
session()->connection()->SetDefaultEncryptionLevel(
ENCRYPTION_FORWARD_SECURE);
diff --git a/chromium/net/quic/test_tools/quic_config_peer.cc b/chromium/net/quic/test_tools/quic_config_peer.cc
index 7fa9db79013..749efbbb817 100644
--- a/chromium/net/quic/test_tools/quic_config_peer.cc
+++ b/chromium/net/quic/test_tools/quic_config_peer.cc
@@ -10,13 +10,6 @@ namespace net {
namespace test {
// static
-void QuicConfigPeer::SetReceivedSocketReceiveBuffer(
- QuicConfig* config,
- uint32_t receive_buffer_bytes) {
- config->socket_receive_buffer_.SetReceivedValue(receive_buffer_bytes);
-}
-
-// static
void QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(
QuicConfig* config,
uint32_t window_bytes) {
@@ -64,5 +57,11 @@ void QuicConfigPeer::SetConnectionOptionsToSend(QuicConfig* config,
config->SetConnectionOptionsToSend(options);
}
+// static
+void QuicConfigPeer::SetReceivedStatelessResetToken(QuicConfig* config,
+ uint128 token) {
+ config->stateless_reset_token_.SetReceivedValue(token);
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/test_tools/quic_config_peer.h b/chromium/net/quic/test_tools/quic_config_peer.h
index 9af9341add0..ece91bf7bbf 100644
--- a/chromium/net/quic/test_tools/quic_config_peer.h
+++ b/chromium/net/quic/test_tools/quic_config_peer.h
@@ -8,6 +8,7 @@
#include "base/macros.h"
#include "net/quic/core/quic_config.h"
#include "net/quic/core/quic_packets.h"
+#include "net/quic/platform/api/quic_uint128.h"
namespace net {
@@ -17,9 +18,6 @@ namespace test {
class QuicConfigPeer {
public:
- static void SetReceivedSocketReceiveBuffer(QuicConfig* config,
- uint32_t receive_buffer_bytes);
-
static void SetReceivedInitialStreamFlowControlWindow(QuicConfig* config,
uint32_t window_bytes);
@@ -40,6 +38,8 @@ class QuicConfigPeer {
static void SetConnectionOptionsToSend(QuicConfig* config,
const QuicTagVector& options);
+ static void SetReceivedStatelessResetToken(QuicConfig* config, uint128 token);
+
private:
DISALLOW_COPY_AND_ASSIGN(QuicConfigPeer);
};
diff --git a/chromium/net/quic/test_tools/quic_connection_peer.cc b/chromium/net/quic/test_tools/quic_connection_peer.cc
index d5c1ae6ca23..11e4227e493 100644
--- a/chromium/net/quic/test_tools/quic_connection_peer.cc
+++ b/chromium/net/quic/test_tools/quic_connection_peer.cc
@@ -98,6 +98,20 @@ void QuicConnectionPeer::SetPeerAddress(QuicConnection* connection,
}
// static
+void QuicConnectionPeer::SetDirectPeerAddress(
+ QuicConnection* connection,
+ const QuicSocketAddress& direct_peer_address) {
+ connection->direct_peer_address_ = direct_peer_address;
+}
+
+// static
+void QuicConnectionPeer::SetEffectivePeerAddress(
+ QuicConnection* connection,
+ const QuicSocketAddress& effective_peer_address) {
+ connection->effective_peer_address_ = effective_peer_address;
+}
+
+// static
bool QuicConnectionPeer::IsSilentCloseEnabled(QuicConnection* connection) {
return connection->idle_timeout_connection_close_behavior_ ==
ConnectionCloseBehavior::SILENT_CLOSE;
@@ -172,6 +186,18 @@ QuicAlarm* QuicConnectionPeer::GetMtuDiscoveryAlarm(
}
// static
+QuicAlarm* QuicConnectionPeer::GetRetransmittableOnWireAlarm(
+ QuicConnection* connection) {
+ return connection->retransmittable_on_wire_alarm_.get();
+}
+
+// static
+QuicAlarm* QuicConnectionPeer::GetPathDegradingAlarm(
+ QuicConnection* connection) {
+ return connection->path_degrading_alarm_.get();
+}
+
+// static
QuicPacketWriter* QuicConnectionPeer::GetWriter(QuicConnection* connection) {
return connection->writer_;
}
diff --git a/chromium/net/quic/test_tools/quic_connection_peer.h b/chromium/net/quic/test_tools/quic_connection_peer.h
index efcee9eb414..d67cb753b57 100644
--- a/chromium/net/quic/test_tools/quic_connection_peer.h
+++ b/chromium/net/quic/test_tools/quic_connection_peer.h
@@ -64,6 +64,14 @@ class QuicConnectionPeer {
static void SetPeerAddress(QuicConnection* connection,
const QuicSocketAddress& peer_address);
+ static void SetDirectPeerAddress(
+ QuicConnection* connection,
+ const QuicSocketAddress& direct_peer_address);
+
+ static void SetEffectivePeerAddress(
+ QuicConnection* connection,
+ const QuicSocketAddress& effective_peer_address);
+
static bool IsSilentCloseEnabled(QuicConnection* connection);
static void SwapCrypters(QuicConnection* connection, QuicFramer* framer);
@@ -84,6 +92,8 @@ class QuicConnectionPeer {
static QuicAlarm* GetSendAlarm(QuicConnection* connection);
static QuicAlarm* GetTimeoutAlarm(QuicConnection* connection);
static QuicAlarm* GetMtuDiscoveryAlarm(QuicConnection* connection);
+ static QuicAlarm* GetRetransmittableOnWireAlarm(QuicConnection* connection);
+ static QuicAlarm* GetPathDegradingAlarm(QuicConnection* connection);
static QuicPacketWriter* GetWriter(QuicConnection* connection);
// If |owns_writer| is true, takes ownership of |writer|.
diff --git a/chromium/net/quic/test_tools/quic_framer_peer.cc b/chromium/net/quic/test_tools/quic_framer_peer.cc
index e9d65f42678..37c91f6bbda 100644
--- a/chromium/net/quic/test_tools/quic_framer_peer.cc
+++ b/chromium/net/quic/test_tools/quic_framer_peer.cc
@@ -49,6 +49,7 @@ bool QuicFramerPeer::ProcessIetfStreamFrame(QuicFramer* framer,
QuicStreamFrame* frame) {
return framer->ProcessIetfStreamFrame(reader, frame_type, frame);
}
+
// static
bool QuicFramerPeer::AppendIetfStreamFrame(QuicFramer* framer,
const QuicStreamFrame& frame,
@@ -56,6 +57,7 @@ bool QuicFramerPeer::AppendIetfStreamFrame(QuicFramer* framer,
QuicDataWriter* writer) {
return framer->AppendIetfStreamFrame(frame, last_frame_in_packet, writer);
}
+
// static
bool QuicFramerPeer::ProcessIetfAckFrame(QuicFramer* framer,
QuicDataReader* reader,
@@ -63,11 +65,12 @@ bool QuicFramerPeer::ProcessIetfAckFrame(QuicFramer* framer,
QuicAckFrame* ack_frame) {
return framer->ProcessIetfAckFrame(reader, frame_type, ack_frame);
}
+
// static
-bool QuicFramerPeer::AppendIetfAckFrameAndTypeByte(QuicFramer* framer,
- const QuicAckFrame& frame,
- QuicDataWriter* writer) {
- return framer->AppendIetfAckFrameAndTypeByte(frame, writer);
+bool QuicFramerPeer::AppendIetfAckFrame(QuicFramer* framer,
+ const QuicAckFrame& frame,
+ QuicDataWriter* writer) {
+ return framer->AppendIetfAckFrame(frame, writer);
}
// static
@@ -77,14 +80,7 @@ bool QuicFramerPeer::AppendIetfConnectionCloseFrame(
QuicDataWriter* writer) {
return framer->AppendIetfConnectionCloseFrame(frame, writer);
}
-// static
-bool QuicFramerPeer::AppendIetfConnectionCloseFrame(
- QuicFramer* framer,
- const QuicIetfTransportErrorCodes code,
- const string& phrase,
- QuicDataWriter* writer) {
- return framer->AppendIetfConnectionCloseFrame(code, phrase, writer);
-}
+
// static
bool QuicFramerPeer::AppendIetfApplicationCloseFrame(
QuicFramer* framer,
@@ -92,13 +88,7 @@ bool QuicFramerPeer::AppendIetfApplicationCloseFrame(
QuicDataWriter* writer) {
return framer->AppendIetfApplicationCloseFrame(frame, writer);
}
-// static
-bool QuicFramerPeer::AppendIetfApplicationCloseFrame(QuicFramer* framer,
- const uint16_t code,
- const string& phrase,
- QuicDataWriter* writer) {
- return framer->AppendIetfApplicationCloseFrame(code, phrase, writer);
-}
+
// static
bool QuicFramerPeer::ProcessIetfConnectionCloseFrame(
QuicFramer* framer,
@@ -107,6 +97,7 @@ bool QuicFramerPeer::ProcessIetfConnectionCloseFrame(
QuicConnectionCloseFrame* frame) {
return framer->ProcessIetfConnectionCloseFrame(reader, frame_type, frame);
}
+
// static
bool QuicFramerPeer::ProcessIetfApplicationCloseFrame(
QuicFramer* framer,
@@ -117,6 +108,176 @@ bool QuicFramerPeer::ProcessIetfApplicationCloseFrame(
}
// static
+bool QuicFramerPeer::AppendIetfPaddingFrame(QuicFramer* framer,
+ const QuicPaddingFrame& frame,
+ QuicDataWriter* writer) {
+ return framer->AppendIetfPaddingFrame(frame, writer);
+}
+
+// static
+void QuicFramerPeer::ProcessIetfPaddingFrame(QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicPaddingFrame* frame) {
+ framer->ProcessIetfPaddingFrame(reader, frame);
+}
+
+// static
+bool QuicFramerPeer::ProcessIetfPathChallengeFrame(
+ QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicPathChallengeFrame* frame) {
+ return framer->ProcessIetfPathChallengeFrame(reader, frame);
+}
+
+// static
+bool QuicFramerPeer::ProcessIetfPathResponseFrame(
+ QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicPathResponseFrame* frame) {
+ return framer->ProcessIetfPathResponseFrame(reader, frame);
+}
+
+// static
+bool QuicFramerPeer::AppendIetfPathChallengeFrame(
+ QuicFramer* framer,
+ const QuicPathChallengeFrame& frame,
+ QuicDataWriter* writer) {
+ return framer->AppendIetfPathChallengeFrame(frame, writer);
+}
+
+// static
+bool QuicFramerPeer::AppendIetfPathResponseFrame(
+ QuicFramer* framer,
+ const QuicPathResponseFrame& frame,
+ QuicDataWriter* writer) {
+ return framer->AppendIetfPathResponseFrame(frame, writer);
+}
+
+// static
+bool QuicFramerPeer::AppendIetfResetStreamFrame(QuicFramer* framer,
+ const QuicRstStreamFrame& frame,
+ QuicDataWriter* writer) {
+ return framer->AppendIetfResetStreamFrame(frame, writer);
+}
+
+// static
+bool QuicFramerPeer::ProcessIetfResetStreamFrame(QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicRstStreamFrame* frame) {
+ return framer->ProcessIetfResetStreamFrame(reader, frame);
+}
+
+// static
+bool QuicFramerPeer::ProcessIetfStopSendingFrame(
+ QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicStopSendingFrame* stop_sending_frame) {
+ return framer->ProcessIetfStopSendingFrame(reader, stop_sending_frame);
+}
+
+// static
+bool QuicFramerPeer::AppendIetfStopSendingFrame(
+ QuicFramer* framer,
+ const QuicStopSendingFrame& stop_sending_frame,
+ QuicDataWriter* writer) {
+ return framer->AppendIetfStopSendingFrame(stop_sending_frame, writer);
+}
+
+// Append/consume IETF-Format MAX_DATA and MAX_STREAM_DATA frames
+// static
+// static
+bool QuicFramerPeer::AppendIetfMaxDataFrame(QuicFramer* framer,
+ const QuicWindowUpdateFrame& frame,
+ QuicDataWriter* writer) {
+ return framer->AppendIetfMaxDataFrame(frame, writer);
+}
+
+// static
+bool QuicFramerPeer::AppendIetfMaxStreamDataFrame(
+ QuicFramer* framer,
+ const QuicWindowUpdateFrame& frame,
+ QuicDataWriter* writer) {
+ return framer->AppendIetfMaxStreamDataFrame(frame, writer);
+}
+
+// static
+bool QuicFramerPeer::ProcessIetfMaxDataFrame(QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicWindowUpdateFrame* frame) {
+ return framer->ProcessIetfMaxDataFrame(reader, frame);
+}
+
+// static
+bool QuicFramerPeer::ProcessIetfMaxStreamDataFrame(
+ QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicWindowUpdateFrame* frame) {
+ return framer->ProcessIetfMaxStreamDataFrame(reader, frame);
+}
+
+// static
+bool QuicFramerPeer::AppendIetfMaxStreamIdFrame(
+ QuicFramer* framer,
+ const QuicIetfMaxStreamIdFrame& frame,
+ QuicDataWriter* writer) {
+ return framer->AppendIetfMaxStreamIdFrame(frame, writer);
+}
+
+// static
+bool QuicFramerPeer::ProcessIetfMaxStreamIdFrame(
+ QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicIetfMaxStreamIdFrame* frame) {
+ return framer->ProcessIetfMaxStreamIdFrame(reader, frame);
+}
+
+// static
+bool QuicFramerPeer::AppendIetfBlockedFrame(QuicFramer* framer,
+ const QuicIetfBlockedFrame& frame,
+ QuicDataWriter* writer) {
+ return framer->AppendIetfBlockedFrame(frame, writer);
+}
+
+// static
+bool QuicFramerPeer::ProcessIetfBlockedFrame(QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicIetfBlockedFrame* frame) {
+ return framer->ProcessIetfBlockedFrame(reader, frame);
+}
+
+// static
+bool QuicFramerPeer::AppendIetfStreamBlockedFrame(
+ QuicFramer* framer,
+ const QuicWindowUpdateFrame& frame,
+ QuicDataWriter* writer) {
+ return framer->AppendIetfStreamBlockedFrame(frame, writer);
+}
+
+// static
+bool QuicFramerPeer::ProcessIetfStreamBlockedFrame(
+ QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicWindowUpdateFrame* frame) {
+ return framer->ProcessIetfStreamBlockedFrame(reader, frame);
+}
+
+// static
+bool QuicFramerPeer::AppendIetfStreamIdBlockedFrame(
+ QuicFramer* framer,
+ const QuicIetfStreamIdBlockedFrame& frame,
+ QuicDataWriter* writer) {
+ return framer->AppendIetfStreamIdBlockedFrame(frame, writer);
+}
+
+// static
+bool QuicFramerPeer::ProcessIetfStreamIdBlockedFrame(
+ QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicIetfStreamIdBlockedFrame* frame) {
+ return framer->ProcessIetfStreamIdBlockedFrame(reader, frame);
+}
+
+// static
void QuicFramerPeer::SwapCrypters(QuicFramer* framer1, QuicFramer* framer2) {
for (int i = ENCRYPTION_NONE; i < NUM_ENCRYPTION_LEVELS; i++) {
framer1->encrypter_[i].swap(framer2->encrypter_[i]);
diff --git a/chromium/net/quic/test_tools/quic_framer_peer.h b/chromium/net/quic/test_tools/quic_framer_peer.h
index de18e9e959f..a4372d2ab12 100644
--- a/chromium/net/quic/test_tools/quic_framer_peer.h
+++ b/chromium/net/quic/test_tools/quic_framer_peer.h
@@ -47,19 +47,10 @@ class QuicFramerPeer {
QuicFramer* framer,
const QuicConnectionCloseFrame& frame,
QuicDataWriter* writer);
- static bool AppendIetfConnectionCloseFrame(
- QuicFramer* framer,
- const QuicIetfTransportErrorCodes code,
- const std::string& phrase,
- QuicDataWriter* writer);
static bool AppendIetfApplicationCloseFrame(
QuicFramer* framer,
const QuicConnectionCloseFrame& frame,
QuicDataWriter* writer);
- static bool AppendIetfApplicationCloseFrame(QuicFramer* framer,
- const uint16_t code,
- const std::string& phrase,
- QuicDataWriter* writer);
static bool ProcessIetfConnectionCloseFrame(QuicFramer* framer,
QuicDataReader* reader,
const uint8_t frame_type,
@@ -68,14 +59,92 @@ class QuicFramerPeer {
QuicDataReader* reader,
const uint8_t frame_type,
QuicConnectionCloseFrame* frame);
-
static bool ProcessIetfAckFrame(QuicFramer* framer,
QuicDataReader* reader,
uint8_t frame_type,
QuicAckFrame* ack_frame);
- static bool AppendIetfAckFrameAndTypeByte(QuicFramer* framer,
- const QuicAckFrame& frame,
- QuicDataWriter* writer);
+ static bool AppendIetfAckFrame(QuicFramer* framer,
+ const QuicAckFrame& frame,
+ QuicDataWriter* writer);
+ static bool AppendIetfResetStreamFrame(QuicFramer* framer,
+ const QuicRstStreamFrame& frame,
+ QuicDataWriter* writer);
+ static bool ProcessIetfResetStreamFrame(QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicRstStreamFrame* frame);
+
+ // Add/remove IETF-Format padding.
+ static bool AppendIetfPaddingFrame(QuicFramer* framer,
+ const QuicPaddingFrame& frame,
+ QuicDataWriter* writer);
+ static void ProcessIetfPaddingFrame(QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicPaddingFrame* frame);
+
+ static bool ProcessIetfPathChallengeFrame(QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicPathChallengeFrame* frame);
+ static bool ProcessIetfPathResponseFrame(QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicPathResponseFrame* frame);
+
+ static bool AppendIetfPathChallengeFrame(QuicFramer* framer,
+ const QuicPathChallengeFrame& frame,
+ QuicDataWriter* writer);
+ static bool AppendIetfPathResponseFrame(QuicFramer* framer,
+ const QuicPathResponseFrame& frame,
+ QuicDataWriter* writer);
+
+ static bool ProcessIetfStopSendingFrame(
+ QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicStopSendingFrame* stop_sending_frame);
+ static bool AppendIetfStopSendingFrame(
+ QuicFramer* framer,
+ const QuicStopSendingFrame& stop_sending_frame,
+ QuicDataWriter* writer);
+
+ // Append/consume IETF-Format MAX_DATA and MAX_STREAM_DATA frames
+ static bool AppendIetfMaxDataFrame(QuicFramer* framer,
+ const QuicWindowUpdateFrame& frame,
+ QuicDataWriter* writer);
+ static bool AppendIetfMaxStreamDataFrame(QuicFramer* framer,
+ const QuicWindowUpdateFrame& frame,
+ QuicDataWriter* writer);
+ static bool ProcessIetfMaxDataFrame(QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicWindowUpdateFrame* frame);
+ static bool ProcessIetfMaxStreamDataFrame(QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicWindowUpdateFrame* frame);
+ static bool AppendIetfMaxStreamIdFrame(QuicFramer* framer,
+ const QuicIetfMaxStreamIdFrame& frame,
+ QuicDataWriter* writer);
+ static bool ProcessIetfMaxStreamIdFrame(QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicIetfMaxStreamIdFrame* frame);
+ static bool AppendIetfBlockedFrame(QuicFramer* framer,
+ const QuicIetfBlockedFrame& frame,
+ QuicDataWriter* writer);
+ static bool ProcessIetfBlockedFrame(QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicIetfBlockedFrame* frame);
+
+ static bool AppendIetfStreamBlockedFrame(QuicFramer* framer,
+ const QuicWindowUpdateFrame& frame,
+ QuicDataWriter* writer);
+ static bool ProcessIetfStreamBlockedFrame(QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicWindowUpdateFrame* frame);
+
+ static bool AppendIetfStreamIdBlockedFrame(
+ QuicFramer* framer,
+ const QuicIetfStreamIdBlockedFrame& frame,
+ QuicDataWriter* writer);
+ static bool ProcessIetfStreamIdBlockedFrame(
+ QuicFramer* framer,
+ QuicDataReader* reader,
+ QuicIetfStreamIdBlockedFrame* frame);
private:
DISALLOW_COPY_AND_ASSIGN(QuicFramerPeer);
diff --git a/chromium/net/quic/test_tools/quic_packet_creator_peer.cc b/chromium/net/quic/test_tools/quic_packet_creator_peer.cc
index b502a9b97b4..62e482a891f 100644
--- a/chromium/net/quic/test_tools/quic_packet_creator_peer.cc
+++ b/chromium/net/quic/test_tools/quic_packet_creator_peer.cc
@@ -11,7 +11,7 @@ namespace test {
// static
bool QuicPacketCreatorPeer::SendVersionInPacket(QuicPacketCreator* creator) {
- return creator->send_version_in_packet_;
+ return creator->IncludeVersionInHeader();
}
// static
@@ -31,7 +31,7 @@ void QuicPacketCreatorPeer::SetPacketNumberLength(
// static
QuicPacketNumberLength QuicPacketCreatorPeer::GetPacketNumberLength(
QuicPacketCreator* creator) {
- return creator->packet_.packet_number_length;
+ return creator->GetPacketNumberLength();
}
void QuicPacketCreatorPeer::SetPacketNumber(QuicPacketCreator* creator,
diff --git a/chromium/net/quic/test_tools/quic_sent_packet_manager_peer.cc b/chromium/net/quic/test_tools/quic_sent_packet_manager_peer.cc
index 8650eabf115..0999690a659 100644
--- a/chromium/net/quic/test_tools/quic_sent_packet_manager_peer.cc
+++ b/chromium/net/quic/test_tools/quic_sent_packet_manager_peer.cc
@@ -113,12 +113,26 @@ void QuicSentPacketManagerPeer::MarkForRetransmission(
// static
QuicTime::Delta QuicSentPacketManagerPeer::GetRetransmissionDelay(
+ const QuicSentPacketManager* sent_packet_manager,
+ size_t consecutive_rto_count) {
+ return sent_packet_manager->GetRetransmissionDelay(consecutive_rto_count);
+}
+
+// static
+QuicTime::Delta QuicSentPacketManagerPeer::GetRetransmissionDelay(
const QuicSentPacketManager* sent_packet_manager) {
return sent_packet_manager->GetRetransmissionDelay();
}
// static
QuicTime::Delta QuicSentPacketManagerPeer::GetTailLossProbeDelay(
+ const QuicSentPacketManager* sent_packet_manager,
+ size_t consecutive_tlp_count) {
+ return sent_packet_manager->GetTailLossProbeDelay(consecutive_tlp_count);
+}
+
+// static
+QuicTime::Delta QuicSentPacketManagerPeer::GetTailLossProbeDelay(
const QuicSentPacketManager* sent_packet_manager) {
return sent_packet_manager->GetTailLossProbeDelay();
}
diff --git a/chromium/net/quic/test_tools/quic_sent_packet_manager_peer.h b/chromium/net/quic/test_tools/quic_sent_packet_manager_peer.h
index 713ae888e6d..d1363ef2c7a 100644
--- a/chromium/net/quic/test_tools/quic_sent_packet_manager_peer.h
+++ b/chromium/net/quic/test_tools/quic_sent_packet_manager_peer.h
@@ -57,8 +57,14 @@ class QuicSentPacketManagerPeer {
TransmissionType transmission_type);
static QuicTime::Delta GetRetransmissionDelay(
+ const QuicSentPacketManager* sent_packet_manager,
+ size_t consecutive_rto_count);
+ static QuicTime::Delta GetRetransmissionDelay(
const QuicSentPacketManager* sent_packet_manager);
static QuicTime::Delta GetTailLossProbeDelay(
+ const QuicSentPacketManager* sent_packet_manager,
+ size_t consecutive_tlp_count);
+ static QuicTime::Delta GetTailLossProbeDelay(
const QuicSentPacketManager* sent_packet_manager);
static bool HasUnackedCryptoPackets(
diff --git a/chromium/net/quic/test_tools/quic_stream_send_buffer_peer.cc b/chromium/net/quic/test_tools/quic_stream_send_buffer_peer.cc
index 5ca41adbfd2..7bb4410d467 100644
--- a/chromium/net/quic/test_tools/quic_stream_send_buffer_peer.cc
+++ b/chromium/net/quic/test_tools/quic_stream_send_buffer_peer.cc
@@ -23,6 +23,17 @@ const BufferedSlice* QuicStreamSendBufferPeer::CurrentWriteSlice(
}
return &send_buffer->buffered_slices_[send_buffer->write_index_];
}
+
+// static
+QuicByteCount QuicStreamSendBufferPeer::TotalLength(
+ QuicStreamSendBuffer* send_buffer) {
+ QuicByteCount length = 0;
+ for (const auto& slice : send_buffer->buffered_slices_) {
+ length += slice.slice.length();
+ }
+ return length;
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/quic/test_tools/quic_stream_send_buffer_peer.h b/chromium/net/quic/test_tools/quic_stream_send_buffer_peer.h
index 6b8b115e718..54c53e9c534 100644
--- a/chromium/net/quic/test_tools/quic_stream_send_buffer_peer.h
+++ b/chromium/net/quic/test_tools/quic_stream_send_buffer_peer.h
@@ -18,6 +18,8 @@ class QuicStreamSendBufferPeer {
static const BufferedSlice* CurrentWriteSlice(
QuicStreamSendBuffer* send_buffer);
+
+ static QuicByteCount TotalLength(QuicStreamSendBuffer* send_buffer);
};
} // namespace test
diff --git a/chromium/net/quic/test_tools/quic_test_utils.cc b/chromium/net/quic/test_tools/quic_test_utils.cc
index c3546dfc861..60a70cca68a 100644
--- a/chromium/net/quic/test_tools/quic_test_utils.cc
+++ b/chromium/net/quic/test_tools/quic_test_utils.cc
@@ -233,6 +233,10 @@ bool NoOpFramerVisitor::OnBlockedFrame(const QuicBlockedFrame& frame) {
return true;
}
+bool NoOpFramerVisitor::IsValidStatelessResetToken(uint128 token) const {
+ return false;
+}
+
MockQuicConnectionVisitor::MockQuicConnectionVisitor() {}
MockQuicConnectionVisitor::~MockQuicConnectionVisitor() {}
@@ -374,9 +378,14 @@ void PacketSavingConnection::SendOrQueuePacket(SerializedPacket* packet) {
}
MockQuicSession::MockQuicSession(QuicConnection* connection)
+ : MockQuicSession(connection, true) {}
+
+MockQuicSession::MockQuicSession(QuicConnection* connection,
+ bool create_mock_crypto_stream)
: QuicSession(connection, nullptr, DefaultQuicConfig()) {
- crypto_stream_ = QuicMakeUnique<MockQuicCryptoStream>(this);
- Initialize();
+ if (create_mock_crypto_stream) {
+ crypto_stream_ = QuicMakeUnique<MockQuicCryptoStream>(this);
+ }
ON_CALL(*this, WritevData(_, _, _, _, _))
.WillByDefault(testing::Return(QuicConsumedData(0, false)));
}
@@ -393,6 +402,10 @@ const QuicCryptoStream* MockQuicSession::GetCryptoStream() const {
return crypto_stream_.get();
}
+void MockQuicSession::SetCryptoStream(QuicCryptoStream* crypto_stream) {
+ crypto_stream_.reset(crypto_stream);
+}
+
// static
QuicConsumedData MockQuicSession::ConsumeData(QuicStream* stream,
QuicStreamId /*id*/,
@@ -432,9 +445,15 @@ CryptoMessageParser* MockQuicCryptoStream::crypto_message_parser() {
}
MockQuicSpdySession::MockQuicSpdySession(QuicConnection* connection)
+ : MockQuicSpdySession(connection, true) {}
+
+MockQuicSpdySession::MockQuicSpdySession(QuicConnection* connection,
+ bool create_mock_crypto_stream)
: QuicSpdySession(connection, nullptr, DefaultQuicConfig()) {
- crypto_stream_ = QuicMakeUnique<MockQuicCryptoStream>(this);
- Initialize();
+ if (create_mock_crypto_stream) {
+ crypto_stream_ = QuicMakeUnique<MockQuicCryptoStream>(this);
+ }
+
ON_CALL(*this, WritevData(_, _, _, _, _))
.WillByDefault(testing::Return(QuicConsumedData(0, false)));
}
@@ -451,6 +470,10 @@ const QuicCryptoStream* MockQuicSpdySession::GetCryptoStream() const {
return crypto_stream_.get();
}
+void MockQuicSpdySession::SetCryptoStream(QuicCryptoStream* crypto_stream) {
+ crypto_stream_.reset(crypto_stream);
+}
+
size_t MockQuicSpdySession::WriteHeaders(
QuicStreamId id,
SpdyHeaderBlock headers,
@@ -642,7 +665,7 @@ QuicEncryptedPacket* ConstructEncryptedPacket(QuicConnectionId connection_id,
const string& data) {
return ConstructEncryptedPacket(
connection_id, version_flag, reset_flag, packet_number, data,
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER);
+ PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER);
}
QuicEncryptedPacket* ConstructEncryptedPacket(
diff --git a/chromium/net/quic/test_tools/quic_test_utils.h b/chromium/net/quic/test_tools/quic_test_utils.h
index 8544ec8dbec..9d2b75a0455 100644
--- a/chromium/net/quic/test_tools/quic_test_utils.h
+++ b/chromium/net/quic/test_tools/quic_test_utils.h
@@ -107,7 +107,7 @@ QuicEncryptedPacket* ConstructEncryptedPacket(
QuicPacketNumberLength packet_number_length);
// This form assumes |connection_id_length| == PACKET_8BYTE_CONNECTION_ID,
-// |packet_number_length| == PACKET_6BYTE_PACKET_NUMBER and
+// |packet_number_length| == PACKET_4BYTE_PACKET_NUMBER and
// |versions| == nullptr.
QuicEncryptedPacket* ConstructEncryptedPacket(QuicConnectionId connection_id,
bool version_flag,
@@ -260,6 +260,9 @@ class MockFramerVisitor : public QuicFramerVisitorInterface {
MOCK_METHOD1(OnWindowUpdateFrame, bool(const QuicWindowUpdateFrame& frame));
MOCK_METHOD1(OnBlockedFrame, bool(const QuicBlockedFrame& frame));
MOCK_METHOD0(OnPacketComplete, void());
+ MOCK_CONST_METHOD1(IsValidStatelessResetToken, bool(uint128));
+ MOCK_METHOD1(OnAuthenticatedIetfStatelessResetPacket,
+ void(const QuicIetfStatelessResetPacket&));
private:
DISALLOW_COPY_AND_ASSIGN(MockFramerVisitor);
@@ -295,6 +298,9 @@ class NoOpFramerVisitor : public QuicFramerVisitorInterface {
bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
void OnPacketComplete() override {}
+ bool IsValidStatelessResetToken(uint128 token) const override;
+ void OnAuthenticatedIetfStatelessResetPacket(
+ const QuicIetfStatelessResetPacket& packet) override {}
private:
DISALLOW_COPY_AND_ASSIGN(NoOpFramerVisitor);
@@ -332,6 +338,7 @@ class MockQuicConnectionVisitor : public QuicConnectionVisitorInterface {
MOCK_METHOD0(OnAckNeedsRetransmittableFrame, void());
MOCK_METHOD0(SendPing, void());
MOCK_CONST_METHOD0(AllowSelfAddressChange, bool());
+ MOCK_METHOD0(OnForwardProgressConfirmed, void());
private:
DISALLOW_COPY_AND_ASSIGN(MockQuicConnectionVisitor);
@@ -470,11 +477,6 @@ class MockQuicConnection : public QuicConnection {
bool ReallySendControlFrame(const QuicFrame& frame) {
return QuicConnection::SendControlFrame(frame);
}
- void ReallySendGoAway(QuicErrorCode error,
- QuicStreamId last_good_stream_id,
- const std::string& reason) {
- QuicConnection::SendGoAway(error, last_good_stream_id, reason);
- }
bool ReallySendConnectivityProbingPacket(
QuicPacketWriter* probing_writer,
@@ -511,11 +513,15 @@ class PacketSavingConnection : public MockQuicConnection {
class MockQuicSession : public QuicSession {
public:
// Takes ownership of |connection|.
+ MockQuicSession(QuicConnection* connection, bool create_mock_crypto_stream);
+
+ // Takes ownership of |connection|.
explicit MockQuicSession(QuicConnection* connection);
~MockQuicSession() override;
QuicCryptoStream* GetMutableCryptoStream() override;
const QuicCryptoStream* GetCryptoStream() const override;
+ void SetCryptoStream(QuicCryptoStream* crypto_stream);
MOCK_METHOD3(OnConnectionClosed,
void(QuicErrorCode error,
@@ -582,10 +588,14 @@ class MockQuicSpdySession : public QuicSpdySession {
public:
// Takes ownership of |connection|.
explicit MockQuicSpdySession(QuicConnection* connection);
+ // Takes ownership of |connection|.
+ MockQuicSpdySession(QuicConnection* connection,
+ bool create_mock_crypto_stream);
~MockQuicSpdySession() override;
QuicCryptoStream* GetMutableCryptoStream() override;
const QuicCryptoStream* GetCryptoStream() const override;
+ void SetCryptoStream(QuicCryptoStream* crypto_stream);
const SpdyHeaderBlock& GetWriteHeaders() { return write_headers_; }
// From QuicSession.
@@ -775,6 +785,8 @@ class MockSendAlgorithm : public SendAlgorithmInterface {
MOCK_METHOD2(SetFromConfig,
void(const QuicConfig& config, Perspective perspective));
MOCK_METHOD1(SetNumEmulatedConnections, void(int num_connections));
+ MOCK_METHOD1(SetInitialCongestionWindowInPackets,
+ void(QuicPacketCount packets));
MOCK_METHOD1(SetMaxCongestionWindow,
void(QuicByteCount max_congestion_window));
MOCK_METHOD5(OnCongestionEvent,
@@ -858,6 +870,8 @@ class MockNetworkChangeVisitor
~MockNetworkChangeVisitor() override;
MOCK_METHOD0(OnCongestionChange, void());
+ // TODO(b/76462509): remove OnPathDegrading() once
+ // FLAGS_quic_reloadable_flag_quic_path_degrading_alarm is deprecated.
MOCK_METHOD0(OnPathDegrading, void());
MOCK_METHOD1(OnPathMtuIncreased, void(QuicPacketLength));
@@ -891,8 +905,7 @@ class MockQuicConnectionDebugVisitor : public QuicConnectionDebugVisitor {
MOCK_METHOD1(OnPacketHeader, void(const QuicPacketHeader& header));
- MOCK_METHOD1(OnSuccessfulVersionNegotiation,
- void(const QuicTransportVersion&));
+ MOCK_METHOD1(OnSuccessfulVersionNegotiation, void(const ParsedQuicVersion&));
MOCK_METHOD1(OnStreamFrame, void(const QuicStreamFrame&));
diff --git a/chromium/net/quic/test_tools/simple_quic_framer.cc b/chromium/net/quic/test_tools/simple_quic_framer.cc
index a92c0075d01..405cfde0bdf 100644
--- a/chromium/net/quic/test_tools/simple_quic_framer.cc
+++ b/chromium/net/quic/test_tools/simple_quic_framer.cc
@@ -127,6 +127,16 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
void OnPacketComplete() override {}
+ bool IsValidStatelessResetToken(uint128 token) const override {
+ return false;
+ }
+
+ void OnAuthenticatedIetfStatelessResetPacket(
+ const QuicIetfStatelessResetPacket& packet) override {
+ stateless_reset_packet_ =
+ QuicMakeUnique<QuicIetfStatelessResetPacket>(packet);
+ }
+
const QuicPacketHeader& header() const { return header_; }
const std::vector<QuicAckFrame>& ack_frames() const { return ack_frames_; }
const std::vector<QuicConnectionCloseFrame>& connection_close_frames() const {
@@ -161,6 +171,7 @@ class SimpleFramerVisitor : public QuicFramerVisitorInterface {
QuicPacketHeader header_;
std::unique_ptr<QuicVersionNegotiationPacket> version_negotiation_packet_;
std::unique_ptr<QuicPublicResetPacket> public_reset_packet_;
+ std::unique_ptr<QuicIetfStatelessResetPacket> stateless_reset_packet_;
std::vector<QuicAckFrame> ack_frames_;
std::vector<QuicStopWaitingFrame> stop_waiting_frames_;
std::vector<QuicPaddingFrame> padding_frames_;
diff --git a/chromium/net/quic/test_tools/simple_session_notifier.cc b/chromium/net/quic/test_tools/simple_session_notifier.cc
index 61ba9238349..689a6599c12 100644
--- a/chromium/net/quic/test_tools/simple_session_notifier.cc
+++ b/chromium/net/quic/test_tools/simple_session_notifier.cc
@@ -24,18 +24,6 @@ SimpleSessionNotifier::~SimpleSessionNotifier() {
}
}
-std::ostream& operator<<(std::ostream& os,
- const SimpleSessionNotifier::StreamState& s) {
- os << "bytes_total: " << s.bytes_total << " bytes_sent: " << s.bytes_sent
- << " bytes_acked " << s.bytes_acked
- << " pending_retransmissions: " << s.pending_retransmissions
- << " fin_buffered: " << s.fin_buffered << " fin_sent: " << s.fin_sent
- << " fin_outstanding: " << s.fin_outstanding
- << " fin_lost: " << s.fin_lost;
-
- return os;
-}
-
SimpleSessionNotifier::StreamState::StreamState()
: bytes_total(0),
bytes_sent(0),
@@ -477,7 +465,7 @@ bool SimpleSessionNotifier::RetransmitLostStreamData() {
}
if (length > consumed.bytes_consumed ||
(can_bundle_fin && !consumed.fin_consumed)) {
- DLOG(INFO) << "Connection is write blocked";
+ DVLOG(1) << "Connection is write blocked";
break;
}
}
diff --git a/chromium/net/quic/test_tools/simple_session_notifier.h b/chromium/net/quic/test_tools/simple_session_notifier.h
index b5700286540..845e2eca3b2 100644
--- a/chromium/net/quic/test_tools/simple_session_notifier.h
+++ b/chromium/net/quic/test_tools/simple_session_notifier.h
@@ -31,9 +31,6 @@ class SimpleSessionNotifier : public SessionNotifierInterface {
QuicRstStreamErrorCode error,
QuicStreamOffset bytes_written);
- // Called when |frame| is sent.
- void OnControlFrameSent(const QuicFrame& frame);
-
// Neuters unencrypted data of crypto stream.
void NeuterUnencryptedData();
diff --git a/chromium/net/quic/test_tools/simple_session_notifier_test.cc b/chromium/net/quic/test_tools/simple_session_notifier_test.cc
index 0b0f6630cf6..545ae483f8b 100644
--- a/chromium/net/quic/test_tools/simple_session_notifier_test.cc
+++ b/chromium/net/quic/test_tools/simple_session_notifier_test.cc
@@ -29,13 +29,6 @@ class MockQuicConnectionWithSendStreamData : public MockQuicConnection {
size_t write_length,
QuicStreamOffset offset,
StreamSendingState state));
-
- static QuicConsumedData ConsumeAllData(QuicStreamId /*id*/,
- size_t write_length,
- QuicStreamOffset /*offset*/,
- StreamSendingState state) {
- return QuicConsumedData(write_length, state != NO_FIN);
- }
};
class SimpleSessionNotifierTest : public QuicTest {
diff --git a/chromium/net/quic/test_tools/simulator/quic_endpoint.cc b/chromium/net/quic/test_tools/simulator/quic_endpoint.cc
index 2b46e83858a..a02af996c48 100644
--- a/chromium/net/quic/test_tools/simulator/quic_endpoint.cc
+++ b/chromium/net/quic/test_tools/simulator/quic_endpoint.cc
@@ -84,9 +84,9 @@ QuicEndpoint::QuicEndpoint(Simulator* simulator,
connection_.SetSelfAddress(GetAddressFromName(name));
connection_.set_visitor(this);
connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- new NullEncrypter(perspective));
+ QuicMakeUnique<NullEncrypter>(perspective));
connection_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- new NullDecrypter(perspective));
+ QuicMakeUnique<NullDecrypter>(perspective));
connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
connection_.SetDataProducer(&producer_);
connection_.SetSessionNotifier(this);
diff --git a/chromium/net/quic/test_tools/simulator/quic_endpoint.h b/chromium/net/quic/test_tools/simulator/quic_endpoint.h
index bd983e4d593..c064560fee6 100644
--- a/chromium/net/quic/test_tools/simulator/quic_endpoint.h
+++ b/chromium/net/quic/test_tools/simulator/quic_endpoint.h
@@ -98,6 +98,7 @@ class QuicEndpoint : public Endpoint,
void OnAckNeedsRetransmittableFrame() override {}
void SendPing() override {}
bool AllowSelfAddressChange() const override;
+ void OnForwardProgressConfirmed() override {}
// End QuicConnectionVisitorInterface implementation.
// Begin SessionNotifierInterface methods:
diff --git a/chromium/net/quic/test_tools/simulator/quic_endpoint_test.cc b/chromium/net/quic/test_tools/simulator/quic_endpoint_test.cc
index 2d8c87ee6b0..edff605c9b5 100644
--- a/chromium/net/quic/test_tools/simulator/quic_endpoint_test.cc
+++ b/chromium/net/quic/test_tools/simulator/quic_endpoint_test.cc
@@ -177,7 +177,7 @@ TEST_F(QuicEndpointTest, Competition) {
endpoint_b->AddBytesToTransfer(2 * 1024 * 1024);
endpoint_c->AddBytesToTransfer(2 * 1024 * 1024);
QuicTime end_time =
- simulator_.GetClock()->Now() + QuicTime::Delta::FromSeconds(8);
+ simulator_.GetClock()->Now() + QuicTime::Delta::FromSeconds(10);
simulator_.RunUntil(
[this, end_time]() { return simulator_.GetClock()->Now() >= end_time; });
diff --git a/chromium/net/reporting/reporting_browsing_data_remover_unittest.cc b/chromium/net/reporting/reporting_browsing_data_remover_unittest.cc
index 3d8d10d8122..7e720e98ff9 100644
--- a/chromium/net/reporting/reporting_browsing_data_remover_unittest.cc
+++ b/chromium/net/reporting/reporting_browsing_data_remover_unittest.cc
@@ -41,7 +41,7 @@ class ReportingBrowsingDataRemoverTest : public ReportingTestBase {
void AddReport(const GURL& url) {
cache()->AddReport(url, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
}
diff --git a/chromium/net/reporting/reporting_cache.cc b/chromium/net/reporting/reporting_cache.cc
index 14a61c28720..61fbd3947b8 100644
--- a/chromium/net/reporting/reporting_cache.cc
+++ b/chromium/net/reporting/reporting_cache.cc
@@ -42,6 +42,11 @@ std::string GetSuperdomain(const std::string& domain) {
return domain.substr(dot_pos + 1);
}
+struct ClientMetadata {
+ base::TimeTicks last_used;
+ ReportingCache::ClientStatistics stats;
+};
+
class ReportingCacheImpl : public ReportingCache {
public:
ReportingCacheImpl(ReportingContext* context) : context_(context) {
@@ -67,10 +72,11 @@ class ReportingCacheImpl : public ReportingCache {
const std::string& group,
const std::string& type,
std::unique_ptr<const base::Value> body,
+ int depth,
base::TimeTicks queued,
int attempts) override {
auto report = std::make_unique<ReportingReport>(
- url, group, type, std::move(body), queued, attempts);
+ url, group, type, std::move(body), depth, queued, attempts);
auto inserted =
reports_.insert(std::make_pair(report.get(), std::move(report)));
@@ -146,6 +152,31 @@ class ReportingCacheImpl : public ReportingCache {
context_->NotifyCacheUpdated();
}
+ void IncrementEndpointDeliveries(
+ const GURL& endpoint,
+ const std::vector<const ReportingReport*>& reports,
+ bool successful) override {
+ std::unordered_map<const ReportingClient*, int> reports_per_client;
+ for (const ReportingReport* report : reports) {
+ DCHECK(base::ContainsKey(reports_, report));
+ url::Origin origin = url::Origin::Create(report->url);
+ const ReportingClient* client =
+ GetClientByOriginAndEndpoint(origin, endpoint);
+ DCHECK(client);
+ reports_per_client[client]++;
+ }
+
+ for (const auto& client_and_report_count : reports_per_client) {
+ auto& metadata = client_metadata_[client_and_report_count.first];
+ metadata.stats.attempted_uploads++;
+ metadata.stats.attempted_reports += client_and_report_count.second;
+ if (successful) {
+ metadata.stats.successful_uploads++;
+ metadata.stats.successful_reports += client_and_report_count.second;
+ }
+ }
+ }
+
void RemoveReports(const std::vector<const ReportingReport*>& reports,
ReportingReport::Outcome outcome) override {
for (const ReportingReport* report : reports) {
@@ -192,7 +223,7 @@ class ReportingCacheImpl : public ReportingCache {
const ReportingClient* old_client =
GetClientByOriginAndEndpoint(origin, endpoint);
if (old_client) {
- last_used = client_last_used_[old_client];
+ last_used = client_metadata_[old_client].last_used;
RemoveClient(old_client);
}
@@ -201,10 +232,10 @@ class ReportingCacheImpl : public ReportingCache {
expires, priority, weight),
last_used);
- if (client_last_used_.size() > context_->policy().max_client_count) {
+ if (client_metadata_.size() > context_->policy().max_client_count) {
// There should only ever be one extra client, added above.
DCHECK_EQ(context_->policy().max_client_count + 1,
- client_last_used_.size());
+ client_metadata_.size());
// And that shouldn't happen if it was replaced, not added.
DCHECK(!old_client);
const ReportingClient* to_evict =
@@ -221,7 +252,7 @@ class ReportingCacheImpl : public ReportingCache {
const ReportingClient* client =
GetClientByOriginAndEndpoint(origin, endpoint);
DCHECK(client);
- client_last_used_[client] = tick_clock()->NowTicks();
+ client_metadata_[client].last_used = tick_clock()->NowTicks();
}
void GetClients(
@@ -304,11 +335,23 @@ class ReportingCacheImpl : public ReportingCache {
void RemoveAllClients() override {
clients_.clear();
wildcard_clients_.clear();
- client_last_used_.clear();
+ client_metadata_.clear();
context_->NotifyCacheUpdated();
}
+ ClientStatistics GetStatisticsForOriginAndEndpoint(
+ const url::Origin& origin,
+ const GURL& endpoint) const override {
+ const ReportingClient* client =
+ GetClientByOriginAndEndpoint(origin, endpoint);
+ auto it = client_metadata_.find(client);
+ if (it == client_metadata_.end()) {
+ return ClientStatistics();
+ }
+ return it->second.stats;
+ }
+
size_t GetFullReportCountForTesting() const override {
return reports_.size();
}
@@ -350,9 +393,9 @@ class ReportingCacheImpl : public ReportingCache {
url::Origin origin = client->origin;
GURL endpoint = client->endpoint;
- auto inserted_last_used =
- client_last_used_.insert(std::make_pair(client.get(), last_used));
- DCHECK(inserted_last_used.second);
+ auto inserted_metadata = client_metadata_.insert(
+ std::make_pair(client.get(), ClientMetadata{last_used}));
+ DCHECK(inserted_metadata.second);
if (client->subdomains == ReportingClient::Subdomains::INCLUDE) {
const std::string& domain = origin.host();
@@ -382,8 +425,8 @@ class ReportingCacheImpl : public ReportingCache {
}
}
- size_t erased_last_used = client_last_used_.erase(client);
- DCHECK_EQ(1u, erased_last_used);
+ size_t erased_metadata = client_metadata_.erase(client);
+ DCHECK_EQ(1u, erased_metadata);
size_t erased_endpoint = clients_[origin].erase(endpoint);
DCHECK_EQ(1u, erased_endpoint);
@@ -425,15 +468,15 @@ class ReportingCacheImpl : public ReportingCache {
}
const ReportingClient* FindClientToEvict(base::TimeTicks now) const {
- DCHECK(!client_last_used_.empty());
+ DCHECK(!client_metadata_.empty());
const ReportingClient* earliest_used = nullptr;
base::TimeTicks earliest_used_last_used;
const ReportingClient* earliest_expired = nullptr;
- for (const auto& it : client_last_used_) {
+ for (const auto& it : client_metadata_) {
const ReportingClient* client = it.first;
- base::TimeTicks client_last_used = it.second;
+ base::TimeTicks client_last_used = it.second.last_used;
if (earliest_used == nullptr ||
client_last_used < earliest_used_last_used) {
earliest_used = client;
@@ -452,7 +495,7 @@ class ReportingCacheImpl : public ReportingCache {
return earliest_used;
}
- base::TickClock* tick_clock() { return context_->tick_clock(); }
+ const base::TickClock* tick_clock() { return context_->tick_clock(); }
ReportingContext* context_;
@@ -480,7 +523,7 @@ class ReportingCacheImpl : public ReportingCache {
wildcard_clients_;
// The time that each client has last been used.
- std::unordered_map<const ReportingClient*, base::TimeTicks> client_last_used_;
+ std::unordered_map<const ReportingClient*, ClientMetadata> client_metadata_;
};
} // namespace
diff --git a/chromium/net/reporting/reporting_cache.h b/chromium/net/reporting/reporting_cache.h
index e948748c375..6711577ef5e 100644
--- a/chromium/net/reporting/reporting_cache.h
+++ b/chromium/net/reporting/reporting_cache.h
@@ -35,6 +35,22 @@ class ReportingContext;
// "doomed", which will cause it to be deallocated once it is no longer pending.
class NET_EXPORT ReportingCache {
public:
+ // Information about the number of deliveries that we've attempted for each
+ // origin and endpoint.
+ struct ClientStatistics {
+ // The number of attempts uploads that we've made for this client.
+ int attempted_uploads = 0;
+ // The number of uploads that have succeeded for this client.
+ int successful_uploads = 0;
+ // The number of individual reports that we've attempted to upload for this
+ // client. (Failed uploads will cause a report to be counted multiple
+ // times, once for each attempt.)
+ int attempted_reports = 0;
+ // The number of individual reports that we've successfully uploaded for
+ // this client.
+ int successful_reports = 0;
+ };
+
static std::unique_ptr<ReportingCache> Create(ReportingContext* context);
virtual ~ReportingCache();
@@ -47,6 +63,7 @@ class NET_EXPORT ReportingCache {
const std::string& group,
const std::string& type,
std::unique_ptr<const base::Value> body,
+ int depth,
base::TimeTicks queued,
int attempts) = 0;
@@ -81,6 +98,13 @@ class NET_EXPORT ReportingCache {
virtual void IncrementReportsAttempts(
const std::vector<const ReportingReport*>& reports) = 0;
+ // Records that we attempted (and possibly succeeded at) delivering |reports|
+ // to |endpoint|.
+ virtual void IncrementEndpointDeliveries(
+ const GURL& endpoint,
+ const std::vector<const ReportingReport*>& reports,
+ bool successful) = 0;
+
// Removes a set of reports. Any reports that are pending will not be removed
// immediately, but rather marked doomed and removed once they are no longer
// pending.
@@ -164,6 +188,12 @@ class NET_EXPORT ReportingCache {
// Removes all clients.
virtual void RemoveAllClients() = 0;
+ // Returns information about the number of attempted and successful uploads
+ // for a particular origin and endpoint.
+ virtual ClientStatistics GetStatisticsForOriginAndEndpoint(
+ const url::Origin& origin,
+ const GURL& endpoint) const = 0;
+
// Gets the count of reports in the cache, *including* doomed reports.
//
// Needed to ensure that doomed reports are eventually deleted, since no
diff --git a/chromium/net/reporting/reporting_cache_unittest.cc b/chromium/net/reporting/reporting_cache_unittest.cc
index 6e447fcf01f..de65ee4e728 100644
--- a/chromium/net/reporting/reporting_cache_unittest.cc
+++ b/chromium/net/reporting/reporting_cache_unittest.cc
@@ -94,7 +94,7 @@ TEST_F(ReportingCacheTest, Reports) {
EXPECT_TRUE(reports.empty());
cache()->AddReport(kUrl1_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(), kNow_, 0);
+ std::make_unique<base::DictionaryValue>(), 0, kNow_, 0);
EXPECT_EQ(1, observer()->cache_update_count());
cache()->GetReports(&reports);
@@ -128,9 +128,9 @@ TEST_F(ReportingCacheTest, Reports) {
TEST_F(ReportingCacheTest, RemoveAllReports) {
cache()->AddReport(kUrl1_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(), kNow_, 0);
+ std::make_unique<base::DictionaryValue>(), 0, kNow_, 0);
cache()->AddReport(kUrl1_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(), kNow_, 0);
+ std::make_unique<base::DictionaryValue>(), 0, kNow_, 0);
EXPECT_EQ(2, observer()->cache_update_count());
std::vector<const ReportingReport*> reports;
@@ -146,7 +146,7 @@ TEST_F(ReportingCacheTest, RemoveAllReports) {
TEST_F(ReportingCacheTest, RemovePendingReports) {
cache()->AddReport(kUrl1_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(), kNow_, 0);
+ std::make_unique<base::DictionaryValue>(), 0, kNow_, 0);
EXPECT_EQ(1, observer()->cache_update_count());
std::vector<const ReportingReport*> reports;
@@ -177,7 +177,7 @@ TEST_F(ReportingCacheTest, RemovePendingReports) {
TEST_F(ReportingCacheTest, RemoveAllPendingReports) {
cache()->AddReport(kUrl1_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(), kNow_, 0);
+ std::make_unique<base::DictionaryValue>(), 0, kNow_, 0);
EXPECT_EQ(1, observer()->cache_update_count());
std::vector<const ReportingReport*> reports;
@@ -410,7 +410,7 @@ TEST_F(ReportingCacheTest, EvictOldestReport) {
// Enqueue the maximum number of reports, spaced apart in time.
for (size_t i = 0; i < max_report_count; ++i) {
cache()->AddReport(kUrl1_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
tick_clock()->Advance(base::TimeDelta::FromMinutes(1));
}
@@ -418,7 +418,7 @@ TEST_F(ReportingCacheTest, EvictOldestReport) {
// Add one more report to force the cache to evict one.
cache()->AddReport(kUrl1_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(), kNow_, 0);
+ std::make_unique<base::DictionaryValue>(), 0, kNow_, 0);
// Make sure the cache evicted a report to make room for the new one, and make
// sure the report evicted was the earliest-queued one.
@@ -438,7 +438,7 @@ TEST_F(ReportingCacheTest, DontEvictPendingReports) {
// Enqueue the maximum number of reports, spaced apart in time.
for (size_t i = 0; i < max_report_count; ++i) {
cache()->AddReport(kUrl1_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
tick_clock()->Advance(base::TimeDelta::FromMinutes(1));
}
@@ -452,7 +452,7 @@ TEST_F(ReportingCacheTest, DontEvictPendingReports) {
// Add one more report to force the cache to evict one. Since the cache has
// only pending reports, it will be forced to evict the *new* report!
cache()->AddReport(kUrl1_, kGroup1_, kType_,
- std::make_unique<base::DictionaryValue>(), kNow_, 0);
+ std::make_unique<base::DictionaryValue>(), 0, kNow_, 0);
// Make sure the cache evicted a report, and make sure the report evicted was
// the new, non-pending one.
diff --git a/chromium/net/reporting/reporting_context.cc b/chromium/net/reporting/reporting_context.cc
index 8f2a280e5b2..04ee3b5d2bb 100644
--- a/chromium/net/reporting/reporting_context.cc
+++ b/chromium/net/reporting/reporting_context.cc
@@ -72,7 +72,7 @@ void ReportingContext::NotifyCacheUpdated() {
ReportingContext::ReportingContext(const ReportingPolicy& policy,
base::Clock* clock,
- base::TickClock* tick_clock,
+ const base::TickClock* tick_clock,
const RandIntCallback& rand_callback,
std::unique_ptr<ReportingUploader> uploader,
std::unique_ptr<ReportingDelegate> delegate)
diff --git a/chromium/net/reporting/reporting_context.h b/chromium/net/reporting/reporting_context.h
index 9b4a6021279..8fff426c2c0 100644
--- a/chromium/net/reporting/reporting_context.h
+++ b/chromium/net/reporting/reporting_context.h
@@ -44,7 +44,7 @@ class NET_EXPORT ReportingContext {
const ReportingPolicy& policy() { return policy_; }
base::Clock* clock() { return clock_; }
- base::TickClock* tick_clock() { return tick_clock_; }
+ const base::TickClock* tick_clock() { return tick_clock_; }
ReportingUploader* uploader() { return uploader_.get(); }
ReportingDelegate* delegate() { return delegate_.get(); }
@@ -65,7 +65,7 @@ class NET_EXPORT ReportingContext {
protected:
ReportingContext(const ReportingPolicy& policy,
base::Clock* clock,
- base::TickClock* tick_clock,
+ const base::TickClock* tick_clock,
const RandIntCallback& rand_callback,
std::unique_ptr<ReportingUploader> uploader,
std::unique_ptr<ReportingDelegate> delegate);
@@ -74,7 +74,7 @@ class NET_EXPORT ReportingContext {
ReportingPolicy policy_;
base::Clock* clock_;
- base::TickClock* tick_clock_;
+ const base::TickClock* tick_clock_;
std::unique_ptr<ReportingUploader> uploader_;
base::ObserverList<ReportingObserver, /* check_empty= */ true> observers_;
diff --git a/chromium/net/reporting/reporting_delegate.cc b/chromium/net/reporting/reporting_delegate.cc
index e25531af265..e0665211c4e 100644
--- a/chromium/net/reporting/reporting_delegate.cc
+++ b/chromium/net/reporting/reporting_delegate.cc
@@ -12,6 +12,9 @@ namespace net {
namespace {
+const int kMaxJsonSize = 16 * 1024;
+const int kMaxJsonDepth = 5;
+
class ReportingDelegateImpl : public ReportingDelegate {
public:
ReportingDelegateImpl(URLRequestContext* request_context)
@@ -53,7 +56,13 @@ class ReportingDelegateImpl : public ReportingDelegate {
void ParseJson(const std::string& unsafe_json,
const JsonSuccessCallback& success_callback,
const JsonFailureCallback& failure_callback) const override {
- std::unique_ptr<base::Value> value = base::JSONReader::Read(unsafe_json);
+ if (unsafe_json.size() > kMaxJsonSize) {
+ failure_callback.Run();
+ return;
+ }
+
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(
+ unsafe_json, base::JSON_PARSE_RFC, kMaxJsonDepth);
if (value)
success_callback.Run(std::move(value));
else
diff --git a/chromium/net/reporting/reporting_delivery_agent.cc b/chromium/net/reporting/reporting_delivery_agent.cc
index 7a3ab2ec82c..467bfd9959a 100644
--- a/chromium/net/reporting/reporting_delivery_agent.cc
+++ b/chromium/net/reporting/reporting_delivery_agent.cc
@@ -71,8 +71,10 @@ class ReportingDeliveryAgentImpl : public ReportingDeliveryAgent,
// ReportingObserver implementation:
void OnCacheUpdated() override {
- if (CacheHasReports())
+ if (CacheHasReports() && !timer_->IsRunning()) {
+ SendReports();
StartTimer();
+ }
}
private:
@@ -180,11 +182,16 @@ class ReportingDeliveryAgentImpl : public ReportingDeliveryAgent,
std::string json;
SerializeReports(reports, tick_clock()->NowTicks(), &json);
- for (const ReportingReport* report : reports)
+ int max_depth = 0;
+ for (const ReportingReport* report : reports) {
undelivered_reports.erase(report);
+ if (report->depth > max_depth)
+ max_depth = report->depth;
+ }
+ // TODO: Calculate actual max depth.
uploader()->StartUpload(
- endpoint, json,
+ endpoint, json, max_depth,
base::BindOnce(
&ReportingDeliveryAgentImpl::OnUploadComplete,
weak_factory_.GetWeakPtr(),
@@ -197,6 +204,10 @@ class ReportingDeliveryAgentImpl : public ReportingDeliveryAgent,
void OnUploadComplete(const std::unique_ptr<Delivery>& delivery,
ReportingUploader::Outcome outcome) {
+ cache()->IncrementEndpointDeliveries(
+ delivery->endpoint, delivery->reports,
+ outcome == ReportingUploader::Outcome::SUCCESS);
+
if (outcome == ReportingUploader::Outcome::SUCCESS) {
cache()->RemoveReports(delivery->reports,
ReportingReport::Outcome::DELIVERED);
@@ -219,7 +230,7 @@ class ReportingDeliveryAgentImpl : public ReportingDeliveryAgent,
}
const ReportingPolicy& policy() { return context_->policy(); }
- base::TickClock* tick_clock() { return context_->tick_clock(); }
+ const base::TickClock* tick_clock() { return context_->tick_clock(); }
ReportingDelegate* delegate() { return context_->delegate(); }
ReportingCache* cache() { return context_->cache(); }
ReportingUploader* uploader() { return context_->uploader(); }
diff --git a/chromium/net/reporting/reporting_delivery_agent_unittest.cc b/chromium/net/reporting/reporting_delivery_agent_unittest.cc
index c5b1a418c14..6bf623a8820 100644
--- a/chromium/net/reporting/reporting_delivery_agent_unittest.cc
+++ b/chromium/net/reporting/reporting_delivery_agent_unittest.cc
@@ -57,17 +57,57 @@ class ReportingDeliveryAgentTest : public ReportingTestBase {
const std::string kType_ = "type";
};
-TEST_F(ReportingDeliveryAgentTest, SuccessfulUpload) {
- static const int kAgeMillis = 12345;
+TEST_F(ReportingDeliveryAgentTest, SuccessfulImmediateUpload) {
+ base::DictionaryValue body;
+ body.SetString("key", "value");
+
+ SetClient(kOrigin_, kEndpoint_, kGroup_);
+ cache()->AddReport(kUrl_, kGroup_, kType_, body.CreateDeepCopy(), 0,
+ tick_clock()->NowTicks(), 0);
+
+ // Upload is automatically started when cache is modified.
+
+ ASSERT_EQ(1u, pending_uploads().size());
+ EXPECT_EQ(kEndpoint_, pending_uploads()[0]->url());
+ {
+ auto value = pending_uploads()[0]->GetValue();
+
+ base::ListValue* list;
+ ASSERT_TRUE(value->GetAsList(&list));
+ EXPECT_EQ(1u, list->GetSize());
+
+ base::DictionaryValue* report;
+ ASSERT_TRUE(list->GetDictionary(0, &report));
+ EXPECT_EQ(4u, report->size());
+
+ ExpectDictIntegerValue(0, *report, "age");
+ ExpectDictStringValue(kType_, *report, "type");
+ ExpectDictStringValue(kUrl_.spec(), *report, "url");
+ ExpectDictDictionaryValue(body, *report, "report");
+ }
+ pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
+ // Successful upload should remove delivered reports.
+ std::vector<const ReportingReport*> reports;
+ cache()->GetReports(&reports);
+ EXPECT_TRUE(reports.empty());
+
+ // TODO(juliatuttle): Check that BackoffEntry was informed of success.
+}
+
+TEST_F(ReportingDeliveryAgentTest, SuccessfulDelayedUpload) {
base::DictionaryValue body;
body.SetString("key", "value");
+ // Trigger and complete an upload to start the delivery timer.
SetClient(kOrigin_, kEndpoint_, kGroup_);
- cache()->AddReport(kUrl_, kGroup_, kType_, body.CreateDeepCopy(),
+ cache()->AddReport(kUrl_, kGroup_, kType_, body.CreateDeepCopy(), 0,
tick_clock()->NowTicks(), 0);
+ pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
- tick_clock()->Advance(base::TimeDelta::FromMilliseconds(kAgeMillis));
+ SetClient(kOrigin_, kEndpoint_, kGroup_);
+ cache()->AddReport(kUrl_, kGroup_, kType_, body.CreateDeepCopy(), 0,
+ tick_clock()->NowTicks(), 0);
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
@@ -85,13 +125,22 @@ TEST_F(ReportingDeliveryAgentTest, SuccessfulUpload) {
ASSERT_TRUE(list->GetDictionary(0, &report));
EXPECT_EQ(4u, report->size());
- ExpectDictIntegerValue(kAgeMillis, *report, "age");
+ ExpectDictIntegerValue(0, *report, "age");
ExpectDictStringValue(kType_, *report, "type");
ExpectDictStringValue(kUrl_.spec(), *report, "url");
ExpectDictDictionaryValue(body, *report, "report");
}
pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS);
+ {
+ ReportingCache::ClientStatistics stats =
+ cache()->GetStatisticsForOriginAndEndpoint(kOrigin_, kEndpoint_);
+ EXPECT_EQ(1, stats.attempted_uploads);
+ EXPECT_EQ(1, stats.successful_uploads);
+ EXPECT_EQ(1, stats.attempted_reports);
+ EXPECT_EQ(1, stats.successful_reports);
+ }
+
// Successful upload should remove delivered reports.
std::vector<const ReportingReport*> reports;
cache()->GetReports(&reports);
@@ -103,7 +152,7 @@ TEST_F(ReportingDeliveryAgentTest, SuccessfulUpload) {
TEST_F(ReportingDeliveryAgentTest, FailedUpload) {
SetClient(kOrigin_, kEndpoint_, kGroup_);
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
EXPECT_TRUE(delivery_timer()->IsRunning());
@@ -112,6 +161,15 @@ TEST_F(ReportingDeliveryAgentTest, FailedUpload) {
ASSERT_EQ(1u, pending_uploads().size());
pending_uploads()[0]->Complete(ReportingUploader::Outcome::FAILURE);
+ {
+ ReportingCache::ClientStatistics stats =
+ cache()->GetStatisticsForOriginAndEndpoint(kOrigin_, kEndpoint_);
+ EXPECT_EQ(1, stats.attempted_uploads);
+ EXPECT_EQ(0, stats.successful_uploads);
+ EXPECT_EQ(1, stats.attempted_reports);
+ EXPECT_EQ(0, stats.successful_reports);
+ }
+
// Failed upload should increment reports' attempts.
std::vector<const ReportingReport*> reports;
cache()->GetReports(&reports);
@@ -124,6 +182,15 @@ TEST_F(ReportingDeliveryAgentTest, FailedUpload) {
EXPECT_TRUE(delivery_timer()->IsRunning());
delivery_timer()->Fire();
EXPECT_TRUE(pending_uploads().empty());
+
+ {
+ ReportingCache::ClientStatistics stats =
+ cache()->GetStatisticsForOriginAndEndpoint(kOrigin_, kEndpoint_);
+ EXPECT_EQ(1, stats.attempted_uploads);
+ EXPECT_EQ(0, stats.successful_uploads);
+ EXPECT_EQ(1, stats.attempted_reports);
+ EXPECT_EQ(0, stats.successful_reports);
+ }
}
TEST_F(ReportingDeliveryAgentTest, DisallowedUpload) {
@@ -137,7 +204,7 @@ TEST_F(ReportingDeliveryAgentTest, DisallowedUpload) {
body.SetString("key", "value");
SetClient(kOrigin_, kEndpoint_, kGroup_);
- cache()->AddReport(kUrl_, kGroup_, kType_, body.CreateDeepCopy(),
+ cache()->AddReport(kUrl_, kGroup_, kType_, body.CreateDeepCopy(), 0,
tick_clock()->NowTicks(), 0);
tick_clock()->Advance(base::TimeDelta::FromMilliseconds(kAgeMillis));
@@ -149,6 +216,15 @@ TEST_F(ReportingDeliveryAgentTest, DisallowedUpload) {
// for this origin.
EXPECT_TRUE(pending_uploads().empty());
+ {
+ ReportingCache::ClientStatistics stats =
+ cache()->GetStatisticsForOriginAndEndpoint(kOrigin_, kEndpoint_);
+ EXPECT_EQ(0, stats.attempted_uploads);
+ EXPECT_EQ(0, stats.successful_uploads);
+ EXPECT_EQ(0, stats.attempted_reports);
+ EXPECT_EQ(0, stats.successful_reports);
+ }
+
// Disallowed reports should NOT have been removed from the cache.
std::vector<const ReportingReport*> reports;
cache()->GetReports(&reports);
@@ -165,7 +241,7 @@ TEST_F(ReportingDeliveryAgentTest, RemoveEndpointUpload) {
ASSERT_TRUE(FindClientInCache(cache(), kDifferentOrigin, kEndpoint_));
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
EXPECT_TRUE(delivery_timer()->IsRunning());
@@ -194,7 +270,7 @@ TEST_F(ReportingDeliveryAgentTest, RemoveEndpointUpload) {
TEST_F(ReportingDeliveryAgentTest, ConcurrentRemove) {
SetClient(kOrigin_, kEndpoint_, kGroup_);
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
EXPECT_TRUE(delivery_timer()->IsRunning());
@@ -233,11 +309,9 @@ TEST_F(ReportingDeliveryAgentTest, ConcurrentRemoveDuringPermissionsCheck) {
SetClient(kOrigin_, kEndpoint_, kGroup_);
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
- EXPECT_TRUE(delivery_timer()->IsRunning());
- delivery_timer()->Fire();
ASSERT_TRUE(context()->test_delegate()->PermissionsCheckPaused());
// Remove the report while the upload is running.
@@ -277,10 +351,10 @@ TEST_F(ReportingDeliveryAgentTest,
SetClient(kDifferentOrigin, kEndpoint_, kGroup_);
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
cache()->AddReport(kDifferentUrl, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
EXPECT_TRUE(delivery_timer()->IsRunning());
@@ -303,7 +377,7 @@ TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToEndpoint) {
SetClient(kDifferentOrigin, kEndpoint_, kGroup_);
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
EXPECT_TRUE(delivery_timer()->IsRunning());
@@ -311,7 +385,7 @@ TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToEndpoint) {
EXPECT_EQ(1u, pending_uploads().size());
cache()->AddReport(kDifferentUrl, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
EXPECT_TRUE(delivery_timer()->IsRunning());
@@ -339,7 +413,7 @@ TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToGroup) {
SetClient(kOrigin_, kDifferentEndpoint, kGroup_);
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
EXPECT_TRUE(delivery_timer()->IsRunning());
@@ -347,7 +421,7 @@ TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToGroup) {
EXPECT_EQ(1u, pending_uploads().size());
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
EXPECT_TRUE(delivery_timer()->IsRunning());
@@ -375,10 +449,10 @@ TEST_F(ReportingDeliveryAgentTest, ParallelizeUploadsAcrossGroups) {
SetClient(kOrigin_, kDifferentEndpoint, kDifferentGroup);
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
cache()->AddReport(kUrl_, kDifferentGroup, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
EXPECT_TRUE(delivery_timer()->IsRunning());
diff --git a/chromium/net/reporting/reporting_endpoint_manager.cc b/chromium/net/reporting/reporting_endpoint_manager.cc
index 6a4c6c126a5..b5aec562ec5 100644
--- a/chromium/net/reporting/reporting_endpoint_manager.cc
+++ b/chromium/net/reporting/reporting_endpoint_manager.cc
@@ -119,7 +119,7 @@ class ReportingEndpointManagerImpl : public ReportingEndpointManager {
private:
const ReportingPolicy& policy() { return context_->policy(); }
- base::TickClock* tick_clock() { return context_->tick_clock(); }
+ const base::TickClock* tick_clock() { return context_->tick_clock(); }
ReportingDelegate* delegate() { return context_->delegate(); }
ReportingCache* cache() { return context_->cache(); }
diff --git a/chromium/net/reporting/reporting_garbage_collector_unittest.cc b/chromium/net/reporting/reporting_garbage_collector_unittest.cc
index 3aac7abfadf..5ae177b08f0 100644
--- a/chromium/net/reporting/reporting_garbage_collector_unittest.cc
+++ b/chromium/net/reporting/reporting_garbage_collector_unittest.cc
@@ -41,7 +41,7 @@ TEST_F(ReportingGarbageCollectorTest, Timer) {
EXPECT_FALSE(garbage_collection_timer()->IsRunning());
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
EXPECT_TRUE(garbage_collection_timer()->IsRunning());
@@ -53,7 +53,7 @@ TEST_F(ReportingGarbageCollectorTest, Timer) {
TEST_F(ReportingGarbageCollectorTest, Report) {
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
garbage_collection_timer()->Fire();
@@ -62,7 +62,7 @@ TEST_F(ReportingGarbageCollectorTest, Report) {
TEST_F(ReportingGarbageCollectorTest, ExpiredReport) {
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
tick_clock()->Advance(2 * policy().max_report_age);
garbage_collection_timer()->Fire();
@@ -72,7 +72,7 @@ TEST_F(ReportingGarbageCollectorTest, ExpiredReport) {
TEST_F(ReportingGarbageCollectorTest, FailedReport) {
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
std::vector<const ReportingReport*> reports;
diff --git a/chromium/net/reporting/reporting_header_parser.cc b/chromium/net/reporting/reporting_header_parser.cc
index e482a55e41a..cd1f7900964 100644
--- a/chromium/net/reporting/reporting_header_parser.cc
+++ b/chromium/net/reporting/reporting_header_parser.cc
@@ -26,14 +26,15 @@ enum class HeaderOutcome {
DISCARDED_NO_REPORTING_SERVICE = 0,
DISCARDED_INVALID_SSL_INFO = 1,
DISCARDED_CERT_STATUS_ERROR = 2,
- DISCARDED_INVALID_JSON = 3,
- PARSED = 4,
+ DISCARDED_JSON_TOO_BIG = 3,
+ DISCARDED_JSON_INVALID = 4,
+ PARSED = 5,
MAX
};
void RecordHeaderOutcome(HeaderOutcome outcome) {
- UMA_HISTOGRAM_ENUMERATION("Reporting.HeaderOutcome", outcome,
+ UMA_HISTOGRAM_ENUMERATION("Net.Reporting.HeaderOutcome", outcome,
HeaderOutcome::MAX);
}
@@ -45,38 +46,30 @@ enum class HeaderEndpointGroupOutcome {
DISCARDED_TTL_NEGATIVE = 4,
DISCARDED_ENDPOINTS_MISSING = 5,
DISCARDED_ENDPOINTS_NOT_LIST = 6,
+
PARSED = 7,
MAX
};
void RecordHeaderEndpointGroupOutcome(HeaderEndpointGroupOutcome outcome) {
- UMA_HISTOGRAM_ENUMERATION("Reporting.HeaderEndpointGroupOutcome", outcome,
+ UMA_HISTOGRAM_ENUMERATION("Net.Reporting.HeaderEndpointGroupOutcome", outcome,
HeaderEndpointGroupOutcome::MAX);
}
enum class HeaderEndpointOutcome {
DISCARDED_NOT_DICTIONARY = 0,
- DISCARDED_ENDPOINT_MISSING = 1, // obsolete
- DISCARDED_ENDPOINT_NOT_STRING = 2, // obsolete
- DISCARDED_ENDPOINT_INVALID = 3, // obsolete
- DISCARDED_ENDPOINT_INSECURE = 4, // obsolete
- DISCARDED_TTL_MISSING = 5, // obsolete
- DISCARDED_TTL_NOT_INTEGER = 6, // obsolete
- DISCARDED_TTL_NEGATIVE = 7, // obsolete
- DISCARDED_GROUP_NOT_STRING = 8, // obsolete
- REMOVED = 9,
- SET_REJECTED_BY_DELEGATE = 10,
- SET = 11,
-
- DISCARDED_PRIORITY_NOT_INTEGER = 12,
- DISCARDED_WEIGHT_NOT_INTEGER = 13,
- DISCARDED_WEIGHT_NOT_POSITIVE = 14,
-
- DISCARDED_URL_MISSING = 15,
- DISCARDED_URL_NOT_STRING = 16,
- DISCARDED_URL_INVALID = 17,
- DISCARDED_URL_INSECURE = 18,
+ DISCARDED_URL_MISSING = 1,
+ DISCARDED_URL_NOT_STRING = 2,
+ DISCARDED_URL_INVALID = 3,
+ DISCARDED_URL_INSECURE = 4,
+ DISCARDED_PRIORITY_NOT_INTEGER = 5,
+ DISCARDED_WEIGHT_NOT_INTEGER = 6,
+ DISCARDED_WEIGHT_NOT_POSITIVE = 7,
+
+ REMOVED = 8,
+ SET_REJECTED_BY_DELEGATE = 9,
+ SET = 10,
MAX
};
@@ -88,7 +81,7 @@ bool EndpointParsedSuccessfully(HeaderEndpointOutcome outcome) {
}
void RecordHeaderEndpointOutcome(HeaderEndpointOutcome outcome) {
- UMA_HISTOGRAM_ENUMERATION("Reporting.HeaderEndpointOutcome", outcome,
+ UMA_HISTOGRAM_ENUMERATION("Net.Reporting.HeaderEndpointOutcome", outcome,
HeaderEndpointOutcome::MAX);
}
@@ -239,8 +232,13 @@ void ReportingHeaderParser::RecordHeaderDiscardedForCertStatusError() {
}
// static
-void ReportingHeaderParser::RecordHeaderDiscardedForInvalidJson() {
- RecordHeaderOutcome(HeaderOutcome::DISCARDED_INVALID_JSON);
+void ReportingHeaderParser::RecordHeaderDiscardedForJsonInvalid() {
+ RecordHeaderOutcome(HeaderOutcome::DISCARDED_JSON_INVALID);
+}
+
+// static
+void ReportingHeaderParser::RecordHeaderDiscardedForJsonTooBig() {
+ RecordHeaderOutcome(HeaderOutcome::DISCARDED_JSON_TOO_BIG);
}
// static
@@ -278,6 +276,8 @@ void ReportingHeaderParser::ParseHeader(ReportingContext* context,
if (new_endpoints.count(old_endpoint) == 0u)
cache->RemoveClientForOriginAndEndpoint(origin, old_endpoint);
}
+
+ RecordHeaderOutcome(HeaderOutcome::PARSED);
}
} // namespace net
diff --git a/chromium/net/reporting/reporting_header_parser.h b/chromium/net/reporting/reporting_header_parser.h
index 94a29beee7c..7613add4d56 100644
--- a/chromium/net/reporting/reporting_header_parser.h
+++ b/chromium/net/reporting/reporting_header_parser.h
@@ -25,7 +25,8 @@ class NET_EXPORT ReportingHeaderParser {
static void RecordHeaderDiscardedForNoReportingService();
static void RecordHeaderDiscardedForInvalidSSLInfo();
static void RecordHeaderDiscardedForCertStatusError();
- static void RecordHeaderDiscardedForInvalidJson();
+ static void RecordHeaderDiscardedForJsonInvalid();
+ static void RecordHeaderDiscardedForJsonTooBig();
static void ParseHeader(ReportingContext* context,
const GURL& url,
diff --git a/chromium/net/reporting/reporting_network_change_observer_unittest.cc b/chromium/net/reporting/reporting_network_change_observer_unittest.cc
index ae35fbda87e..db1aabcff0f 100644
--- a/chromium/net/reporting/reporting_network_change_observer_unittest.cc
+++ b/chromium/net/reporting/reporting_network_change_observer_unittest.cc
@@ -65,7 +65,7 @@ TEST_F(ReportingNetworkChangeObserverTest, ClearNothing) {
UsePolicy(new_policy);
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
SetClient();
ASSERT_EQ(1u, report_count());
@@ -84,7 +84,7 @@ TEST_F(ReportingNetworkChangeObserverTest, ClearReports) {
UsePolicy(new_policy);
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
SetClient();
ASSERT_EQ(1u, report_count());
@@ -103,7 +103,7 @@ TEST_F(ReportingNetworkChangeObserverTest, ClearClients) {
UsePolicy(new_policy);
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
SetClient();
ASSERT_EQ(1u, report_count());
@@ -122,7 +122,7 @@ TEST_F(ReportingNetworkChangeObserverTest, ClearReportsAndClients) {
UsePolicy(new_policy);
cache()->AddReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>(),
+ std::make_unique<base::DictionaryValue>(), 0,
tick_clock()->NowTicks(), 0);
SetClient();
ASSERT_EQ(1u, report_count());
diff --git a/chromium/net/reporting/reporting_report.cc b/chromium/net/reporting/reporting_report.cc
index 37c4a22bd3d..c6dd820401d 100644
--- a/chromium/net/reporting/reporting_report.cc
+++ b/chromium/net/reporting/reporting_report.cc
@@ -18,7 +18,7 @@ namespace net {
namespace {
void RecordReportOutcome(ReportingReport::Outcome outcome) {
- UMA_HISTOGRAM_ENUMERATION("Reporting.ReportOutcome", outcome,
+ UMA_HISTOGRAM_ENUMERATION("Net.Reporting.ReportOutcome", outcome,
ReportingReport::Outcome::MAX);
}
@@ -28,12 +28,14 @@ ReportingReport::ReportingReport(const GURL& url,
const std::string& group,
const std::string& type,
std::unique_ptr<const base::Value> body,
+ int depth,
base::TimeTicks queued,
int attempts)
: url(url),
group(group),
type(type),
body(std::move(body)),
+ depth(depth),
queued(queued),
attempts(attempts),
outcome(Outcome::UNKNOWN),
@@ -59,9 +61,9 @@ void ReportingReport::RecordOutcome(base::TimeTicks now) {
RecordReportOutcome(outcome);
if (outcome == Outcome::DELIVERED) {
- UMA_HISTOGRAM_LONG_TIMES_100("Reporting.ReportDeliveredLatency",
+ UMA_HISTOGRAM_LONG_TIMES_100("Net.Reporting.ReportDeliveredLatency",
now - queued);
- UMA_HISTOGRAM_COUNTS_100("Reporting.ReportDeliveredAttempts", attempts);
+ UMA_HISTOGRAM_COUNTS_100("Net.Reporting.ReportDeliveredAttempts", attempts);
}
recorded_outcome = true;
diff --git a/chromium/net/reporting/reporting_report.h b/chromium/net/reporting/reporting_report.h
index 1621ab0a49d..196be9e0f5a 100644
--- a/chromium/net/reporting/reporting_report.h
+++ b/chromium/net/reporting/reporting_report.h
@@ -33,7 +33,6 @@ struct NET_EXPORT ReportingReport {
ERASED_BROWSING_DATA_REMOVED = 7,
ERASED_REPORTING_SHUT_DOWN = 8,
DELIVERED = 9,
- ERASED_NO_BACKGROUND_SYNC_PERMISSION = 10,
MAX
};
@@ -42,6 +41,7 @@ struct NET_EXPORT ReportingReport {
const std::string& group,
const std::string& type,
std::unique_ptr<const base::Value> body,
+ int depth,
base::TimeTicks queued,
int attempts);
~ReportingReport();
@@ -65,6 +65,11 @@ struct NET_EXPORT ReportingReport {
// The body of the report. (Included in the delivered report.)
std::unique_ptr<const base::Value> body;
+ // How many uploads deep the related request was: 0 if the related request was
+ // not an upload (or there was no related request), or n+1 if it was an upload
+ // reporting on requests of at most depth n.
+ int depth;
+
// When the report was queued. (Included in the delivered report as an age
// relative to the time of the delivery attempt.)
base::TimeTicks queued;
diff --git a/chromium/net/reporting/reporting_service.cc b/chromium/net/reporting/reporting_service.cc
index 5137082775d..ce1efb0f28f 100644
--- a/chromium/net/reporting/reporting_service.cc
+++ b/chromium/net/reporting/reporting_service.cc
@@ -36,14 +36,15 @@ class ReportingServiceImpl : public ReportingService {
void QueueReport(const GURL& url,
const std::string& group,
const std::string& type,
- std::unique_ptr<const base::Value> body) override {
+ std::unique_ptr<const base::Value> body,
+ int depth) override {
DCHECK(context_);
DCHECK(context_->delegate());
if (!context_->delegate()->CanQueueReport(url::Origin::Create(url)))
return;
- context_->cache()->AddReport(url, group, type, std::move(body),
+ context_->cache()->AddReport(url, group, type, std::move(body), depth,
context_->tick_clock()->NowTicks(), 0);
}
@@ -54,7 +55,7 @@ class ReportingServiceImpl : public ReportingService {
base::BindRepeating(&ReportingServiceImpl::ProcessHeaderValue,
weak_factory_.GetWeakPtr(), url),
base::BindRepeating(
- &ReportingHeaderParser::RecordHeaderDiscardedForInvalidJson));
+ &ReportingHeaderParser::RecordHeaderDiscardedForJsonInvalid));
}
void RemoveBrowsingData(int data_type_mask,
@@ -64,8 +65,8 @@ class ReportingServiceImpl : public ReportingService {
context_->cache(), data_type_mask, origin_filter);
}
- bool RequestIsUpload(const URLRequest& request) override {
- return context_->uploader()->RequestIsUpload(request);
+ int GetUploadDepth(const URLRequest& request) override {
+ return context_->uploader()->GetUploadDepth(request);
}
const ReportingPolicy& GetPolicy() const override {
diff --git a/chromium/net/reporting/reporting_service.h b/chromium/net/reporting/reporting_service.h
index 37958702e00..b165cdcdfc8 100644
--- a/chromium/net/reporting/reporting_service.h
+++ b/chromium/net/reporting/reporting_service.h
@@ -53,7 +53,8 @@ class NET_EXPORT ReportingService {
virtual void QueueReport(const GURL& url,
const std::string& group,
const std::string& type,
- std::unique_ptr<const base::Value> body) = 0;
+ std::unique_ptr<const base::Value> body,
+ int depth) = 0;
// Processes a Report-To header. |url| is the URL that originated the header;
// |header_value| is the normalized value of the Report-To header.
@@ -66,9 +67,9 @@ class NET_EXPORT ReportingService {
int data_type_mask,
const base::RepeatingCallback<bool(const GURL&)>& origin_filter) = 0;
- // Checks whether |request| is a Reporting upload, to avoid loops of reporting
- // about report uploads.
- virtual bool RequestIsUpload(const URLRequest& request) = 0;
+ // Checks how many uploads deep |request| is: 0 if it's not an upload, n+1 if
+ // it's an upload reporting on requests of at most depth n.
+ virtual int GetUploadDepth(const URLRequest& request) = 0;
virtual const ReportingPolicy& GetPolicy() const = 0;
diff --git a/chromium/net/reporting/reporting_service_unittest.cc b/chromium/net/reporting/reporting_service_unittest.cc
index 65e1a651d6a..c0dd7fe5f60 100644
--- a/chromium/net/reporting/reporting_service_unittest.cc
+++ b/chromium/net/reporting/reporting_service_unittest.cc
@@ -48,7 +48,7 @@ class ReportingServiceTest : public ::testing::Test {
TEST_F(ReportingServiceTest, QueueReport) {
service()->QueueReport(kUrl_, kGroup_, kType_,
- std::make_unique<base::DictionaryValue>());
+ std::make_unique<base::DictionaryValue>(), 0);
std::vector<const ReportingReport*> reports;
context()->cache()->GetReports(&reports);
@@ -78,5 +78,37 @@ TEST_F(ReportingServiceTest, ProcessHeader) {
client->expires);
}
+TEST_F(ReportingServiceTest, ProcessHeader_TooLong) {
+ const std::string header_too_long =
+ "{\"endpoints\":[{\"url\":\"" + kEndpoint_.spec() +
+ "\"}],"
+ "\"group\":\"" +
+ kGroup_ +
+ "\","
+ "\"max-age\":86400," +
+ "\"junk\":\"" + std::string(32 * 1024, 'a') + "\"}";
+ service()->ProcessHeader(kUrl_, header_too_long);
+
+ const ReportingClient* client =
+ FindClientInCache(context()->cache(), kOrigin_, kEndpoint_);
+ EXPECT_FALSE(client);
+}
+
+TEST_F(ReportingServiceTest, ProcessHeader_TooDeep) {
+ const std::string header_too_deep = "{\"endpoints\":[{\"url\":\"" +
+ kEndpoint_.spec() +
+ "\"}],"
+ "\"group\":\"" +
+ kGroup_ +
+ "\","
+ "\"max-age\":86400," +
+ "\"junk\":[[[[[[[[[[]]]]]]]]]]}";
+ service()->ProcessHeader(kUrl_, header_too_deep);
+
+ const ReportingClient* client =
+ FindClientInCache(context()->cache(), kOrigin_, kEndpoint_);
+ EXPECT_FALSE(client);
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/reporting/reporting_test_util.cc b/chromium/net/reporting/reporting_test_util.cc
index 47c29f5e124..a23535f7572 100644
--- a/chromium/net/reporting/reporting_test_util.cc
+++ b/chromium/net/reporting/reporting_test_util.cc
@@ -24,6 +24,7 @@
#include "net/reporting/reporting_garbage_collector.h"
#include "net/reporting/reporting_policy.h"
#include "net/reporting/reporting_uploader.h"
+#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -45,7 +46,7 @@ class PendingUploadImpl : public TestReportingUploader::PendingUpload {
~PendingUploadImpl() override = default;
- // PendingUpload implementationP:
+ // PendingUpload implementation:
const GURL& url() const override { return url_; }
const std::string& json() const override { return json_; }
std::unique_ptr<base::Value> GetValue() const override {
@@ -99,18 +100,21 @@ TestReportingUploader::~TestReportingUploader() = default;
void TestReportingUploader::StartUpload(const GURL& url,
const std::string& json,
+ int max_depth,
UploadCallback callback) {
pending_uploads_.push_back(std::make_unique<PendingUploadImpl>(
url, json, std::move(callback),
base::BindOnce(&ErasePendingUpload, &pending_uploads_)));
}
-bool TestReportingUploader::RequestIsUpload(const URLRequest& request) {
+int TestReportingUploader::GetUploadDepth(const URLRequest& request) {
NOTIMPLEMENTED();
- return true;
+ return 0;
}
-TestReportingDelegate::TestReportingDelegate() = default;
+TestReportingDelegate::TestReportingDelegate()
+ : test_request_context_(std::make_unique<TestURLRequestContext>()),
+ real_delegate_(ReportingDelegate::Create(test_request_context_.get())) {}
TestReportingDelegate::~TestReportingDelegate() = default;
@@ -156,15 +160,11 @@ void TestReportingDelegate::ParseJson(
const std::string& unsafe_json,
const JsonSuccessCallback& success_callback,
const JsonFailureCallback& failure_callback) const {
- std::unique_ptr<base::Value> value = base::JSONReader::Read(unsafe_json);
- if (value)
- success_callback.Run(std::move(value));
- else
- failure_callback.Run();
+ real_delegate_->ParseJson(unsafe_json, success_callback, failure_callback);
}
TestReportingContext::TestReportingContext(base::Clock* clock,
- base::TickClock* tick_clock,
+ const base::TickClock* tick_clock,
const ReportingPolicy& policy)
: ReportingContext(
policy,
diff --git a/chromium/net/reporting/reporting_test_util.h b/chromium/net/reporting/reporting_test_util.h
index d4e675aa93f..239a2f42a83 100644
--- a/chromium/net/reporting/reporting_test_util.h
+++ b/chromium/net/reporting/reporting_test_util.h
@@ -36,6 +36,7 @@ namespace net {
class ReportingCache;
struct ReportingClient;
class ReportingGarbageCollector;
+class TestURLRequestContext;
// Finds a particular client (by origin and endpoint) in the cache and returns
// it (or nullptr if not found).
@@ -72,9 +73,10 @@ class TestReportingUploader : public ReportingUploader {
void StartUpload(const GURL& url,
const std::string& json,
+ int max_depth,
UploadCallback callback) override;
- bool RequestIsUpload(const URLRequest& request) override;
+ int GetUploadDepth(const URLRequest& request) override;
private:
std::vector<std::unique_ptr<PendingUpload>> pending_uploads_;
@@ -82,6 +84,9 @@ class TestReportingUploader : public ReportingUploader {
DISALLOW_COPY_AND_ASSIGN(TestReportingUploader);
};
+// Allows all permissions unless set_disallow_report_uploads is called; uses
+// the real ReportingDelegate for JSON parsing to exercise depth and size
+// limits.
class TestReportingDelegate : public ReportingDelegate {
public:
TestReportingDelegate();
@@ -118,6 +123,8 @@ class TestReportingDelegate : public ReportingDelegate {
const JsonFailureCallback& failure_callback) const override;
private:
+ std::unique_ptr<TestURLRequestContext> test_request_context_;
+ std::unique_ptr<ReportingDelegate> real_delegate_;
bool disallow_report_uploads_ = false;
bool pause_permissions_check_ = false;
@@ -133,7 +140,7 @@ class TestReportingDelegate : public ReportingDelegate {
class TestReportingContext : public ReportingContext {
public:
TestReportingContext(base::Clock* clock,
- base::TickClock* tick_clock,
+ const base::TickClock* tick_clock,
const ReportingPolicy& policy);
~TestReportingContext();
diff --git a/chromium/net/reporting/reporting_uploader.cc b/chromium/net/reporting/reporting_uploader.cc
index 2220858c3b0..9cd12737499 100644
--- a/chromium/net/reporting/reporting_uploader.cc
+++ b/chromium/net/reporting/reporting_uploader.cc
@@ -9,6 +9,7 @@
#include <vector>
#include "base/callback_helpers.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/load_flags.h"
@@ -26,6 +27,10 @@ namespace {
class UploadUserData : public base::SupportsUserData::Data {
public:
static const void* const kUserDataKey;
+
+ UploadUserData(int depth) : depth(depth) {}
+
+ int depth;
};
// SetUserData needs a unique const void* to serve as the key, so create a const
@@ -40,6 +45,26 @@ ReportingUploader::Outcome ResponseCodeToOutcome(int response_code) {
return ReportingUploader::Outcome::FAILURE;
}
+enum class UploadOutcome {
+ CANCELED_REDIRECT_TO_INSECURE_URL = 0,
+ CANCELED_AUTH_REQUIRED = 1,
+ CANCELED_CERTIFICATE_REQUESTED = 2,
+ CANCELED_SSL_CERTIFICATE_ERROR = 3,
+ CANCELED_REPORTING_SHUTDOWN = 4,
+ FAILED = 5, // See Net.Reporting.UploadError for breakdown.
+ SUCCEEDED_SUCCESS = 6,
+ SUCCEEDED_REMOVE_ENDPOINT = 7,
+
+ MAX
+};
+
+void RecordUploadOutcome(UploadOutcome outcome) {
+ UMA_HISTOGRAM_ENUMERATION("Net.Reporting.UploadOutcome", outcome,
+ UploadOutcome::MAX);
+}
+
+// TODO: Record net and HTTP error.
+
class ReportingUploaderImpl : public ReportingUploader, URLRequest::Delegate {
public:
ReportingUploaderImpl(const URLRequestContext* context) : context_(context) {
@@ -56,6 +81,7 @@ class ReportingUploaderImpl : public ReportingUploader, URLRequest::Delegate {
void StartUpload(const GURL& url,
const std::string& json,
+ int max_depth,
UploadCallback callback) override {
net::NetworkTrafficAnnotationTag traffic_annotation =
net::DefineNetworkTrafficAnnotation("reporting", R"(
@@ -95,7 +121,7 @@ class ReportingUploaderImpl : public ReportingUploader, URLRequest::Delegate {
ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));
request->SetUserData(UploadUserData::kUserDataKey,
- std::make_unique<UploadUserData>());
+ std::make_unique<UploadUserData>(max_depth));
// This inherently sets mode = "no-cors", but that doesn't matter, because
// the origins that are included in the upload don't actually get to see
@@ -111,8 +137,10 @@ class ReportingUploaderImpl : public ReportingUploader, URLRequest::Delegate {
}
// static
- bool RequestIsUpload(const net::URLRequest& request) override {
- return request.GetUserData(UploadUserData::kUserDataKey);
+ int GetUploadDepth(const net::URLRequest& request) override {
+ UploadUserData* data = static_cast<UploadUserData*>(
+ request.GetUserData(UploadUserData::kUserDataKey));
+ return data ? data->depth + 1 : 0;
}
// URLRequest::Delegate implementation:
@@ -157,6 +185,18 @@ class ReportingUploaderImpl : public ReportingUploader, URLRequest::Delegate {
int response_code = headers ? headers->response_code() : 0;
Outcome outcome = ResponseCodeToOutcome(response_code);
+ if (net_error != OK) {
+ RecordUploadOutcome(UploadOutcome::FAILED);
+ base::UmaHistogramSparse("Net.Reporting.UploadError", net_error);
+ } else if (response_code >= 200 && response_code <= 299) {
+ RecordUploadOutcome(UploadOutcome::SUCCEEDED_SUCCESS);
+ } else if (response_code == 410) {
+ RecordUploadOutcome(UploadOutcome::SUCCEEDED_REMOVE_ENDPOINT);
+ } else {
+ RecordUploadOutcome(UploadOutcome::FAILED);
+ base::UmaHistogramSparse("Net.Reporting.UploadError", response_code);
+ }
+
std::move(upload->second).Run(outcome);
request->Cancel();
diff --git a/chromium/net/reporting/reporting_uploader.h b/chromium/net/reporting/reporting_uploader.h
index f6c65c701b5..b17c0c49a86 100644
--- a/chromium/net/reporting/reporting_uploader.h
+++ b/chromium/net/reporting/reporting_uploader.h
@@ -34,10 +34,11 @@ class NET_EXPORT ReportingUploader {
// |url|, and calls |callback| when complete (whether successful or not).
virtual void StartUpload(const GURL& url,
const std::string& json,
+ int max_depth,
UploadCallback callback) = 0;
// Returns whether |request| is an upload request sent by this uploader.
- virtual bool RequestIsUpload(const URLRequest& request) = 0;
+ virtual int GetUploadDepth(const URLRequest& request) = 0;
// Creates a real implementation of |ReportingUploader| that uploads reports
// using |context|.
diff --git a/chromium/net/reporting/reporting_uploader_unittest.cc b/chromium/net/reporting/reporting_uploader_unittest.cc
index 9fcda4d0915..e417b08dd91 100644
--- a/chromium/net/reporting/reporting_uploader_unittest.cc
+++ b/chromium/net/reporting/reporting_uploader_unittest.cc
@@ -109,7 +109,8 @@ TEST_F(ReportingUploaderTest, Upload) {
ASSERT_TRUE(server_.Start());
TestUploadCallback callback;
- uploader_->StartUpload(server_.GetURL("/"), kUploadBody, callback.callback());
+ uploader_->StartUpload(server_.GetURL("/"), kUploadBody, 0,
+ callback.callback());
callback.WaitForCall();
}
@@ -118,7 +119,8 @@ TEST_F(ReportingUploaderTest, Success) {
ASSERT_TRUE(server_.Start());
TestUploadCallback callback;
- uploader_->StartUpload(server_.GetURL("/"), kUploadBody, callback.callback());
+ uploader_->StartUpload(server_.GetURL("/"), kUploadBody, 0,
+ callback.callback());
callback.WaitForCall();
EXPECT_EQ(ReportingUploader::Outcome::SUCCESS, callback.outcome());
@@ -130,7 +132,7 @@ TEST_F(ReportingUploaderTest, NetworkError1) {
ASSERT_TRUE(server_.ShutdownAndWaitUntilComplete());
TestUploadCallback callback;
- uploader_->StartUpload(url, kUploadBody, callback.callback());
+ uploader_->StartUpload(url, kUploadBody, 0, callback.callback());
callback.WaitForCall();
EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
@@ -141,7 +143,8 @@ TEST_F(ReportingUploaderTest, NetworkError2) {
ASSERT_TRUE(server_.Start());
TestUploadCallback callback;
- uploader_->StartUpload(server_.GetURL("/"), kUploadBody, callback.callback());
+ uploader_->StartUpload(server_.GetURL("/"), kUploadBody, 0,
+ callback.callback());
callback.WaitForCall();
EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
@@ -153,7 +156,8 @@ TEST_F(ReportingUploaderTest, ServerError) {
ASSERT_TRUE(server_.Start());
TestUploadCallback callback;
- uploader_->StartUpload(server_.GetURL("/"), kUploadBody, callback.callback());
+ uploader_->StartUpload(server_.GetURL("/"), kUploadBody, 0,
+ callback.callback());
callback.WaitForCall();
EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
@@ -165,7 +169,8 @@ TEST_F(ReportingUploaderTest, RemoveEndpoint) {
ASSERT_TRUE(server_.Start());
TestUploadCallback callback;
- uploader_->StartUpload(server_.GetURL("/"), kUploadBody, callback.callback());
+ uploader_->StartUpload(server_.GetURL("/"), kUploadBody, 0,
+ callback.callback());
callback.WaitForCall();
EXPECT_EQ(ReportingUploader::Outcome::REMOVE_ENDPOINT, callback.outcome());
@@ -207,7 +212,8 @@ TEST_F(ReportingUploaderTest, FollowHttpsRedirect) {
ASSERT_TRUE(server_.Start());
TestUploadCallback callback;
- uploader_->StartUpload(server_.GetURL("/"), kUploadBody, callback.callback());
+ uploader_->StartUpload(server_.GetURL("/"), kUploadBody, 0,
+ callback.callback());
callback.WaitForCall();
EXPECT_TRUE(followed);
@@ -228,7 +234,8 @@ TEST_F(ReportingUploaderTest, DontFollowHttpRedirect) {
ASSERT_TRUE(server_.Start());
TestUploadCallback callback;
- uploader_->StartUpload(server_.GetURL("/"), kUploadBody, callback.callback());
+ uploader_->StartUpload(server_.GetURL("/"), kUploadBody, 0,
+ callback.callback());
callback.WaitForCall();
EXPECT_FALSE(followed);
@@ -254,7 +261,7 @@ TEST_F(ReportingUploaderTest, DontSendCookies) {
ASSERT_TRUE(cookie_callback.result());
TestUploadCallback upload_callback;
- uploader_->StartUpload(server_.GetURL("/"), kUploadBody,
+ uploader_->StartUpload(server_.GetURL("/"), kUploadBody, 0,
upload_callback.callback());
upload_callback.WaitForCall();
}
@@ -274,7 +281,7 @@ TEST_F(ReportingUploaderTest, DontSaveCookies) {
ASSERT_TRUE(server_.Start());
TestUploadCallback upload_callback;
- uploader_->StartUpload(server_.GetURL("/"), kUploadBody,
+ uploader_->StartUpload(server_.GetURL("/"), kUploadBody, 0,
upload_callback.callback());
upload_callback.WaitForCall();
@@ -312,7 +319,7 @@ TEST_F(ReportingUploaderTest, DontCacheResponse) {
{
TestUploadCallback callback;
- uploader_->StartUpload(server_.GetURL("/"), kUploadBody,
+ uploader_->StartUpload(server_.GetURL("/"), kUploadBody, 0,
callback.callback());
callback.WaitForCall();
}
@@ -320,7 +327,7 @@ TEST_F(ReportingUploaderTest, DontCacheResponse) {
{
TestUploadCallback callback;
- uploader_->StartUpload(server_.GetURL("/"), kUploadBody,
+ uploader_->StartUpload(server_.GetURL("/"), kUploadBody, 0,
callback.callback());
callback.WaitForCall();
}
diff --git a/chromium/net/server/http_server.cc b/chromium/net/server/http_server.cc
index f0fc3c34a0a..49a31960256 100644
--- a/chromium/net/server/http_server.cc
+++ b/chromium/net/server/http_server.cc
@@ -298,8 +298,7 @@ int HttpServer::HandleReadResult(HttpConnection* connection, int rv) {
content_length > kMaxBodySize) {
SendResponse(connection->id(),
HttpServerResponseInfo::CreateFor500(
- "request content-length too big or unknown: " +
- request.GetHeaderValue(kContentLength)),
+ "request content-length too big or unknown."),
kHttpServerErrorResponseTrafficAnnotation);
Close(connection->id());
return ERR_CONNECTION_CLOSED;
diff --git a/chromium/net/socket/client_socket_factory.cc b/chromium/net/socket/client_socket_factory.cc
index 908e3191d09..c54fdf7d5c2 100644
--- a/chromium/net/socket/client_socket_factory.cc
+++ b/chromium/net/socket/client_socket_factory.cc
@@ -40,20 +40,19 @@ class DefaultClientSocketFactory : public ClientSocketFactory,
std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
NetLog* net_log,
const NetLogSource& source) override {
return std::unique_ptr<DatagramClientSocket>(
- new UDPClientSocket(bind_type, rand_int_cb, net_log, source));
+ new UDPClientSocket(bind_type, net_log, source));
}
- std::unique_ptr<StreamSocket> CreateTransportClientSocket(
+ std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
const AddressList& addresses,
std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
NetLog* net_log,
const NetLogSource& source) override {
- return std::unique_ptr<StreamSocket>(new TCPClientSocket(
- addresses, std::move(socket_performance_watcher), net_log, source));
+ return std::make_unique<TCPClientSocket>(
+ addresses, std::move(socket_performance_watcher), net_log, source);
}
std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
diff --git a/chromium/net/socket/client_socket_factory.h b/chromium/net/socket/client_socket_factory.h
index 65490656f5a..39d14a80fd1 100644
--- a/chromium/net/socket/client_socket_factory.h
+++ b/chromium/net/socket/client_socket_factory.h
@@ -9,9 +9,9 @@
#include <string>
#include "net/base/net_export.h"
-#include "net/base/rand_callback.h"
#include "net/socket/datagram_socket.h"
#include "net/socket/socket_performance_watcher.h"
+#include "net/socket/transport_client_socket.h"
namespace net {
@@ -24,7 +24,6 @@ struct NetLogSource;
class SSLClientSocket;
struct SSLClientSocketContext;
struct SSLConfig;
-class StreamSocket;
// An interface used to instantiate StreamSocket objects. Used to facilitate
// testing code with mock socket implementations.
@@ -36,11 +35,10 @@ class NET_EXPORT ClientSocketFactory {
// if it has one.
virtual std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
NetLog* net_log,
const NetLogSource& source) = 0;
- virtual std::unique_ptr<StreamSocket> CreateTransportClientSocket(
+ virtual std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
const AddressList& addresses,
std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
NetLog* net_log,
diff --git a/chromium/net/socket/client_socket_handle.h b/chromium/net/socket/client_socket_handle.h
index 1a0afb96e88..3926bcc18ea 100644
--- a/chromium/net/socket/client_socket_handle.h
+++ b/chromium/net/socket/client_socket_handle.h
@@ -7,6 +7,7 @@
#include <memory>
#include <string>
+#include <utility>
#include "base/logging.h"
#include "base/macros.h"
@@ -151,8 +152,9 @@ class NET_EXPORT ClientSocketHandle {
void set_ssl_error_response_info(const HttpResponseInfo& ssl_error_state) {
ssl_error_response_info_ = ssl_error_state;
}
- void set_pending_http_proxy_connection(ClientSocketHandle* connection) {
- pending_http_proxy_connection_.reset(connection);
+ void set_pending_http_proxy_connection(
+ std::unique_ptr<ClientSocketHandle> connection) {
+ pending_http_proxy_connection_ = std::move(connection);
}
void set_connection_attempts(const ConnectionAttempts& attempts) {
connection_attempts_ = attempts;
@@ -169,8 +171,8 @@ class NET_EXPORT ClientSocketHandle {
const HttpResponseInfo& ssl_error_response_info() const {
return ssl_error_response_info_;
}
- ClientSocketHandle* release_pending_http_proxy_connection() {
- return pending_http_proxy_connection_.release();
+ std::unique_ptr<ClientSocketHandle> release_pending_http_proxy_connection() {
+ return std::move(pending_http_proxy_connection_);
}
// If the connection failed, returns the connection attempts made. (If it
// succeeded, they will be returned through the socket instead; see
diff --git a/chromium/net/socket/client_socket_pool_base_unittest.cc b/chromium/net/socket/client_socket_pool_base_unittest.cc
index 91e0e68b7c1..54f1e4e5de3 100644
--- a/chromium/net/socket/client_socket_pool_base_unittest.cc
+++ b/chromium/net/socket/client_socket_pool_base_unittest.cc
@@ -225,21 +225,20 @@ class MockClientSocketFactory : public ClientSocketFactory {
std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
NetLog* net_log,
const NetLogSource& source) override {
NOTREACHED();
return std::unique_ptr<DatagramClientSocket>();
}
- std::unique_ptr<StreamSocket> CreateTransportClientSocket(
+ std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
const AddressList& addresses,
std::unique_ptr<
SocketPerformanceWatcher> /* socket_performance_watcher */,
NetLog* /* net_log */,
const NetLogSource& /*source*/) override {
allocation_count_++;
- return std::unique_ptr<StreamSocket>();
+ return nullptr;
}
std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
diff --git a/chromium/net/socket/client_socket_pool_manager.cc b/chromium/net/socket/client_socket_pool_manager.cc
index 14ee93e0c80..7c7adb0400c 100644
--- a/chromium/net/socket/client_socket_pool_manager.cc
+++ b/chromium/net/socket/client_socket_pool_manager.cc
@@ -4,6 +4,8 @@
#include "net/socket/client_socket_pool_manager.h"
+#include <memory>
+
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "net/base/load_flags.h"
@@ -41,8 +43,8 @@ static_assert(arraysize(g_max_sockets_per_pool) ==
// be the same as the limit for ws. Also note that Firefox uses a limit of 200.
// See http://crbug.com/486800
int g_max_sockets_per_group[] = {
- 6, // NORMAL_SOCKET_POOL
- 255 // WEBSOCKET_SOCKET_POOL
+ 6, // NORMAL_SOCKET_POOL
+ 255 // WEBSOCKET_SOCKET_POOL
};
static_assert(arraysize(g_max_sockets_per_group) ==
@@ -87,7 +89,7 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type,
scoped_refptr<SOCKSSocketParams> socks_params;
std::unique_ptr<HostPortPair> proxy_host_port;
- bool using_ssl = group_type == ClientSocketPoolManager::SSL_GROUP;
+ const bool using_ssl = group_type == ClientSocketPoolManager::SSL_GROUP;
HostPortPair origin_host_port = endpoint;
if (!using_ssl && session->params().testing_fixed_http_port != 0) {
@@ -96,10 +98,9 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type,
origin_host_port.set_port(session->params().testing_fixed_https_port);
}
- bool disable_resolver_cache =
- request_load_flags & LOAD_BYPASS_CACHE ||
- request_load_flags & LOAD_VALIDATE_CACHE ||
- request_load_flags & LOAD_DISABLE_CACHE;
+ // LOAD_BYPASS_CACHE should bypass the host cache as well as the HTTP cache.
+ // Other cache-related load flags should not have this effect.
+ bool disable_resolver_cache = request_load_flags & LOAD_BYPASS_CACHE;
int load_flags = request_load_flags;
if (session->params().ignore_certificate_errors)
@@ -116,7 +117,11 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type,
connection_group = "ftp/" + connection_group;
}
if (using_ssl) {
- connection_group = "ssl/" + connection_group;
+ std::string prefix = "ssl/";
+ if (ssl_config_for_origin.version_interference_probe) {
+ prefix += "version-interference-probe/";
+ }
+ connection_group = prefix + connection_group;
}
ClientSocketPool::RespectLimits respect_limits =
@@ -185,7 +190,8 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type,
origin_host_port, session->http_auth_cache(),
session->http_auth_handler_factory(), session->spdy_session_pool(),
session->quic_stream_factory(), proxy_server.is_trusted_proxy(),
- force_tunnel || using_ssl);
+ force_tunnel || using_ssl,
+ NetworkTrafficAnnotationTag(proxy_info.traffic_annotation()));
} else {
DCHECK(proxy_info.is_socks());
char socks_version;
@@ -198,7 +204,7 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type,
socks_params = new SOCKSSocketParams(
proxy_tcp_params, socks_version == '5', origin_host_port,
- proxy_info.traffic_annotation());
+ NetworkTrafficAnnotationTag(proxy_info.traffic_annotation()));
}
}
@@ -426,6 +432,8 @@ int InitSocketHandleForRawConnect(const HostPortPair& host_port_pair,
int InitSocketHandleForTlsConnect(const HostPortPair& endpoint,
HttpNetworkSession* session,
+ int request_load_flags,
+ RequestPriority request_priority,
const ProxyInfo& proxy_info,
const SSLConfig& ssl_config_for_origin,
const SSLConfig& ssl_config_for_proxy,
@@ -435,8 +443,6 @@ int InitSocketHandleForTlsConnect(const HostPortPair& endpoint,
const CompletionCallback& callback) {
DCHECK(socket_handle);
HttpRequestHeaders request_extra_headers;
- int request_load_flags = 0;
- RequestPriority request_priority = MEDIUM;
return InitSocketPoolHelper(
ClientSocketPoolManager::SSL_GROUP, endpoint, request_extra_headers,
request_load_flags, request_priority, session, proxy_info,
diff --git a/chromium/net/socket/client_socket_pool_manager.h b/chromium/net/socket/client_socket_pool_manager.h
index df54c05e7d6..8837701de05 100644
--- a/chromium/net/socket/client_socket_pool_manager.h
+++ b/chromium/net/socket/client_socket_pool_manager.h
@@ -146,6 +146,7 @@ int InitSocketHandleForWebSocketRequest(
const OnHostResolutionCallback& resolution_callback,
const CompletionCallback& callback);
+// Deprecated: Please do not use this outside of //net and //services/network.
// A helper method that uses the passed in proxy information to initialize a
// ClientSocketHandle with the relevant socket pool. Use this method for
// a raw socket connection to a host-port pair (that needs to tunnel through
@@ -163,6 +164,7 @@ NET_EXPORT int InitSocketHandleForRawConnect(
ClientSocketHandle* socket_handle,
const CompletionCallback& callback);
+// Deprecated: Please do not use this outside of //net and //services/network.
// A helper method that uses the passed in proxy information to initialize a
// ClientSocketHandle with the relevant socket pool. Use this method for
// a raw socket connection with TLS negotiation to a host-port pair (that needs
@@ -170,6 +172,8 @@ NET_EXPORT int InitSocketHandleForRawConnect(
NET_EXPORT int InitSocketHandleForTlsConnect(
const HostPortPair& host_port_pair,
HttpNetworkSession* session,
+ int request_load_flags,
+ RequestPriority request_priority,
const ProxyInfo& proxy_info,
const SSLConfig& ssl_config_for_origin,
const SSLConfig& ssl_config_for_proxy,
diff --git a/chromium/net/socket/client_socket_pool_manager_impl.cc b/chromium/net/socket/client_socket_pool_manager_impl.cc
index 872582e363a..1eb70718052 100644
--- a/chromium/net/socket/client_socket_pool_manager_impl.cc
+++ b/chromium/net/socket/client_socket_pool_manager_impl.cc
@@ -52,6 +52,7 @@ ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
CTPolicyEnforcer* ct_policy_enforcer,
const std::string& ssl_session_cache_shard,
SSLConfigService* ssl_config_service,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
HttpNetworkSession::SocketPoolType pool_type)
: net_log_(net_log),
socket_factory_(socket_factory),
@@ -73,6 +74,7 @@ ClientSocketPoolManagerImpl::ClientSocketPoolManagerImpl(
max_sockets_per_group(pool_type),
host_resolver,
socket_factory_,
+ websocket_endpoint_lock_manager,
net_log)
: new TransportClientSocketPool(
max_sockets_per_pool(pool_type),
diff --git a/chromium/net/socket/client_socket_pool_manager_impl.h b/chromium/net/socket/client_socket_pool_manager_impl.h
index 7946a4edc72..add67d20387 100644
--- a/chromium/net/socket/client_socket_pool_manager_impl.h
+++ b/chromium/net/socket/client_socket_pool_manager_impl.h
@@ -41,6 +41,7 @@ class SSLClientSocketPool;
class SSLConfigService;
class TransportClientSocketPool;
class TransportSecurityState;
+class WebSocketEndpointLockManager;
class NET_EXPORT_PRIVATE ClientSocketPoolManagerImpl
: public ClientSocketPoolManager,
@@ -59,6 +60,7 @@ class NET_EXPORT_PRIVATE ClientSocketPoolManagerImpl
CTPolicyEnforcer* ct_policy_enforcer,
const std::string& ssl_session_cache_shard,
SSLConfigService* ssl_config_service,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
HttpNetworkSession::SocketPoolType pool_type);
~ClientSocketPoolManagerImpl() override;
diff --git a/chromium/net/socket/datagram_client_socket.h b/chromium/net/socket/datagram_client_socket.h
index 826a2e70902..01318864cfe 100644
--- a/chromium/net/socket/datagram_client_socket.h
+++ b/chromium/net/socket/datagram_client_socket.h
@@ -5,6 +5,7 @@
#ifndef NET_SOCKET_DATAGRAM_CLIENT_SOCKET_H_
#define NET_SOCKET_DATAGRAM_CLIENT_SOCKET_H_
+#include "net/base/datagram_buffer.h"
#include "net/base/net_export.h"
#include "net/base/network_change_notifier.h"
#include "net/socket/datagram_socket.h"
@@ -48,6 +49,82 @@ class NET_EXPORT_PRIVATE DatagramClientSocket : public DatagramSocket,
// Enables experimental optimization for receiving data from a socket.
// By default, this method is no-op.
virtual void EnableRecvOptimization() {}
+
+ // As Write, but internally this can delay writes and batch them up
+ // for writing in a separate task. This is to increase throughput
+ // in bulk transfer scenarios (in QUIC) where a substantial
+ // proportion of CPU time is spend in kernel UDP writes, and total
+ // CPU time of the net IO thread saturates single core capacity.
+ // The batching is required to allow overlapped computation time
+ // between user and kernel packet processing.
+ //
+ // Returns the number of bytes written or a net error code. A
+ // return value of zero is possible, because with batching enabled,
+ // the underlying socket write may be delayed so as to accumulate
+ // multiple buffers. The return value may also be larger than the
+ // number of bytes in |buffers| due to completion of previous
+ // writes. [ Writing the batch to the socket typically happens on a
+ // different thread/cpu core. ]
+ //
+ // As with |Write|, a return value of ERR_IO_PENDING indicates the
+ // caller should suspend further writes until the callback fires.
+ //
+ // If a socket write returns an error, it will be surfaced either as
+ // the return value from the next call to |WriteAsync|, or via the
+ // callback.
+ //
+ // Not all platforms will implement this, see |write_async_enabled()|
+ // below.
+ virtual int WriteAsync(
+ DatagramBuffers buffers,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) = 0;
+
+ // |buffer| is copied to an internal |DatagramBuffer|, caller
+ // |retains ownership of |buffer|.
+ virtual int WriteAsync(
+ const char* buffer,
+ size_t buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) = 0;
+
+ // With WriteAsync, the caller may wish to try unwritten buffers on
+ // a new socket, e.g. with QUIC connection migration.
+ virtual DatagramBuffers GetUnwrittenBuffers() = 0;
+
+ // Enable |WriteAsync()|. May be a noop, see |WriteAsyncEnabled()|
+ // below. Must be called right after construction and before other
+ // calls. This is intended to support rollout of |WriteAsync| for
+ // QUIC via a Finch trial, using the kWRBA client connection option.
+ virtual void SetWriteAsyncEnabled(bool enabled) = 0;
+
+ // Needed with |WriteAsync()| enabled, for socket's
+ // |DatagramBufferPool|. Must be called right after construction
+ // and before other calls.
+ virtual void SetMaxPacketSize(size_t max_packet_size) = 0;
+
+ // This is true if the |SetWriteAsyncEnabled(true)| has been called
+ // *and* the platform supports |WriteAsync()|.
+ virtual bool WriteAsyncEnabled() = 0;
+
+ // In |WriteAsync()|, allow socket writing to happen on a separate
+ // core when advantageous. This can increase maximum single-stream
+ // throughput. Must be called right after construction and before
+ // other calls. This is intended to support QUIC Finch trials, using
+ // the kMLTC client connection option.
+ virtual void SetWriteMultiCoreEnabled(bool enabled) = 0;
+
+ // In |WriteAsync()|, use |sendmmsg()| on platforms that support it.
+ // This can increase maximum single-stream throughput. Must be
+ // called right after construction and before other calls. This is
+ // intended to support QUIC Finch trials, using the kMMSG client
+ // connection option.
+ virtual void SetSendmmsgEnabled(bool enabled) = 0;
+
+ // This is to (de-)activate batching in |WriteAsync|, e.g. in
+ // |QuicChromiumClientSession| based on whether there are large
+ // upload stream(s) active.
+ virtual void SetWriteBatchingActive(bool active) = 0;
};
} // namespace net
diff --git a/chromium/net/socket/datagram_socket.h b/chromium/net/socket/datagram_socket.h
index f5294745cc3..254922dc06e 100644
--- a/chromium/net/socket/datagram_socket.h
+++ b/chromium/net/socket/datagram_socket.h
@@ -45,6 +45,10 @@ class NET_EXPORT_PRIVATE DatagramSocket {
// return ERR_IO_PENDING.
virtual int SetDoNotFragment() = 0;
+ // If |confirm| is true, then the MSG_CONFIRM flag will be passed to
+ // subsequent writes if it's supported by the platform.
+ virtual void SetMsgConfirm(bool confirm) = 0;
+
// Gets the NetLog for this socket.
virtual const NetLogWithSource& NetLog() const = 0;
};
diff --git a/chromium/net/socket/fuzzed_datagram_client_socket.cc b/chromium/net/socket/fuzzed_datagram_client_socket.cc
index 65043f505e3..ae62f938e47 100644
--- a/chromium/net/socket/fuzzed_datagram_client_socket.cc
+++ b/chromium/net/socket/fuzzed_datagram_client_socket.cc
@@ -91,6 +91,35 @@ int FuzzedDatagramClientSocket::GetLocalAddress(IPEndPoint* address) const {
void FuzzedDatagramClientSocket::UseNonBlockingIO() {}
+int FuzzedDatagramClientSocket::WriteAsync(
+ DatagramBuffers buffers,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
+ return -1;
+}
+
+int FuzzedDatagramClientSocket::WriteAsync(
+ const char* buffer,
+ size_t buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
+ return -1;
+}
+
+DatagramBuffers FuzzedDatagramClientSocket::GetUnwrittenBuffers() {
+ DatagramBuffers result;
+ return result;
+}
+
+void FuzzedDatagramClientSocket::SetWriteAsyncEnabled(bool enabled) {}
+bool FuzzedDatagramClientSocket::WriteAsyncEnabled() {
+ return false;
+}
+void FuzzedDatagramClientSocket::SetMaxPacketSize(size_t max_packet_size) {}
+void FuzzedDatagramClientSocket::SetWriteMultiCoreEnabled(bool enabled) {}
+void FuzzedDatagramClientSocket::SetSendmmsgEnabled(bool enabled) {}
+void FuzzedDatagramClientSocket::SetWriteBatchingActive(bool active) {}
+
const NetLogWithSource& FuzzedDatagramClientSocket::NetLog() const {
return net_log_;
}
diff --git a/chromium/net/socket/fuzzed_datagram_client_socket.h b/chromium/net/socket/fuzzed_datagram_client_socket.h
index 6d195626ad9..bb54f647b12 100644
--- a/chromium/net/socket/fuzzed_datagram_client_socket.h
+++ b/chromium/net/socket/fuzzed_datagram_client_socket.h
@@ -46,6 +46,23 @@ class FuzzedDatagramClientSocket : public DatagramClientSocket {
int GetPeerAddress(IPEndPoint* address) const override;
int GetLocalAddress(IPEndPoint* address) const override;
void UseNonBlockingIO() override;
+ int WriteAsync(
+ const char* buffer,
+ size_t buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
+ int WriteAsync(
+ DatagramBuffers buffers,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
+ DatagramBuffers GetUnwrittenBuffers() override;
+ void SetWriteAsyncEnabled(bool enabled) override;
+ void SetMaxPacketSize(size_t max_packet_size) override;
+ bool WriteAsyncEnabled() override;
+ void SetWriteMultiCoreEnabled(bool enabled) override;
+ void SetSendmmsgEnabled(bool enabled) override;
+ void SetWriteBatchingActive(bool active) override;
+
const NetLogWithSource& NetLog() const override;
// Socket implementation:
@@ -59,6 +76,7 @@ class FuzzedDatagramClientSocket : public DatagramClientSocket {
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
int SetDoNotFragment() override;
+ void SetMsgConfirm(bool confirm) override {}
private:
void OnReadComplete(const net::CompletionCallback& callback, int result);
diff --git a/chromium/net/socket/fuzzed_socket.cc b/chromium/net/socket/fuzzed_socket.cc
index be62fff5a8b..1eec23d95bd 100644
--- a/chromium/net/socket/fuzzed_socket.cc
+++ b/chromium/net/socket/fuzzed_socket.cc
@@ -19,6 +19,8 @@ namespace net {
namespace {
+const int kMaxAsyncReadsAndWrites = 1000;
+
// Some of the socket errors that can be returned by normal socket connection
// attempts.
const Error kConnectErrors[] = {
@@ -57,8 +59,12 @@ int FuzzedSocket::Read(IOBuffer* buf,
result = net_error_;
sync = !error_pending_;
} else {
- // Otherwise, use |data_provider_|.
- sync = data_provider_->ConsumeBool();
+ // Otherwise, use |data_provider_|. Always consume a bool, even when
+ // ForceSync() is true, to behave more consistently against input mutations.
+ sync = data_provider_->ConsumeBool() || ForceSync();
+
+ num_async_reads_and_writes_ += static_cast<int>(!sync);
+
std::string data = data_provider_->ConsumeRandomLengthString(buf_len);
result = data.size();
@@ -106,8 +112,12 @@ int FuzzedSocket::Write(
result = net_error_;
sync = !error_pending_;
} else {
- // Otherwise, use |data_|.
- sync = data_provider_->ConsumeBool();
+ // Otherwise, use |data_provider_|. Always consume a bool, even when
+ // ForceSync() is true, to behave more consistently against input mutations.
+ sync = data_provider_->ConsumeBool() || ForceSync();
+
+ num_async_reads_and_writes_ += static_cast<int>(!sync);
+
result = data_provider_->ConsumeUint8();
if (result > buf_len)
result = buf_len;
@@ -140,6 +150,11 @@ int FuzzedSocket::SetSendBufferSize(int32_t size) {
return OK;
}
+int FuzzedSocket::Bind(const net::IPEndPoint& local_addr) {
+ NOTREACHED();
+ return ERR_NOT_IMPLEMENTED;
+}
+
int FuzzedSocket::Connect(const CompletionCallback& callback) {
// Sockets can normally be reused, but don't support it here.
DCHECK_NE(net_error_, OK);
@@ -283,4 +298,8 @@ void FuzzedSocket::OnConnectComplete(const CompletionCallback& callback,
callback.Run(result);
}
+bool FuzzedSocket::ForceSync() const {
+ return (num_async_reads_and_writes_ >= kMaxAsyncReadsAndWrites);
+}
+
} // namespace net
diff --git a/chromium/net/socket/fuzzed_socket.h b/chromium/net/socket/fuzzed_socket.h
index 3340e4349d7..9febde19fea 100644
--- a/chromium/net/socket/fuzzed_socket.h
+++ b/chromium/net/socket/fuzzed_socket.h
@@ -14,7 +14,7 @@
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/log/net_log_with_source.h"
-#include "net/socket/stream_socket.h"
+#include "net/socket/transport_client_socket.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
namespace base {
@@ -39,7 +39,7 @@ class NetLog;
// reads and writes must be done in a deterministic order and for a
// deterministic number of bytes, every time the fuzzer is run with the same
// data.
-class FuzzedSocket : public StreamSocket {
+class FuzzedSocket : public TransportClientSocket {
public:
// |data_provider| is used as to determine behavior of the FuzzedSocket. It
// must remain valid until after the FuzzedSocket is destroyed.
@@ -69,7 +69,8 @@ class FuzzedSocket : public StreamSocket {
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
- // StreamSocket implementation:
+ // TransportClientSocket implementation:
+ int Bind(const net::IPEndPoint& local_addr) override;
int Connect(const CompletionCallback& callback) override;
void Disconnect() override;
bool IsConnected() const override;
@@ -99,6 +100,12 @@ class FuzzedSocket : public StreamSocket {
void OnWriteComplete(const CompletionCallback& callback, int result);
void OnConnectComplete(const CompletionCallback& callback, int result);
+ // Returns whether all operations should be synchronous. Starts returning
+ // true once there have been too many async reads and writes, as spinning the
+ // message loop too often tends to cause fuzzers to time out.
+ // See https://crbug.com/823012
+ bool ForceSync() const;
+
base::FuzzedDataProvider* data_provider_;
// If true, the result of the Connect() call is fuzzed - it can succeed or
@@ -122,6 +129,8 @@ class FuzzedSocket : public StreamSocket {
int64_t total_bytes_read_ = 0;
int64_t total_bytes_written_ = 0;
+ int num_async_reads_and_writes_ = 0;
+
NetLogWithSource net_log_;
IPEndPoint remote_address_;
diff --git a/chromium/net/socket/fuzzed_socket_factory.cc b/chromium/net/socket/fuzzed_socket_factory.cc
index ca158aea386..a28ac314fec 100644
--- a/chromium/net/socket/fuzzed_socket_factory.cc
+++ b/chromium/net/socket/fuzzed_socket_factory.cc
@@ -139,13 +139,13 @@ FuzzedSocketFactory::~FuzzedSocketFactory() = default;
std::unique_ptr<DatagramClientSocket>
FuzzedSocketFactory::CreateDatagramClientSocket(
DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
NetLog* net_log,
const NetLogSource& source) {
return std::make_unique<FuzzedDatagramClientSocket>(data_provider_);
}
-std::unique_ptr<StreamSocket> FuzzedSocketFactory::CreateTransportClientSocket(
+std::unique_ptr<TransportClientSocket>
+FuzzedSocketFactory::CreateTransportClientSocket(
const AddressList& addresses,
std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
NetLog* net_log,
diff --git a/chromium/net/socket/fuzzed_socket_factory.h b/chromium/net/socket/fuzzed_socket_factory.h
index 788594b8c37..081904a32e1 100644
--- a/chromium/net/socket/fuzzed_socket_factory.h
+++ b/chromium/net/socket/fuzzed_socket_factory.h
@@ -37,11 +37,10 @@ class FuzzedSocketFactory : public ClientSocketFactory {
std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
NetLog* net_log,
const NetLogSource& source) override;
- std::unique_ptr<StreamSocket> CreateTransportClientSocket(
+ std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
const AddressList& addresses,
std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
NetLog* net_log,
diff --git a/chromium/net/socket/socket_posix.cc b/chromium/net/socket/socket_posix.cc
index 91ce4e82e7a..81fa49a6cad 100644
--- a/chromium/net/socket/socket_posix.cc
+++ b/chromium/net/socket/socket_posix.cc
@@ -12,6 +12,7 @@
#include "base/callback_helpers.h"
#include "base/files/file_util.h"
#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
#include "base/posix/eintr_wrapper.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
@@ -174,7 +175,7 @@ int SocketPosix::Accept(std::unique_ptr<SocketPosix>* socket,
return rv;
if (!base::MessageLoopForIO::current()->WatchFileDescriptor(
- socket_fd_, true, base::MessageLoopForIO::WATCH_READ,
+ socket_fd_, true, base::MessagePumpForIO::WATCH_READ,
&accept_socket_watcher_, this)) {
PLOG(ERROR) << "WatchFileDescriptor failed on accept, errno " << errno;
return MapSystemError(errno);
@@ -199,7 +200,7 @@ int SocketPosix::Connect(const SockaddrStorage& address,
return rv;
if (!base::MessageLoopForIO::current()->WatchFileDescriptor(
- socket_fd_, true, base::MessageLoopForIO::WATCH_WRITE,
+ socket_fd_, true, base::MessagePumpForIO::WATCH_WRITE,
&write_socket_watcher_, this)) {
PLOG(ERROR) << "WatchFileDescriptor failed on connect, errno " << errno;
return MapSystemError(errno);
@@ -337,7 +338,7 @@ int SocketPosix::ReadIfReady(IOBuffer* buf,
return rv;
if (!base::MessageLoopForIO::current()->WatchFileDescriptor(
- socket_fd_, true, base::MessageLoopForIO::WATCH_READ,
+ socket_fd_, true, base::MessagePumpForIO::WATCH_READ,
&read_socket_watcher_, this)) {
PLOG(ERROR) << "WatchFileDescriptor failed on read, errno " << errno;
return MapSystemError(errno);
@@ -377,7 +378,7 @@ int SocketPosix::WaitForWrite(IOBuffer* buf,
DCHECK_LT(0, buf_len);
if (!base::MessageLoopForIO::current()->WatchFileDescriptor(
- socket_fd_, true, base::MessageLoopForIO::WATCH_WRITE,
+ socket_fd_, true, base::MessagePumpForIO::WATCH_WRITE,
&write_socket_watcher_, this)) {
PLOG(ERROR) << "WatchFileDescriptor failed on write, errno " << errno;
return MapSystemError(errno);
diff --git a/chromium/net/socket/socket_posix.h b/chromium/net/socket/socket_posix.h
index cdccc8c04bf..642a0fb0b01 100644
--- a/chromium/net/socket/socket_posix.h
+++ b/chromium/net/socket/socket_posix.h
@@ -10,7 +10,7 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_pump_for_io.h"
#include "base/threading/thread_checker.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
@@ -24,7 +24,8 @@ struct SockaddrStorage;
// Socket class to provide asynchronous read/write operations on top of the
// posix socket api. It supports AF_INET, AF_INET6, and AF_UNIX addresses.
-class NET_EXPORT_PRIVATE SocketPosix : public base::MessageLoopForIO::Watcher {
+class NET_EXPORT_PRIVATE SocketPosix
+ : public base::MessagePumpForIO::FdWatcher {
public:
SocketPosix();
~SocketPosix() override;
@@ -104,7 +105,7 @@ class NET_EXPORT_PRIVATE SocketPosix : public base::MessageLoopForIO::Watcher {
SocketDescriptor socket_fd() const { return socket_fd_; }
private:
- // base::MessageLoopForIO::Watcher methods.
+ // base::MessagePumpForIO::FdWatcher methods.
void OnFileCanReadWithoutBlocking(int fd) override;
void OnFileCanWriteWithoutBlocking(int fd) override;
@@ -125,11 +126,11 @@ class NET_EXPORT_PRIVATE SocketPosix : public base::MessageLoopForIO::Watcher {
SocketDescriptor socket_fd_;
- base::MessageLoopForIO::FileDescriptorWatcher accept_socket_watcher_;
+ base::MessagePumpForIO::FdWatchController accept_socket_watcher_;
std::unique_ptr<SocketPosix>* accept_socket_;
CompletionCallback accept_callback_;
- base::MessageLoopForIO::FileDescriptorWatcher read_socket_watcher_;
+ base::MessagePumpForIO::FdWatchController read_socket_watcher_;
// Non-null when a Read() is in progress.
scoped_refptr<IOBuffer> read_buf_;
@@ -139,7 +140,7 @@ class NET_EXPORT_PRIVATE SocketPosix : public base::MessageLoopForIO::Watcher {
// Non-null when a ReadIfReady() is in progress.
CompletionCallback read_if_ready_callback_;
- base::MessageLoopForIO::FileDescriptorWatcher write_socket_watcher_;
+ base::MessagePumpForIO::FdWatchController write_socket_watcher_;
scoped_refptr<IOBuffer> write_buf_;
int write_buf_len_;
// External callback; called when write or connect is complete.
diff --git a/chromium/net/socket/socket_test_util.cc b/chromium/net/socket/socket_test_util.cc
index c66bedf2e30..9d53bf9e2e1 100644
--- a/chromium/net/socket/socket_test_util.cc
+++ b/chromium/net/socket/socket_test_util.cc
@@ -20,6 +20,7 @@
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/rand_util.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -725,20 +726,18 @@ void MockClientSocketFactory::ResetNextMockIndexes() {
std::unique_ptr<DatagramClientSocket>
MockClientSocketFactory::CreateDatagramClientSocket(
DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
NetLog* net_log,
const NetLogSource& source) {
SocketDataProvider* data_provider = mock_data_.GetNext();
std::unique_ptr<MockUDPClientSocket> socket(
new MockUDPClientSocket(data_provider, net_log));
if (bind_type == DatagramSocket::RANDOM_BIND)
- socket->set_source_port(
- static_cast<uint16_t>(rand_int_cb.Run(1025, 65535)));
+ socket->set_source_port(static_cast<uint16_t>(base::RandInt(1025, 65535)));
udp_client_socket_ports_.push_back(socket->source_port());
return std::move(socket);
}
-std::unique_ptr<StreamSocket>
+std::unique_ptr<TransportClientSocket>
MockClientSocketFactory::CreateTransportClientSocket(
const AddressList& addresses,
std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
@@ -775,6 +774,7 @@ void MockClientSocketFactory::ClearSSLSessionCache() {
MockClientSocket::MockClientSocket(const NetLogWithSource& net_log)
: connected_(false), net_log_(net_log), weak_factory_(this) {
+ local_addr_ = IPEndPoint(IPAddress(192, 0, 2, 33), 123);
peer_addr_ = IPEndPoint(IPAddress(192, 0, 2, 33), 0);
}
@@ -786,6 +786,11 @@ int MockClientSocket::SetSendBufferSize(int32_t size) {
return OK;
}
+int MockClientSocket::Bind(const net::IPEndPoint& local_addr) {
+ local_addr_ = local_addr;
+ return net::OK;
+}
+
void MockClientSocket::Disconnect() {
connected_ = false;
}
@@ -806,7 +811,7 @@ int MockClientSocket::GetPeerAddress(IPEndPoint* address) const {
}
int MockClientSocket::GetLocalAddress(IPEndPoint* address) const {
- *address = IPEndPoint(IPAddress(192, 0, 2, 33), 123);
+ *address = local_addr_;
return OK;
}
@@ -826,41 +831,6 @@ void MockClientSocket::GetConnectionAttempts(ConnectionAttempts* out) const {
out->clear();
}
-int64_t MockClientSocket::GetTotalReceivedBytes() const {
- NOTIMPLEMENTED();
- return 0;
-}
-
-void MockClientSocket::GetSSLCertRequestInfo(
- SSLCertRequestInfo* cert_request_info) {
-}
-
-int MockClientSocket::ExportKeyingMaterial(const base::StringPiece& label,
- bool has_context,
- const base::StringPiece& context,
- unsigned char* out,
- unsigned int outlen) {
- memset(out, 'A', outlen);
- return OK;
-}
-
-ChannelIDService* MockClientSocket::GetChannelIDService() const {
- NOTREACHED();
- return NULL;
-}
-
-Error MockClientSocket::GetTokenBindingSignature(crypto::ECPrivateKey* key,
- TokenBindingType tb_type,
- std::vector<uint8_t>* out) {
- NOTREACHED();
- return ERR_NOT_IMPLEMENTED;
-}
-
-crypto::ECPrivateKey* MockClientSocket::GetChannelIDKey() const {
- NOTREACHED();
- return NULL;
-}
-
MockClientSocket::~MockClientSocket() = default;
void MockClientSocket::RunCallbackAsync(const CompletionCallback& callback,
@@ -1176,13 +1146,10 @@ MockSSLClientSocket::MockSSLClientSocket(
const HostPortPair& host_port_pair,
const SSLConfig& ssl_config,
SSLSocketDataProvider* data)
- : MockClientSocket(
- // Have to use the right NetLogWithSource for LoadTimingInfo
- // regression
- // tests.
- transport_socket->socket()->NetLog()),
+ : net_log_(transport_socket->socket()->NetLog()),
transport_(std::move(transport_socket)),
- data_(data) {
+ data_(data),
+ weak_factory_(this) {
DCHECK(data_);
peer_addr_ = data->connect.peer_addr;
}
@@ -1213,6 +1180,7 @@ int MockSSLClientSocket::Write(
int MockSSLClientSocket::Connect(const CompletionCallback& callback) {
DCHECK(transport_->socket()->IsConnected());
+ data_->is_connect_data_consumed = true;
if (data_->connect.result == OK)
connected_ = true;
if (data_->connect.mode == ASYNC) {
@@ -1223,7 +1191,6 @@ int MockSSLClientSocket::Connect(const CompletionCallback& callback) {
}
void MockSSLClientSocket::Disconnect() {
- MockClientSocket::Disconnect();
if (transport_->socket() != NULL)
transport_->socket()->Disconnect();
}
@@ -1240,6 +1207,11 @@ bool MockSSLClientSocket::WasEverUsed() const {
return transport_->socket()->WasEverUsed();
}
+int MockSSLClientSocket::GetLocalAddress(IPEndPoint* address) const {
+ *address = IPEndPoint(IPAddress(192, 0, 2, 33), 123);
+ return OK;
+}
+
int MockSSLClientSocket::GetPeerAddress(IPEndPoint* address) const {
return transport_->socket()->GetPeerAddress(address);
}
@@ -1262,6 +1234,32 @@ void MockSSLClientSocket::ApplySocketTag(const SocketTag& tag) {
return transport_->socket()->ApplySocketTag(tag);
}
+const NetLogWithSource& MockSSLClientSocket::NetLog() const {
+ return net_log_;
+}
+
+void MockSSLClientSocket::GetConnectionAttempts(ConnectionAttempts* out) const {
+ out->clear();
+}
+
+int64_t MockSSLClientSocket::GetTotalReceivedBytes() const {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
+int64_t MockClientSocket::GetTotalReceivedBytes() const {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
+int MockSSLClientSocket::SetReceiveBufferSize(int32_t size) {
+ return OK;
+}
+
+int MockSSLClientSocket::SetSendBufferSize(int32_t size) {
+ return OK;
+}
+
void MockSSLClientSocket::GetSSLCertRequestInfo(
SSLCertRequestInfo* cert_request_info) {
DCHECK(cert_request_info);
@@ -1289,6 +1287,33 @@ Error MockSSLClientSocket::GetTokenBindingSignature(crypto::ECPrivateKey* key,
return OK;
}
+int MockSSLClientSocket::ExportKeyingMaterial(const base::StringPiece& label,
+ bool has_context,
+ const base::StringPiece& context,
+ unsigned char* out,
+ unsigned int outlen) {
+ memset(out, 'A', outlen);
+ return OK;
+}
+
+crypto::ECPrivateKey* MockSSLClientSocket::GetChannelIDKey() const {
+ NOTREACHED();
+ return NULL;
+}
+
+void MockSSLClientSocket::RunCallbackAsync(const CompletionCallback& callback,
+ int result) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(&MockSSLClientSocket::RunCallback,
+ weak_factory_.GetWeakPtr(), callback, result));
+}
+
+void MockSSLClientSocket::RunCallback(const CompletionCallback& callback,
+ int result) {
+ if (!callback.is_null())
+ callback.Run(result);
+}
+
void MockSSLClientSocket::OnReadComplete(const MockRead& data) {
NOTIMPLEMENTED();
}
@@ -1382,6 +1407,80 @@ int MockUDPClientSocket::Write(
return write_result.result;
}
+int MockUDPClientSocket::WriteAsync(
+ const char* buffer,
+ size_t buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& /* traffic_annotation */) {
+ DCHECK(buffer);
+ DCHECK_GT(buf_len, 0u);
+
+ if (!connected_ || !data_)
+ return ERR_UNEXPECTED;
+ data_transferred_ = true;
+
+ std::string data(buffer, buf_len);
+ MockWriteResult write_result = data_->OnWrite(data);
+
+ // ERR_IO_PENDING is a signal that the socket data will call back
+ // asynchronously.
+ if (write_result.result == ERR_IO_PENDING) {
+ pending_write_callback_ = callback;
+ return ERR_IO_PENDING;
+ }
+ if (write_result.mode == ASYNC) {
+ RunCallbackAsync(callback, write_result.result);
+ return ERR_IO_PENDING;
+ }
+ return write_result.result;
+}
+
+int MockUDPClientSocket::WriteAsync(
+ DatagramBuffers buffers,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& /* traffic_annotation */) {
+ DCHECK(!buffers.empty());
+
+ if (!connected_ || !data_)
+ return ERR_UNEXPECTED;
+
+ unwritten_buffers_ = std::move(buffers);
+
+ int rv = 0;
+ size_t buf_len = 0;
+ do {
+ auto& buf = unwritten_buffers_.front();
+
+ buf_len = buf->length();
+ std::string data(buf->data(), buf_len);
+ MockWriteResult write_result = data_->OnWrite(data);
+ rv = write_result.result;
+
+ // ERR_IO_PENDING is a signal that the socket data will call back
+ // asynchronously.
+ if (write_result.result == ERR_IO_PENDING) {
+ pending_write_callback_ = callback;
+ return ERR_IO_PENDING;
+ }
+ if (write_result.mode == ASYNC) {
+ RunCallbackAsync(callback, write_result.result);
+ return ERR_IO_PENDING;
+ }
+
+ if (rv < 0) {
+ return rv;
+ }
+
+ unwritten_buffers_.pop_front();
+ } while (!unwritten_buffers_.empty());
+
+ return buf_len;
+}
+
+DatagramBuffers MockUDPClientSocket::GetUnwrittenBuffers() {
+ return std::move(unwritten_buffers_);
+}
+
int MockUDPClientSocket::SetReceiveBufferSize(int32_t size) {
return OK;
}
@@ -1410,6 +1509,15 @@ int MockUDPClientSocket::GetLocalAddress(IPEndPoint* address) const {
void MockUDPClientSocket::UseNonBlockingIO() {}
+void MockUDPClientSocket::SetWriteAsyncEnabled(bool enabled) {}
+bool MockUDPClientSocket::WriteAsyncEnabled() {
+ return false;
+}
+void MockUDPClientSocket::SetMaxPacketSize(size_t max_packet_size) {}
+void MockUDPClientSocket::SetWriteMultiCoreEnabled(bool enabled) {}
+void MockUDPClientSocket::SetSendmmsgEnabled(bool enabled) {}
+void MockUDPClientSocket::SetWriteBatchingActive(bool active) {}
+
const NetLogWithSource& MockUDPClientSocket::NetLog() const {
return net_log_;
}
@@ -1775,26 +1883,15 @@ void MockSOCKSClientSocketPool::ReleaseSocket(
return transport_pool_->ReleaseSocket(group_name, std::move(socket), id);
}
-ScopedWebSocketEndpointZeroUnlockDelay::
- ScopedWebSocketEndpointZeroUnlockDelay() {
- old_delay_ =
- WebSocketEndpointLockManager::GetInstance()->SetUnlockDelayForTesting(
- base::TimeDelta());
-}
-
-ScopedWebSocketEndpointZeroUnlockDelay::
- ~ScopedWebSocketEndpointZeroUnlockDelay() {
- base::TimeDelta active_delay =
- WebSocketEndpointLockManager::GetInstance()->SetUnlockDelayForTesting(
- old_delay_);
- EXPECT_EQ(active_delay, base::TimeDelta());
-}
-
WrappedStreamSocket::WrappedStreamSocket(
std::unique_ptr<StreamSocket> transport)
: transport_(std::move(transport)) {}
WrappedStreamSocket::~WrappedStreamSocket() {}
+int WrappedStreamSocket::Bind(const net::IPEndPoint& local_addr) {
+ NOTREACHED();
+ return ERR_FAILED;
+}
int WrappedStreamSocket::Connect(const CompletionCallback& callback) {
return transport_->Connect(callback);
}
@@ -1908,7 +2005,7 @@ void MockTaggingStreamSocket::ApplySocketTag(const SocketTag& tag) {
transport_->ApplySocketTag(tag);
}
-std::unique_ptr<StreamSocket>
+std::unique_ptr<TransportClientSocket>
MockTaggingClientSocketFactory::CreateTransportClientSocket(
const AddressList& addresses,
std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
@@ -1924,12 +2021,11 @@ MockTaggingClientSocketFactory::CreateTransportClientSocket(
std::unique_ptr<DatagramClientSocket>
MockTaggingClientSocketFactory::CreateDatagramClientSocket(
DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
NetLog* net_log,
const NetLogSource& source) {
std::unique_ptr<DatagramClientSocket> socket(
- MockClientSocketFactory::CreateDatagramClientSocket(
- bind_type, rand_int_cb, net_log, source));
+ MockClientSocketFactory::CreateDatagramClientSocket(bind_type, net_log,
+ source));
udp_socket_ = static_cast<MockUDPClientSocket*>(socket.get());
return socket;
}
diff --git a/chromium/net/socket/socket_test_util.h b/chromium/net/socket/socket_test_util.h
index b9b0f024c43..97c1b1cfc56 100644
--- a/chromium/net/socket/socket_test_util.h
+++ b/chromium/net/socket/socket_test_util.h
@@ -21,7 +21,6 @@
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/strings/string16.h"
-#include "base/time/time.h"
#include "build/build_config.h"
#include "net/base/address_list.h"
#include "net/base/io_buffer.h"
@@ -39,6 +38,7 @@
#include "net/socket/socks_client_socket_pool.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/ssl_client_socket_pool.h"
+#include "net/socket/transport_client_socket.h"
#include "net/socket/transport_client_socket_pool.h"
#include "net/ssl/ssl_config_service.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
@@ -360,6 +360,9 @@ struct SSLSocketDataProvider {
SSLSocketDataProvider(const SSLSocketDataProvider& other);
~SSLSocketDataProvider();
+ // Returns whether MockConnect data has been consumed.
+ bool ConnectDataConsumed() const { return is_connect_data_consumed; }
+
// Result for Connect().
MockConnect connect;
@@ -374,6 +377,8 @@ struct SSLSocketDataProvider {
ChannelIDService* channel_id_service;
base::Optional<NextProtoVector> next_protos_expected_in_ssl_config;
+
+ bool is_connect_data_consumed = false;
};
// Uses the sequence_number field in the mock reads and writes to
@@ -528,10 +533,9 @@ class MockClientSocketFactory : public ClientSocketFactory {
// ClientSocketFactory
std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
NetLog* net_log,
const NetLogSource& source) override;
- std::unique_ptr<StreamSocket> CreateTransportClientSocket(
+ std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
const AddressList& addresses,
std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
NetLog* net_log,
@@ -559,7 +563,7 @@ class MockClientSocketFactory : public ClientSocketFactory {
DISALLOW_COPY_AND_ASSIGN(MockClientSocketFactory);
};
-class MockClientSocket : public SSLClientSocket {
+class MockClientSocket : public TransportClientSocket {
public:
// The NetLogWithSource is needed to test LoadTimingInfo, which uses NetLog
// IDs as
@@ -577,7 +581,8 @@ class MockClientSocket : public SSLClientSocket {
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
- // StreamSocket implementation.
+ // TransportClientSocket implementation.
+ int Bind(const net::IPEndPoint& local_addr) override;
int Connect(const CompletionCallback& callback) override = 0;
void Disconnect() override;
bool IsConnected() const override;
@@ -595,19 +600,6 @@ class MockClientSocket : public SSLClientSocket {
int64_t GetTotalReceivedBytes() const override;
void ApplySocketTag(const SocketTag& tag) override {}
- // SSLClientSocket implementation.
- void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
- int ExportKeyingMaterial(const base::StringPiece& label,
- bool has_context,
- const base::StringPiece& context,
- unsigned char* out,
- unsigned int outlen) override;
- ChannelIDService* GetChannelIDService() const override;
- Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
- TokenBindingType tb_type,
- std::vector<uint8_t>* out) override;
- crypto::ECPrivateKey* GetChannelIDKey() const override;
-
protected:
~MockClientSocket() override;
void RunCallbackAsync(const CompletionCallback& callback, int result);
@@ -616,7 +608,7 @@ class MockClientSocket : public SSLClientSocket {
// True if Connect completed successfully and Disconnect hasn't been called.
bool connected_;
- // Address of the "remote" peer we're connected to.
+ IPEndPoint local_addr_;
IPEndPoint peer_addr_;
NetLogWithSource net_log_;
@@ -709,7 +701,7 @@ class MockTCPClientSocket : public MockClientSocket, public AsyncSocket {
DISALLOW_COPY_AND_ASSIGN(MockTCPClientSocket);
};
-class MockSSLClientSocket : public MockClientSocket, public AsyncSocket {
+class MockSSLClientSocket : public AsyncSocket, public SSLClientSocket {
public:
MockSSLClientSocket(std::unique_ptr<ClientSocketHandle> transport_socket,
const HostPortPair& host_and_port,
@@ -736,16 +728,34 @@ class MockSSLClientSocket : public MockClientSocket, public AsyncSocket {
bool IsConnectedAndIdle() const override;
bool WasEverUsed() const override;
int GetPeerAddress(IPEndPoint* address) const override;
+ int GetLocalAddress(IPEndPoint* address) const override;
bool WasAlpnNegotiated() const override;
NextProto GetNegotiatedProtocol() const override;
bool GetSSLInfo(SSLInfo* ssl_info) override;
void ApplySocketTag(const SocketTag& tag) override;
+ const NetLogWithSource& NetLog() const override;
+ void SetSubresourceSpeculation() override {}
+ void SetOmniboxSpeculation() override {}
+ void GetConnectionAttempts(ConnectionAttempts* out) const override;
+ void ClearConnectionAttempts() override {}
+ void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+ int64_t GetTotalReceivedBytes() const override;
+ int SetReceiveBufferSize(int32_t size) override;
+ int SetSendBufferSize(int32_t size) override;
// SSLClientSocket implementation.
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
TokenBindingType tb_type,
std::vector<uint8_t>* out) override;
+ int ExportKeyingMaterial(const base::StringPiece& label,
+ bool has_context,
+ const base::StringPiece& context,
+ unsigned char* out,
+ unsigned int outlen) override;
+ ChannelIDService* GetChannelIDService() const override;
+ crypto::ECPrivateKey* GetChannelIDKey() const override;
+
// This MockSocket does not implement the manual async IO feature.
void OnReadComplete(const MockRead& data) override;
void OnWriteComplete(int rv) override;
@@ -755,15 +765,22 @@ class MockSSLClientSocket : public MockClientSocket, public AsyncSocket {
// TODO(mmenke): Probably a good idea to support it, anyways.
void OnDataProviderDestroyed() override {}
- ChannelIDService* GetChannelIDService() const override;
-
private:
static void ConnectCallback(MockSSLClientSocket* ssl_client_socket,
const CompletionCallback& callback,
int rv);
+ void RunCallbackAsync(const CompletionCallback& callback, int result);
+ void RunCallback(const CompletionCallback& callback, int result);
+
+ bool connected_ = false;
+ NetLogWithSource net_log_;
std::unique_ptr<ClientSocketHandle> transport_;
SSLSocketDataProvider* data_;
+ // Address of the "remote" peer we're connected to.
+ IPEndPoint peer_addr_;
+
+ base::WeakPtrFactory<MockSSLClientSocket> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(MockSSLClientSocket);
};
@@ -781,6 +798,17 @@ class MockUDPClientSocket : public DatagramClientSocket, public AsyncSocket {
int buf_len,
const CompletionCallback& callback,
const NetworkTrafficAnnotationTag& traffic_annotation) override;
+ int WriteAsync(
+ DatagramBuffers buffers,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
+ int WriteAsync(
+ const char* buffer,
+ size_t buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
+ DatagramBuffers GetUnwrittenBuffers() override;
+
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
int SetDoNotFragment() override;
@@ -790,6 +818,12 @@ class MockUDPClientSocket : public DatagramClientSocket, public AsyncSocket {
int GetPeerAddress(IPEndPoint* address) const override;
int GetLocalAddress(IPEndPoint* address) const override;
void UseNonBlockingIO() override;
+ void SetWriteAsyncEnabled(bool enabled) override;
+ void SetMaxPacketSize(size_t max_packet_size) override;
+ bool WriteAsyncEnabled() override;
+ void SetWriteMultiCoreEnabled(bool enabled) override;
+ void SetSendmmsgEnabled(bool enabled) override;
+ void SetWriteBatchingActive(bool active) override;
const NetLogWithSource& NetLog() const override;
// DatagramClientSocket implementation.
@@ -799,6 +833,7 @@ class MockUDPClientSocket : public DatagramClientSocket, public AsyncSocket {
int ConnectUsingDefaultNetwork(const IPEndPoint& address) override;
NetworkChangeNotifier::NetworkHandle GetBoundNetwork() const override;
void ApplySocketTag(const SocketTag& tag) override;
+ void SetMsgConfirm(bool confirm) override {}
// AsyncSocket implementation.
void OnReadComplete(const MockRead& data) override;
@@ -845,6 +880,8 @@ class MockUDPClientSocket : public DatagramClientSocket, public AsyncSocket {
NetLogWithSource net_log_;
+ DatagramBuffers unwritten_buffers_;
+
SocketTag tag_;
bool data_transferred_ = false;
bool tagged_before_data_transferred_ = true;
@@ -1047,30 +1084,19 @@ class MockSOCKSClientSocketPool : public SOCKSClientSocketPool {
DISALLOW_COPY_AND_ASSIGN(MockSOCKSClientSocketPool);
};
-// Convenience class to temporarily set the WebSocketEndpointLockManager unlock
-// delay to zero for testing purposes. Automatically restores the original value
-// when destroyed.
-class ScopedWebSocketEndpointZeroUnlockDelay {
- public:
- ScopedWebSocketEndpointZeroUnlockDelay();
- ~ScopedWebSocketEndpointZeroUnlockDelay();
-
- private:
- base::TimeDelta old_delay_;
-};
-
// WrappedStreamSocket is a base class that wraps an existing StreamSocket,
// forwarding the Socket and StreamSocket interfaces to the underlying
// transport.
// This is to provide a common base class for subclasses to override specific
// StreamSocket methods for testing, while still communicating with a 'real'
// StreamSocket.
-class WrappedStreamSocket : public StreamSocket {
+class WrappedStreamSocket : public TransportClientSocket {
public:
explicit WrappedStreamSocket(std::unique_ptr<StreamSocket> transport);
~WrappedStreamSocket() override;
// StreamSocket implementation:
+ int Bind(const net::IPEndPoint& local_addr) override;
int Connect(const CompletionCallback& callback) override;
void Disconnect() override;
bool IsConnected() const override;
@@ -1144,10 +1170,9 @@ class MockTaggingClientSocketFactory : public MockClientSocketFactory {
// ClientSocketFactory implementation.
std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
NetLog* net_log,
const NetLogSource& source) override;
- std::unique_ptr<StreamSocket> CreateTransportClientSocket(
+ std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
const AddressList& addresses,
std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
NetLog* net_log,
diff --git a/chromium/net/socket/ssl_client_socket.cc b/chromium/net/socket/ssl_client_socket.cc
index a4d8742bc68..3fe46eb84fe 100644
--- a/chromium/net/socket/ssl_client_socket.cc
+++ b/chromium/net/socket/ssl_client_socket.cc
@@ -36,10 +36,6 @@ bool SSLClientSocket::IgnoreCertError(int error, int load_flags) {
IsCertificateError(error);
}
-SSLErrorDetails SSLClientSocket::GetConnectErrorDetails() const {
- return SSLErrorDetails::kOther;
-}
-
// static
std::vector<uint8_t> SSLClientSocket::SerializeNextProtos(
const NextProtoVector& next_protos) {
diff --git a/chromium/net/socket/ssl_client_socket.h b/chromium/net/socket/ssl_client_socket.h
index b173c769dff..8835ded7c2e 100644
--- a/chromium/net/socket/ssl_client_socket.h
+++ b/chromium/net/socket/ssl_client_socket.h
@@ -65,32 +65,6 @@ struct SSLClientSocketContext {
std::string ssl_session_cache_shard;
};
-// Details on a failed operation. This enum is used to diagnose causes of TLS
-// version interference by buggy middleboxes. The values are histogramed so they
-// must not be changed.
-enum class SSLErrorDetails {
- kOther = 0,
- // The failure was due to ERR_CONNECTION_CLOSED. BlueCoat has a bug with this
- // failure mode. https://crbug.com/694593.
- kConnectionClosed = 1,
- // The failure was due to ERR_CONNECTION_RESET.
- kConnectionReset = 2,
- // The failure was due to receiving an access_denied alert. Fortinet has a
- // bug with this failure mode. https://crbug.com/676969.
- kAccessDeniedAlert = 3,
- // The failure was due to receiving a bad_record_mac alert.
- kBadRecordMACAlert = 4,
- // The failure was due to receiving an unencrypted application_data record
- // during the handshake. Watchguard has a bug with this failure
- // mode. https://crbug.com/733223.
- kApplicationDataInsteadOfHandshake = 5,
- // The failure was due to failing to negotiate a version or cipher suite.
- kVersionOrCipherMismatch = 6,
- // The failure was due to some other protocol error.
- kProtocolError = 7,
- kLastValue = kProtocolError,
-};
-
// A client socket that uses SSL as the transport layer.
//
// NOTE: The SSL handshake occurs within the Connect method after a TCP
@@ -139,10 +113,6 @@ class NET_EXPORT SSLClientSocket : public SSLSocket {
// establishing the connection (or NULL if no channel ID was used).
virtual crypto::ECPrivateKey* GetChannelIDKey() const = 0;
- // Returns details for a failed Connect() operation. This method is used to
- // track causes of TLS version interference by buggy middleboxes.
- virtual SSLErrorDetails GetConnectErrorDetails() const;
-
protected:
void set_signed_cert_timestamps_received(
bool signed_cert_timestamps_received) {
@@ -162,9 +132,9 @@ class NET_EXPORT SSLClientSocket : public SSLSocket {
FRIEND_TEST_ALL_PREFIXES(SSLClientSocket, SerializeNextProtos);
// For signed_cert_timestamps_received_ and stapled_ocsp_response_received_.
FRIEND_TEST_ALL_PREFIXES(SSLClientSocketTest,
- ConnectSignedCertTimestampsEnabledTLSExtension);
+ ConnectSignedCertTimestampsTLSExtension);
FRIEND_TEST_ALL_PREFIXES(SSLClientSocketTest,
- ConnectSignedCertTimestampsEnabledOCSP);
+ ConnectSignedCertTimestampsEnablesOCSP);
FRIEND_TEST_ALL_PREFIXES(SSLClientSocketTest,
ConnectSignedCertTimestampsDisabled);
FRIEND_TEST_ALL_PREFIXES(SSLClientSocketTest,
diff --git a/chromium/net/socket/ssl_client_socket_impl.cc b/chromium/net/socket/ssl_client_socket_impl.cc
index 550267a7569..93233a753fe 100644
--- a/chromium/net/socket/ssl_client_socket_impl.cc
+++ b/chromium/net/socket/ssl_client_socket_impl.cc
@@ -25,7 +25,6 @@
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
-#include "base/threading/thread_local.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
#include "base/values.h"
@@ -66,10 +65,6 @@
#include "net/ssl/ssl_key_logger.h"
#endif
-#if defined(USE_NSS_CERTS)
-#include "net/cert_net/nss_ocsp.h"
-#endif
-
namespace net {
namespace {
@@ -459,7 +454,6 @@ SSLClientSocketImpl::SSLClientSocketImpl(
policy_enforcer_(context.ct_policy_enforcer),
pkp_bypassed_(false),
is_fatal_cert_error_(false),
- connect_error_details_(SSLErrorDetails::kOther),
net_log_(transport_->socket()->NetLog()),
weak_factory_(this) {
CHECK(cert_verifier_);
@@ -491,8 +485,7 @@ void SSLClientSocketImpl::GetSSLCertRequestInfo(
cert_request_info->cert_authorities.clear();
const STACK_OF(CRYPTO_BUFFER)* authorities =
SSL_get0_server_requested_CAs(ssl_.get());
- for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(authorities); i++) {
- const CRYPTO_BUFFER* ca_name = sk_CRYPTO_BUFFER_value(authorities, i);
+ for (const CRYPTO_BUFFER* ca_name : authorities) {
cert_request_info->cert_authorities.push_back(
std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(ca_name)),
CRYPTO_BUFFER_len(ca_name)));
@@ -549,10 +542,6 @@ crypto::ECPrivateKey* SSLClientSocketImpl::GetChannelIDKey() const {
return channel_id_key_.get();
}
-SSLErrorDetails SSLClientSocketImpl::GetConnectErrorDetails() const {
- return connect_error_details_;
-}
-
int SSLClientSocketImpl::ExportKeyingMaterial(const base::StringPiece& label,
bool has_context,
const base::StringPiece& context,
@@ -720,6 +709,7 @@ bool SSLClientSocketImpl::GetSSLInfo(SSLInfo* ssl_info) {
SSL_is_token_binding_negotiated(ssl_.get());
ssl_info->token_binding_key_param = static_cast<net::TokenBindingParam>(
SSL_get_negotiated_token_binding_param(ssl_.get()));
+ ssl_info->dummy_pq_padding_received = SSL_dummy_pq_padding_used(ssl_.get());
ssl_info->pinning_failure_log = pinning_failure_log_;
ssl_info->ocsp_result = server_cert_verify_result_.ocsp_result;
ssl_info->is_fatal_cert_error = is_fatal_cert_error_;
@@ -758,8 +748,7 @@ void SSLClientSocketImpl::DumpMemoryStats(SocketMemoryStats* stats) const {
const STACK_OF(CRYPTO_BUFFER)* server_cert_chain =
SSL_get0_peer_certificates(ssl_.get());
if (server_cert_chain) {
- for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(server_cert_chain); ++i) {
- const CRYPTO_BUFFER* cert = sk_CRYPTO_BUFFER_value(server_cert_chain, i);
+ for (const CRYPTO_BUFFER* cert : server_cert_chain) {
stats->cert_size += CRYPTO_BUFFER_len(cert);
}
stats->cert_count = sk_CRYPTO_BUFFER_num(server_cert_chain);
@@ -847,14 +836,6 @@ void SSLClientSocketImpl::OnWriteReady() {
int SSLClientSocketImpl::Init() {
DCHECK(!ssl_);
-#if defined(USE_NSS_CERTS)
- if (ssl_config_.cert_io_enabled) {
- // TODO(davidben): Move this out of SSLClientSocket. See
- // https://crbug.com/539520.
- EnsureNSSHttpIOInit();
- }
-#endif
-
SSLContext* context = SSLContext::GetInstance();
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
@@ -975,10 +956,8 @@ int SSLClientSocketImpl::Init() {
wire_protos.size());
}
- if (ssl_config_.signed_cert_timestamps_enabled) {
- SSL_enable_signed_cert_timestamps(ssl_.get());
- SSL_enable_ocsp_stapling(ssl_.get());
- }
+ SSL_enable_signed_cert_timestamps(ssl_.get());
+ SSL_enable_ocsp_stapling(ssl_.get());
if (cert_verifier_->SupportsOCSPStapling())
SSL_enable_ocsp_stapling(ssl_.get());
@@ -1012,29 +991,10 @@ void SSLClientSocketImpl::DoWriteCallback(int rv) {
base::ResetAndReturn(&user_write_callback_).Run(rv);
}
-// TODO(cbentzel): Remove including "base/threading/thread_local.h" and
-// g_first_run_completed once crbug.com/424386 is fixed.
-base::LazyInstance<base::ThreadLocalBoolean>::Leaky g_first_run_completed =
- LAZY_INSTANCE_INITIALIZER;
-
int SSLClientSocketImpl::DoHandshake() {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
- int rv;
-
- // TODO(cbentzel): Leave only 1 call to SSL_do_handshake once crbug.com/424386
- // is fixed.
- if (ssl_config_.send_client_cert && ssl_config_.client_cert.get()) {
- rv = SSL_do_handshake(ssl_.get());
- } else {
- if (g_first_run_completed.Get().Get()) {
- rv = SSL_do_handshake(ssl_.get());
- } else {
- g_first_run_completed.Get().Set(true);
- rv = SSL_do_handshake(ssl_.get());
- }
- }
-
+ int rv = SSL_do_handshake(ssl_.get());
int net_error = OK;
if (rv <= 0) {
int ssl_error = SSL_get_error(ssl_.get(), rv);
@@ -1063,38 +1023,6 @@ int SSLClientSocketImpl::DoHandshake() {
return ERR_IO_PENDING;
}
- switch (net_error) {
- case ERR_CONNECTION_CLOSED:
- connect_error_details_ = SSLErrorDetails::kConnectionClosed;
- break;
- case ERR_CONNECTION_RESET:
- connect_error_details_ = SSLErrorDetails::kConnectionReset;
- break;
- case ERR_SSL_PROTOCOL_ERROR: {
- int lib = ERR_GET_LIB(error_info.error_code);
- int reason = ERR_GET_REASON(error_info.error_code);
- if (lib == ERR_LIB_SSL && reason == SSL_R_TLSV1_ALERT_ACCESS_DENIED) {
- connect_error_details_ = SSLErrorDetails::kAccessDeniedAlert;
- } else if (lib == ERR_LIB_SSL &&
- reason == SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE) {
- connect_error_details_ =
- SSLErrorDetails::kApplicationDataInsteadOfHandshake;
- } else {
- connect_error_details_ = SSLErrorDetails::kProtocolError;
- }
- break;
- }
- case ERR_SSL_BAD_RECORD_MAC_ALERT:
- connect_error_details_ = SSLErrorDetails::kBadRecordMACAlert;
- break;
- case ERR_SSL_VERSION_OR_CIPHER_MISMATCH:
- connect_error_details_ = SSLErrorDetails::kVersionOrCipherMismatch;
- break;
- default:
- connect_error_details_ = SSLErrorDetails::kOther;
- break;
- }
-
LOG(ERROR) << "handshake failed; returned " << rv << ", SSL error code "
<< ssl_error << ", net_error " << net_error;
net_log_.AddEvent(
diff --git a/chromium/net/socket/ssl_client_socket_impl.h b/chromium/net/socket/ssl_client_socket_impl.h
index 12ccd437ecc..8e084e9e642 100644
--- a/chromium/net/socket/ssl_client_socket_impl.h
+++ b/chromium/net/socket/ssl_client_socket_impl.h
@@ -89,7 +89,6 @@ class SSLClientSocketImpl : public SSLClientSocket,
TokenBindingType tb_type,
std::vector<uint8_t>* out) override;
crypto::ECPrivateKey* GetChannelIDKey() const override;
- SSLErrorDetails GetConnectErrorDetails() const override;
// SSLSocket implementation.
int ExportKeyingMaterial(const base::StringPiece& label,
@@ -350,8 +349,6 @@ class SSLClientSocketImpl : public SSLClientSocket,
// and false otherwise.
bool is_fatal_cert_error_;
- SSLErrorDetails connect_error_details_;
-
NetLogWithSource net_log_;
base::WeakPtrFactory<SSLClientSocketImpl> weak_factory_;
diff --git a/chromium/net/socket/ssl_client_socket_pool.cc b/chromium/net/socket/ssl_client_socket_pool.cc
index a1bfb5d5b7d..2e6b009e304 100644
--- a/chromium/net/socket/ssl_client_socket_pool.cc
+++ b/chromium/net/socket/ssl_client_socket_pool.cc
@@ -133,10 +133,7 @@ SSLConnectJob::SSLConnectJob(const std::string& group_name,
? "pm/" + context.ssl_session_cache_shard
: context.ssl_session_cache_shard))),
callback_(
- base::Bind(&SSLConnectJob::OnIOComplete, base::Unretained(this))),
- version_interference_probe_(false),
- version_interference_error_(OK),
- version_interference_details_(SSLErrorDetails::kOther) {}
+ base::Bind(&SSLConnectJob::OnIOComplete, base::Unretained(this))) {}
SSLConnectJob::~SSLConnectJob() = default;
@@ -166,7 +163,7 @@ void SSLConnectJob::GetAdditionalErrorState(ClientSocketHandle* handle) {
// problem. See DoTunnelConnectComplete.
if (error_response_info_.headers.get()) {
handle->set_pending_http_proxy_connection(
- transport_socket_handle_.release());
+ std::move(transport_socket_handle_));
}
handle->set_ssl_error_response_info(error_response_info_);
if (!connect_timing_.ssl_start.is_null())
@@ -325,22 +322,13 @@ int SSLConnectJob::DoSSLConnect() {
connect_timing_.ssl_start = base::TimeTicks::Now();
- SSLConfig ssl_config = params_->ssl_config();
- if (version_interference_probe_) {
- DCHECK_EQ(SSL_PROTOCOL_VERSION_TLS1_3, ssl_config.version_max);
- ssl_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
- ssl_config.version_interference_probe = true;
- }
ssl_socket_ = client_socket_factory_->CreateSSLClientSocket(
- std::move(transport_socket_handle_), params_->host_and_port(), ssl_config,
- context_);
+ std::move(transport_socket_handle_), params_->host_and_port(),
+ params_->ssl_config(), context_);
return ssl_socket_->Connect(callback_);
}
int SSLConnectJob::DoSSLConnectComplete(int result) {
- // Version interference probes should not result in success.
- DCHECK(!version_interference_probe_ || result != OK);
-
connect_timing_.ssl_end = base::TimeTicks::Now();
if (result != OK && !server_address_.address().empty()) {
@@ -348,38 +336,7 @@ int SSLConnectJob::DoSSLConnectComplete(int result) {
server_address_ = IPEndPoint();
}
- // Perform a TLS 1.3 version interference probe on various connection
- // errors. The retry will never produce a successful connection but may map
- // errors to ERR_SSL_VERSION_INTERFERENCE, which signals a probable
- // version-interfering middlebox.
- if (params_->ssl_config().version_max == SSL_PROTOCOL_VERSION_TLS1_3 &&
- !version_interference_probe_) {
- if (result == ERR_CONNECTION_CLOSED || result == ERR_SSL_PROTOCOL_ERROR ||
- result == ERR_SSL_VERSION_OR_CIPHER_MISMATCH ||
- result == ERR_CONNECTION_RESET ||
- result == ERR_SSL_BAD_RECORD_MAC_ALERT) {
- // Report the error code for each time a version interference probe is
- // triggered.
- base::UmaHistogramSparse("Net.SSLVersionInterferenceProbeTrigger",
- std::abs(result));
- net_log().AddEventWithNetErrorCode(
- NetLogEventType::SSL_VERSION_INTERFERENCE_PROBE, result);
- SSLErrorDetails details = ssl_socket_->GetConnectErrorDetails();
-
- ResetStateForRetry();
- version_interference_probe_ = true;
- version_interference_error_ = result;
- version_interference_details_ = details;
- next_state_ = GetInitialState(params_->GetConnectionType());
- return OK;
- }
- }
-
const std::string& host = params_->host_and_port().host();
- bool is_google =
- host == "google.com" ||
- (host.size() > 11 && host.rfind(".google.com") == host.size() - 11);
-
bool tls13_supported = IsTLS13ExperimentHost(host);
if (result == OK ||
@@ -424,60 +381,28 @@ int SSLConnectJob::DoSSLConnectComplete(int result) {
100);
}
- if (is_google) {
- UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Google2",
+ if (tls13_supported) {
+ UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_TLS13Experiment",
connect_duration,
base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromMinutes(1),
- 100);
- if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_RESUME) {
- UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Google_"
- "Resume_Handshake",
- connect_duration,
- base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromMinutes(1),
- 100);
- } else if (ssl_info.handshake_type == SSLInfo::HANDSHAKE_FULL) {
- UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_Google_"
- "Full_Handshake",
- connect_duration,
- base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromMinutes(1),
- 100);
- }
+ base::TimeDelta::FromMinutes(1), 100);
}
- if (tls13_supported) {
- UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_TLS13Experiment",
+ if (ssl_info.dummy_pq_padding_received) {
+ UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency_PQPadding",
connect_duration,
base::TimeDelta::FromMilliseconds(1),
base::TimeDelta::FromMinutes(1), 100);
}
}
- base::UmaHistogramSparse("Net.SSL_Connection_Error", std::abs(result));
-
- if (is_google) {
- base::UmaHistogramSparse("Net.SSL_Connection_Error_Google",
- std::abs(result));
- }
-
- if (tls13_supported) {
- base::UmaHistogramSparse("Net.SSL_Connection_Error_TLS13Experiment",
- std::abs(result));
- }
-
- if (result == ERR_SSL_VERSION_INTERFERENCE) {
- // Record the error code version interference was detected at.
- DCHECK(version_interference_probe_);
- DCHECK_NE(OK, version_interference_error_);
- base::UmaHistogramSparse("Net.SSLVersionInterferenceError",
- std::abs(version_interference_error_));
+ // Don't double-count the version interference probes.
+ if (!params_->ssl_config().version_interference_probe) {
+ base::UmaHistogramSparse("Net.SSL_Connection_Error", std::abs(result));
if (tls13_supported) {
- UMA_HISTOGRAM_ENUMERATION(
- "Net.SSLVersionInterferenceDetails_TLS13Experiment",
- version_interference_details_, SSLErrorDetails::kLastValue);
+ base::UmaHistogramSparse("Net.SSL_Connection_Error_TLS13Experiment",
+ std::abs(result));
}
}
@@ -511,13 +436,6 @@ int SSLConnectJob::ConnectInternal() {
return DoLoop(OK);
}
-void SSLConnectJob::ResetStateForRetry() {
- transport_socket_handle_.reset();
- ssl_socket_.reset();
- error_response_info_ = HttpResponseInfo();
- server_address_ = IPEndPoint();
-}
-
SSLClientSocketPool::SSLConnectJobFactory::SSLConnectJobFactory(
TransportClientSocketPool* transport_pool,
SOCKSClientSocketPool* socks_pool,
diff --git a/chromium/net/socket/ssl_client_socket_pool.h b/chromium/net/socket/ssl_client_socket_pool.h
index 1ec3d32843b..777b6b741d5 100644
--- a/chromium/net/socket/ssl_client_socket_pool.h
+++ b/chromium/net/socket/ssl_client_socket_pool.h
@@ -149,8 +149,6 @@ class SSLConnectJob : public ConnectJob {
// Otherwise, it returns a net error code.
int ConnectInternal() override;
- void ResetStateForRetry();
-
scoped_refptr<SSLSocketParams> params_;
TransportClientSocketPool* const transport_pool_;
SOCKSClientSocketPool* const socks_pool_;
@@ -172,16 +170,6 @@ class SSLConnectJob : public ConnectJob {
// through an HTTPS CONNECT request or a SOCKS proxy).
IPEndPoint server_address_;
- bool version_interference_probe_;
-
- // The error which triggered a TLS 1.3 version interference probe, or OK if
- // none was triggered.
- int version_interference_error_;
-
- // Details for the error which triggered a TLS 1.3 interference probe, or
- // kOther if not applicable.
- SSLErrorDetails version_interference_details_;
-
DISALLOW_COPY_AND_ASSIGN(SSLConnectJob);
};
diff --git a/chromium/net/socket/ssl_client_socket_pool_unittest.cc b/chromium/net/socket/ssl_client_socket_pool_unittest.cc
index db01fe2ba6c..b29f728e9cf 100644
--- a/chromium/net/socket/ssl_client_socket_pool_unittest.cc
+++ b/chromium/net/socket/ssl_client_socket_pool_unittest.cc
@@ -27,7 +27,7 @@
#include "net/http/transport_security_state.h"
#include "net/log/net_log_source.h"
#include "net/log/net_log_with_source.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/next_proto.h"
#include "net/socket/socket_tag.h"
@@ -130,7 +130,8 @@ class SSLClientSocketPoolTest : public testing::Test {
session_->spdy_session_pool(),
session_->quic_stream_factory(),
/*is_trusted_proxy=*/false,
- /*tunnel=*/true)),
+ /*tunnel=*/true,
+ TRAFFIC_ANNOTATION_FOR_TESTS)),
http_proxy_socket_pool_(kMaxSockets,
kMaxSocketsPerGroup,
&transport_socket_pool_,
@@ -734,8 +735,8 @@ TEST_F(SSLClientSocketPoolTest, NeedProxyAuth) {
EXPECT_FALSE(handle.is_ssl_error());
const HttpResponseInfo& tunnel_info = handle.ssl_error_response_info();
EXPECT_EQ(tunnel_info.headers->response_code(), 407);
- std::unique_ptr<ClientSocketHandle> tunnel_handle(
- handle.release_pending_http_proxy_connection());
+ std::unique_ptr<ClientSocketHandle> tunnel_handle =
+ handle.release_pending_http_proxy_connection();
EXPECT_TRUE(tunnel_handle->socket());
EXPECT_FALSE(tunnel_handle->socket()->IsConnected());
}
diff --git a/chromium/net/socket/ssl_client_socket_unittest.cc b/chromium/net/socket/ssl_client_socket_unittest.cc
index 7c4108debcf..d423a295406 100644
--- a/chromium/net/socket/ssl_client_socket_unittest.cc
+++ b/chromium/net/socket/ssl_client_socket_unittest.cc
@@ -804,8 +804,10 @@ class MockCTPolicyEnforcer : public CTPolicyEnforcer {
class MockRequireCTDelegate : public TransportSecurityState::RequireCTDelegate {
public:
- MOCK_METHOD1(IsCTRequiredForHost,
- CTRequirementLevel(const std::string& host));
+ MOCK_METHOD3(IsCTRequiredForHost,
+ CTRequirementLevel(const std::string& host,
+ const X509Certificate* chain,
+ const HashValueVector& hashes));
};
class SSLClientSocketTest : public PlatformTest {
@@ -2448,7 +2450,9 @@ TEST_F(SSLClientSocketCertRequestInfoTest, CertKeyTypes) {
EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, request_info->cert_key_types[1]);
}
-TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledTLSExtension) {
+// Tests that the Certificate Transparency (RFC 6962) TLS extension is
+// supported.
+TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsTLSExtension) {
// Encoding of SCT List containing 'test'.
base::StringPiece sct_ext("\x00\x06\x00\x04test", 8);
@@ -2457,7 +2461,6 @@ TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledTLSExtension) {
ASSERT_TRUE(StartTestServer(ssl_options));
SSLConfig ssl_config;
- ssl_config.signed_cert_timestamps_enabled = true;
MockCTVerifier ct_verifier;
SetCTVerifier(&ct_verifier);
@@ -2610,8 +2613,9 @@ TEST_F(SSLClientSocketTest, CTCompliantEVHistogram) {
static_cast<int>(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS), 1);
}
-// Test that enabling Signed Certificate Timestamps enables OCSP stapling.
-TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledOCSP) {
+// Tests that OCSP stapling is requested, as per Certificate Transparency (RFC
+// 6962).
+TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnablesOCSP) {
SpawnedTestServer::SSLOptions ssl_options;
ssl_options.staple_ocsp_response = true;
// The test server currently only knows how to generate OCSP responses
@@ -2621,10 +2625,6 @@ TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledOCSP) {
ASSERT_TRUE(StartTestServer(ssl_options));
SSLConfig ssl_config;
- // Enabling Signed Cert Timestamps ensures we request OCSP stapling for
- // Certificate Transparency verification regardless of whether the platform
- // is able to process the OCSP status itself.
- ssl_config.signed_cert_timestamps_enabled = true;
int rv;
ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
@@ -2633,22 +2633,6 @@ TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledOCSP) {
EXPECT_TRUE(sock_->stapled_ocsp_response_received_);
}
-TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsDisabled) {
- SpawnedTestServer::SSLOptions ssl_options;
- ssl_options.signed_cert_timestamps_tls_ext = "test";
-
- ASSERT_TRUE(StartTestServer(ssl_options));
-
- SSLConfig ssl_config;
- ssl_config.signed_cert_timestamps_enabled = false;
-
- int rv;
- ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv));
- EXPECT_THAT(rv, IsOk());
-
- EXPECT_FALSE(sock_->signed_cert_timestamps_received_);
-}
-
// Tests that IsConnectedAndIdle and WasEverUsed behave as expected.
TEST_F(SSLClientSocketTest, ReuseStates) {
ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions()));
@@ -3481,12 +3465,12 @@ TEST_F(SSLClientSocketTest, CTIsRequired) {
// Set up CT
MockRequireCTDelegate require_ct_delegate;
transport_security_state_->SetRequireCTDelegate(&require_ct_delegate);
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_))
+ EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
.WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
CTRequirementLevel::NOT_REQUIRED));
EXPECT_CALL(
require_ct_delegate,
- IsCTRequiredForHost(spawned_test_server()->host_port_pair().host()))
+ IsCTRequiredForHost(spawned_test_server()->host_port_pair().host(), _, _))
.WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
CTRequirementLevel::REQUIRED));
EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(server_cert.get(), _, _))
@@ -3796,9 +3780,13 @@ TEST_F(SSLClientSocketTest, CTRequiredHistogramNonCompliantLocalRoot) {
cert_verifier_->AddResultForCert(server_cert.get(), verify_result, OK);
// Set up the CT requirement and failure to comply.
+ base::ScopedClosureRunner cleanup(base::BindOnce(
+ &TransportSecurityState::SetShouldRequireCTForTesting, nullptr));
+ bool require_ct = true;
+ TransportSecurityState::SetShouldRequireCTForTesting(&require_ct);
MockRequireCTDelegate require_ct_delegate;
transport_security_state_->SetRequireCTDelegate(&require_ct_delegate);
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_))
+ EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
.WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
CTRequirementLevel::REQUIRED));
EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(server_cert.get(), _, _))
@@ -3938,12 +3926,12 @@ TEST_F(SSLClientSocketTest, PKPMoreImportantThanCT) {
// Set up CT.
MockRequireCTDelegate require_ct_delegate;
transport_security_state_->SetRequireCTDelegate(&require_ct_delegate);
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_))
+ EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
.WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
CTRequirementLevel::NOT_REQUIRED));
EXPECT_CALL(
require_ct_delegate,
- IsCTRequiredForHost(spawned_test_server()->host_port_pair().host()))
+ IsCTRequiredForHost(spawned_test_server()->host_port_pair().host(), _, _))
.WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
CTRequirementLevel::REQUIRED));
EXPECT_CALL(*ct_policy_enforcer_, CheckCompliance(server_cert.get(), _, _))
diff --git a/chromium/net/socket/tcp_client_socket.h b/chromium/net/socket/tcp_client_socket.h
index cda599b52a4..f4861d01ce1 100644
--- a/chromium/net/socket/tcp_client_socket.h
+++ b/chromium/net/socket/tcp_client_socket.h
@@ -17,6 +17,7 @@
#include "net/socket/connection_attempts.h"
#include "net/socket/stream_socket.h"
#include "net/socket/tcp_socket.h"
+#include "net/socket/transport_client_socket.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
@@ -26,7 +27,7 @@ struct NetLogSource;
class SocketPerformanceWatcher;
// A client socket that uses TCP as the transport layer.
-class NET_EXPORT TCPClientSocket : public StreamSocket {
+class NET_EXPORT TCPClientSocket : public TransportClientSocket {
public:
// The IP address(es) and port number to connect to. The TCP socket will try
// each IP address in the list until it succeeds in establishing a
@@ -44,10 +45,8 @@ class NET_EXPORT TCPClientSocket : public StreamSocket {
~TCPClientSocket() override;
- // Binds the socket to a local IP address and port.
- int Bind(const IPEndPoint& address);
-
- // StreamSocket implementation.
+ // TransportClientSocket implementation.
+ int Bind(const IPEndPoint& address) override;
int Connect(const CompletionCallback& callback) override;
void Disconnect() override;
bool IsConnected() const override;
diff --git a/chromium/net/socket/tcp_socket_unittest.cc b/chromium/net/socket/tcp_socket_unittest.cc
index c9d4c716455..eadda3f8e14 100644
--- a/chromium/net/socket/tcp_socket_unittest.cc
+++ b/chromium/net/socket/tcp_socket_unittest.cc
@@ -38,6 +38,24 @@ namespace net {
namespace {
+// IOBuffer with the ability to invoke a callback when destroyed. Useful for
+// checking for leaks.
+class IOBufferWithDestructionCallback : public IOBufferWithSize {
+ public:
+ explicit IOBufferWithDestructionCallback(base::OnceClosure on_destroy_closure)
+ : IOBufferWithSize(1024),
+ on_destroy_closure_(std::move(on_destroy_closure)) {
+ DCHECK(on_destroy_closure_);
+ }
+
+ protected:
+ ~IOBufferWithDestructionCallback() override {
+ std::move(on_destroy_closure_).Run();
+ }
+
+ base::OnceClosure on_destroy_closure_;
+};
+
class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
public:
explicit TestSocketPerformanceWatcher(bool should_notify_updated_rtt)
@@ -419,6 +437,96 @@ TEST_F(TCPSocketTest, ReadWrite) {
ASSERT_EQ(message, received_message);
}
+// Destroy a TCPSocket while there's a pending read, and make sure the read
+// IOBuffer that the socket was holding on to is destroyed.
+// See https://crbug.com/804868.
+TEST_F(TCPSocketTest, DestroyWithPendingRead) {
+ ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
+
+ // Create a connected socket.
+
+ TestCompletionCallback connect_callback;
+ std::unique_ptr<TCPSocket> connecting_socket =
+ std::make_unique<TCPSocket>(nullptr, nullptr, NetLogSource());
+ int result = connecting_socket->Open(ADDRESS_FAMILY_IPV4);
+ ASSERT_THAT(result, IsOk());
+ int connect_result =
+ connecting_socket->Connect(local_address_, connect_callback.callback());
+
+ TestCompletionCallback accept_callback;
+ std::unique_ptr<TCPSocket> accepted_socket;
+ IPEndPoint accepted_address;
+ result = socket_.Accept(&accepted_socket, &accepted_address,
+ accept_callback.callback());
+ ASSERT_THAT(accept_callback.GetResult(result), IsOk());
+ ASSERT_TRUE(accepted_socket.get());
+ ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk());
+
+ // Try to read from the socket, but never write anything to the other end.
+ base::RunLoop run_loop;
+ scoped_refptr<IOBufferWithDestructionCallback> read_buffer(
+ base::MakeRefCounted<IOBufferWithDestructionCallback>(
+ run_loop.QuitClosure()));
+ TestCompletionCallback read_callback;
+ EXPECT_EQ(ERR_IO_PENDING,
+ connecting_socket->Read(read_buffer.get(), read_buffer->size(),
+ read_callback.callback()));
+
+ // Release the handle to the read buffer and destroy the socket. Make sure the
+ // read buffer is destroyed.
+ read_buffer = nullptr;
+ connecting_socket.reset();
+ run_loop.Run();
+}
+
+// Destroy a TCPSocket while there's a pending write, and make sure the write
+// IOBuffer that the socket was holding on to is destroyed.
+TEST_F(TCPSocketTest, DestroyWithPendingWrite) {
+ ASSERT_NO_FATAL_FAILURE(SetUpListenIPv4());
+
+ // Create a connected socket.
+
+ TestCompletionCallback connect_callback;
+ std::unique_ptr<TCPSocket> connecting_socket =
+ std::make_unique<TCPSocket>(nullptr, nullptr, NetLogSource());
+ int result = connecting_socket->Open(ADDRESS_FAMILY_IPV4);
+ ASSERT_THAT(result, IsOk());
+ int connect_result =
+ connecting_socket->Connect(local_address_, connect_callback.callback());
+
+ TestCompletionCallback accept_callback;
+ std::unique_ptr<TCPSocket> accepted_socket;
+ IPEndPoint accepted_address;
+ result = socket_.Accept(&accepted_socket, &accepted_address,
+ accept_callback.callback());
+ ASSERT_THAT(accept_callback.GetResult(result), IsOk());
+ ASSERT_TRUE(accepted_socket.get());
+ ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk());
+
+ // Repeatedly write to the socket until an operation does not complete
+ // synchronously.
+ base::RunLoop run_loop;
+ scoped_refptr<IOBufferWithDestructionCallback> write_buffer(
+ base::MakeRefCounted<IOBufferWithDestructionCallback>(
+ run_loop.QuitClosure()));
+ memset(write_buffer->data(), '1', write_buffer->size());
+ TestCompletionCallback write_callback;
+ while (true) {
+ int result = connecting_socket->Write(
+ write_buffer.get(), write_buffer->size(), write_callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ if (result == ERR_IO_PENDING)
+ break;
+ ASSERT_LT(0, result);
+ }
+
+ // Release the handle to the read buffer and destroy the socket. Make sure the
+ // write buffer is destroyed.
+ write_buffer = nullptr;
+ connecting_socket.reset();
+ run_loop.Run();
+}
+
// These tests require kernel support for tcp_info struct, and so they are
// enabled only on certain platforms.
#if defined(TCP_INFO) || defined(OS_LINUX)
diff --git a/chromium/net/socket/tcp_socket_win.cc b/chromium/net/socket/tcp_socket_win.cc
index 4ecab0b6061..f31e5bd71cd 100644
--- a/chromium/net/socket/tcp_socket_win.cc
+++ b/chromium/net/socket/tcp_socket_win.cc
@@ -112,12 +112,15 @@ class TCPSocketWin::Core : public base::RefCounted<Core> {
void WatchForWrite();
// The TCPSocketWin is going away.
- void Detach() { socket_ = NULL; }
+ void Detach();
- // The separate OVERLAPPED variables for asynchronous operation.
- // |read_overlapped_| is used for both Connect() and Read().
- // |write_overlapped_| is only used for Write();
- OVERLAPPED read_overlapped_;
+ // Event handle for monitoring connect and read events through WSAEventSelect.
+ HANDLE read_event_;
+
+ // OVERLAPPED variable for overlapped writes.
+ // TODO(mmenke): Can writes be switched to WSAEventSelect as well? That would
+ // allow removing this class. The only concern is whether that would have a
+ // negative perf impact.
OVERLAPPED write_overlapped_;
// The buffers used in Read() and Write().
@@ -174,35 +177,32 @@ class TCPSocketWin::Core : public base::RefCounted<Core> {
};
TCPSocketWin::Core::Core(TCPSocketWin* socket)
- : read_buffer_length_(0),
+ : read_event_(WSACreateEvent()),
+ read_buffer_length_(0),
write_buffer_length_(0),
non_blocking_reads_initialized_(false),
socket_(socket),
reader_(this),
writer_(this) {
- memset(&read_overlapped_, 0, sizeof(read_overlapped_));
memset(&write_overlapped_, 0, sizeof(write_overlapped_));
-
- read_overlapped_.hEvent = WSACreateEvent();
write_overlapped_.hEvent = WSACreateEvent();
}
TCPSocketWin::Core::~Core() {
- // Make sure the message loop is not watching this object anymore.
- read_watcher_.StopWatching();
- write_watcher_.StopWatching();
+ // Detach should already have been called.
+ DCHECK(!socket_);
- WSACloseEvent(read_overlapped_.hEvent);
- memset(&read_overlapped_, 0xaf, sizeof(read_overlapped_));
+ // Stop the write watcher. The read watcher should already have been stopped
+ // in Detach().
+ write_watcher_.StopWatching();
WSACloseEvent(write_overlapped_.hEvent);
memset(&write_overlapped_, 0xaf, sizeof(write_overlapped_));
}
void TCPSocketWin::Core::WatchForRead() {
- // We grab an extra reference because there is an IO operation in progress.
- // Balanced in ReadDelegate::OnObjectSignaled().
- AddRef();
- read_watcher_.StartWatchingOnce(read_overlapped_.hEvent, &reader_);
+ // Reads use WSAEventSelect, which closesocket() cancels so unlike writes,
+ // there's no need to increment the reference count here.
+ read_watcher_.StartWatchingOnce(read_event_, &reader_);
}
void TCPSocketWin::Core::WatchForWrite() {
@@ -212,16 +212,25 @@ void TCPSocketWin::Core::WatchForWrite() {
write_watcher_.StartWatchingOnce(write_overlapped_.hEvent, &writer_);
}
-void TCPSocketWin::Core::ReadDelegate::OnObjectSignaled(HANDLE object) {
- DCHECK_EQ(object, core_->read_overlapped_.hEvent);
- if (core_->socket_) {
- if (core_->socket_->waiting_connect_)
- core_->socket_->DidCompleteConnect();
- else
- core_->socket_->DidSignalRead();
- }
+void TCPSocketWin::Core::Detach() {
+ // Stop watching the read watcher. A read won't be signalled after the Detach
+ // call, since the socket has been closed, but it's possible the event was
+ // signalled when the socket was closed, but hasn't been handled yet, so need
+ // to stop watching now to avoid trying to handle the event. See
+ // https://crbug.com/831149
+ read_watcher_.StopWatching();
+ WSACloseEvent(read_event_);
- core_->Release();
+ socket_ = nullptr;
+}
+
+void TCPSocketWin::Core::ReadDelegate::OnObjectSignaled(HANDLE object) {
+ DCHECK_EQ(object, core_->read_event_);
+ DCHECK(core_->socket_);
+ if (core_->socket_->waiting_connect_)
+ core_->socket_->DidCompleteConnect();
+ else
+ core_->socket_->DidSignalRead();
}
void TCPSocketWin::Core::WriteDelegate::OnObjectSignaled(
@@ -230,6 +239,7 @@ void TCPSocketWin::Core::WriteDelegate::OnObjectSignaled(
if (core_->socket_)
core_->socket_->DidCompleteWrite();
+ // Matches the AddRef() in WatchForWrite().
core_->Release();
}
@@ -493,7 +503,7 @@ int TCPSocketWin::ReadIfReady(IOBuffer* buf,
DCHECK(read_if_ready_callback_.is_null());
if (!core_->non_blocking_reads_initialized_) {
- WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_READ | FD_CLOSE);
+ WSAEventSelect(socket_, core_->read_event_, FD_READ | FD_CLOSE);
core_->non_blocking_reads_initialized_ = true;
}
int rv = recv(socket_, buf->data(), buf_len, 0);
@@ -672,8 +682,8 @@ void TCPSocketWin::Close() {
if (!accept_callback_.is_null()) {
accept_watcher_.StopWatching();
- accept_socket_ = NULL;
- accept_address_ = NULL;
+ accept_socket_ = nullptr;
+ accept_address_ = nullptr;
accept_callback_.Reset();
}
@@ -683,16 +693,12 @@ void TCPSocketWin::Close() {
}
if (core_.get()) {
- if (waiting_connect_) {
- // We closed the socket, so this notification will never come.
- // From MSDN' WSAEventSelect documentation:
- // "Closing a socket with closesocket also cancels the association and
- // selection of network events specified in WSAEventSelect for the
- // socket".
- core_->Release();
- }
core_->Detach();
- core_ = NULL;
+ core_ = nullptr;
+
+ // |core_| may still exist and own a reference to itself, if there's a
+ // pending write. It has to stay alive until the operation completes, even
+ // when the socket is closed. This is not the case for reads.
}
waiting_connect_ = false;
@@ -808,7 +814,7 @@ int TCPSocketWin::DoConnect() {
// WSAEventSelect sets the socket to non-blocking mode as a side effect.
// Our connect() and recv() calls require that the socket be non-blocking.
- WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT);
+ WSAEventSelect(socket_, core_->read_event_, FD_CONNECT);
SockaddrStorage storage;
if (!peer_address_->ToSockAddr(storage.addr, &storage.addr_len))
@@ -827,7 +833,7 @@ int TCPSocketWin::DoConnect() {
// and we don't know if it's correct.
NOTREACHED();
- if (ResetEventIfSignaled(core_->read_overlapped_.hEvent))
+ if (ResetEventIfSignaled(core_->read_event_))
return OK;
} else {
int os_error = WSAGetLastError();
@@ -912,8 +918,7 @@ void TCPSocketWin::DidCompleteConnect() {
int result;
WSANETWORKEVENTS events;
- int rv =
- WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, &events);
+ int rv = WSAEnumNetworkEvents(socket_, core_->read_event_, &events);
int os_error = WSAGetLastError();
if (rv == SOCKET_ERROR) {
NOTREACHED();
@@ -977,8 +982,7 @@ void TCPSocketWin::DidSignalRead() {
int os_error = 0;
WSANETWORKEVENTS network_events;
- int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent,
- &network_events);
+ int rv = WSAEnumNetworkEvents(socket_, core_->read_event_, &network_events);
os_error = WSAGetLastError();
if (rv == SOCKET_ERROR) {
diff --git a/chromium/net/socket/transport_client_socket.h b/chromium/net/socket/transport_client_socket.h
new file mode 100644
index 00000000000..8f64e92ccd2
--- /dev/null
+++ b/chromium/net/socket/transport_client_socket.h
@@ -0,0 +1,27 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_SOCKET_TRANSPORT_CLIENT_SOCKET_H_
+#define NET_SOCKET_TRANSPORT_CLIENT_SOCKET_H_
+
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_export.h"
+#include "net/socket/stream_socket.h"
+
+namespace net {
+
+// A socket class that extends StreamSocket to provide methods that are relevant
+// to a transport client socket.
+class NET_EXPORT_PRIVATE TransportClientSocket : public StreamSocket {
+ public:
+ ~TransportClientSocket() override {}
+
+ // Binds the socket to a local address, |local_addr|. Returns OK on success,
+ // and a net error code on failure.
+ virtual int Bind(const net::IPEndPoint& local_addr) = 0;
+};
+
+} // namespace net
+
+#endif // NET_SOCKET_TRANSPORT_CLIENT_SOCKET_H_
diff --git a/chromium/net/socket/transport_client_socket_pool_test_util.cc b/chromium/net/socket/transport_client_socket_pool_test_util.cc
index 7f872c6ea18..d8599e96959 100644
--- a/chromium/net/socket/transport_client_socket_pool_test_util.cc
+++ b/chromium/net/socket/transport_client_socket_pool_test_util.cc
@@ -25,6 +25,7 @@
#include "net/socket/client_socket_handle.h"
#include "net/socket/datagram_client_socket.h"
#include "net/socket/ssl_client_socket.h"
+#include "net/socket/transport_client_socket.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -39,14 +40,18 @@ IPAddress ParseIP(const std::string& ip) {
}
// A StreamSocket which connects synchronously and successfully.
-class MockConnectClientSocket : public StreamSocket {
+class MockConnectClientSocket : public TransportClientSocket {
public:
MockConnectClientSocket(const AddressList& addrlist, net::NetLog* net_log)
: connected_(false),
addrlist_(addrlist),
net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)) {}
- // StreamSocket implementation.
+ // TransportClientSocket implementation.
+ int Bind(const net::IPEndPoint& local_addr) override {
+ NOTREACHED();
+ return ERR_FAILED;
+ }
int Connect(const CompletionCallback& callback) override {
connected_ = true;
return OK;
@@ -111,13 +116,18 @@ class MockConnectClientSocket : public StreamSocket {
DISALLOW_COPY_AND_ASSIGN(MockConnectClientSocket);
};
-class MockFailingClientSocket : public StreamSocket {
+class MockFailingClientSocket : public TransportClientSocket {
public:
MockFailingClientSocket(const AddressList& addrlist, net::NetLog* net_log)
: addrlist_(addrlist),
net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::SOCKET)) {}
- // StreamSocket implementation.
+ // TransportClientSocket implementation.
+ int Bind(const net::IPEndPoint& local_addr) override {
+ NOTREACHED();
+ return ERR_FAILED;
+ }
+
int Connect(const CompletionCallback& callback) override {
return ERR_CONNECTION_FAILED;
}
@@ -177,7 +187,7 @@ class MockFailingClientSocket : public StreamSocket {
DISALLOW_COPY_AND_ASSIGN(MockFailingClientSocket);
};
-class MockTriggerableClientSocket : public StreamSocket {
+class MockTriggerableClientSocket : public TransportClientSocket {
public:
// |should_connect| indicates whether the socket should successfully complete
// or fail.
@@ -198,7 +208,7 @@ class MockTriggerableClientSocket : public StreamSocket {
weak_factory_.GetWeakPtr());
}
- static std::unique_ptr<StreamSocket> MakeMockPendingClientSocket(
+ static std::unique_ptr<TransportClientSocket> MakeMockPendingClientSocket(
const AddressList& addrlist,
bool should_connect,
net::NetLog* net_log) {
@@ -209,7 +219,7 @@ class MockTriggerableClientSocket : public StreamSocket {
return std::move(socket);
}
- static std::unique_ptr<StreamSocket> MakeMockDelayedClientSocket(
+ static std::unique_ptr<TransportClientSocket> MakeMockDelayedClientSocket(
const AddressList& addrlist,
bool should_connect,
const base::TimeDelta& delay,
@@ -221,7 +231,7 @@ class MockTriggerableClientSocket : public StreamSocket {
return std::move(socket);
}
- static std::unique_ptr<StreamSocket> MakeMockStalledClientSocket(
+ static std::unique_ptr<TransportClientSocket> MakeMockStalledClientSocket(
const AddressList& addrlist,
net::NetLog* net_log,
bool failing) {
@@ -236,7 +246,12 @@ class MockTriggerableClientSocket : public StreamSocket {
return std::move(socket);
}
- // StreamSocket implementation.
+ // TransportClientSocket implementation.
+ int Bind(const net::IPEndPoint& local_addr) override {
+ NOTREACHED();
+ return ERR_FAILED;
+ }
+
int Connect(const CompletionCallback& callback) override {
DCHECK(callback_.is_null());
callback_ = callback;
@@ -372,14 +387,13 @@ MockTransportClientSocketFactory::~MockTransportClientSocketFactory() = default;
std::unique_ptr<DatagramClientSocket>
MockTransportClientSocketFactory::CreateDatagramClientSocket(
DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
NetLog* net_log,
const NetLogSource& source) {
NOTREACHED();
return std::unique_ptr<DatagramClientSocket>();
}
-std::unique_ptr<StreamSocket>
+std::unique_ptr<TransportClientSocket>
MockTransportClientSocketFactory::CreateTransportClientSocket(
const AddressList& addresses,
std::unique_ptr<SocketPerformanceWatcher> /* socket_performance_watcher */,
@@ -394,11 +408,9 @@ MockTransportClientSocketFactory::CreateTransportClientSocket(
switch (type) {
case MOCK_CLIENT_SOCKET:
- return std::unique_ptr<StreamSocket>(
- new MockConnectClientSocket(addresses, net_log_));
+ return std::make_unique<MockConnectClientSocket>(addresses, net_log_);
case MOCK_FAILING_CLIENT_SOCKET:
- return std::unique_ptr<StreamSocket>(
- new MockFailingClientSocket(addresses, net_log_));
+ return std::make_unique<MockFailingClientSocket>(addresses, net_log_);
case MOCK_PENDING_CLIENT_SOCKET:
return MockTriggerableClientSocket::MakeMockPendingClientSocket(
addresses, true, net_log_);
@@ -431,8 +443,7 @@ MockTransportClientSocketFactory::CreateTransportClientSocket(
}
default:
NOTREACHED();
- return std::unique_ptr<StreamSocket>(
- new MockConnectClientSocket(addresses, net_log_));
+ return std::make_unique<MockConnectClientSocket>(addresses, net_log_);
}
}
diff --git a/chromium/net/socket/transport_client_socket_pool_test_util.h b/chromium/net/socket/transport_client_socket_pool_test_util.h
index e7c9e3eee9d..b935233b791 100644
--- a/chromium/net/socket/transport_client_socket_pool_test_util.h
+++ b/chromium/net/socket/transport_client_socket_pool_test_util.h
@@ -75,11 +75,10 @@ class MockTransportClientSocketFactory : public ClientSocketFactory {
std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
NetLog* net_log,
const NetLogSource& source) override;
- std::unique_ptr<StreamSocket> CreateTransportClientSocket(
+ std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
const AddressList& addresses,
std::unique_ptr<
SocketPerformanceWatcher> /* socket_performance_watcher */,
diff --git a/chromium/net/socket/transport_client_socket_pool_unittest.cc b/chromium/net/socket/transport_client_socket_pool_unittest.cc
index bdd5df5e738..7d844f7ba87 100644
--- a/chromium/net/socket/transport_client_socket_pool_unittest.cc
+++ b/chromium/net/socket/transport_client_socket_pool_unittest.cc
@@ -510,11 +510,7 @@ class RequestSocketCallback : public TestCompletionCallbackBase {
// run through the MessageLoop once to get it completely released.
handle_->socket()->Disconnect();
handle_->Reset();
- {
- base::MessageLoop::ScopedNestableTaskAllower allow(
- base::MessageLoop::current());
- base::RunLoop().RunUntilIdle();
- }
+ base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
within_callback_ = true;
scoped_refptr<TransportSocketParams> dest(new TransportSocketParams(
HostPortPair("www.google.com", 80), false, OnHostResolutionCallback(),
diff --git a/chromium/net/socket/udp_client_socket.cc b/chromium/net/socket/udp_client_socket.cc
index 049a1fcaa38..65790992fd0 100644
--- a/chromium/net/socket/udp_client_socket.cc
+++ b/chromium/net/socket/udp_client_socket.cc
@@ -11,10 +11,9 @@
namespace net {
UDPClientSocket::UDPClientSocket(DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
net::NetLog* net_log,
const net::NetLogSource& source)
- : socket_(bind_type, rand_int_cb, net_log, source),
+ : socket_(bind_type, net_log, source),
network_(NetworkChangeNotifier::kInvalidNetworkHandle) {}
UDPClientSocket::~UDPClientSocket() = default;
@@ -95,6 +94,27 @@ int UDPClientSocket::Write(
return socket_.Write(buf, buf_len, callback, traffic_annotation);
}
+int UDPClientSocket::WriteAsync(
+ const char* buffer,
+ size_t buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
+ DCHECK(WriteAsyncEnabled());
+ return socket_.WriteAsync(buffer, buf_len, callback, traffic_annotation);
+}
+
+int UDPClientSocket::WriteAsync(
+ DatagramBuffers buffers,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
+ DCHECK(WriteAsyncEnabled());
+ return socket_.WriteAsync(std::move(buffers), callback, traffic_annotation);
+}
+
+DatagramBuffers UDPClientSocket::GetUnwrittenBuffers() {
+ return socket_.GetUnwrittenBuffers();
+}
+
void UDPClientSocket::Close() {
socket_.Close();
}
@@ -119,6 +139,10 @@ int UDPClientSocket::SetDoNotFragment() {
return socket_.SetDoNotFragment();
}
+void UDPClientSocket::SetMsgConfirm(bool confirm) {
+ socket_.SetMsgConfirm(confirm);
+}
+
const NetLogWithSource& UDPClientSocket::NetLog() const {
return socket_.NetLog();
}
@@ -129,6 +153,30 @@ void UDPClientSocket::UseNonBlockingIO() {
#endif
}
+void UDPClientSocket::SetWriteAsyncEnabled(bool enabled) {
+ socket_.SetWriteAsyncEnabled(enabled);
+}
+
+void UDPClientSocket::SetMaxPacketSize(size_t max_packet_size) {
+ socket_.SetMaxPacketSize(max_packet_size);
+}
+
+bool UDPClientSocket::WriteAsyncEnabled() {
+ return socket_.WriteAsyncEnabled();
+}
+
+void UDPClientSocket::SetWriteMultiCoreEnabled(bool enabled) {
+ socket_.SetWriteMultiCoreEnabled(enabled);
+}
+
+void UDPClientSocket::SetSendmmsgEnabled(bool enabled) {
+ socket_.SetSendmmsgEnabled(enabled);
+}
+
+void UDPClientSocket::SetWriteBatchingActive(bool active) {
+ socket_.SetWriteBatchingActive(active);
+}
+
void UDPClientSocket::EnableRecvOptimization() {
#if defined(OS_POSIX)
socket_.enable_experimental_recv_optimization();
diff --git a/chromium/net/socket/udp_client_socket.h b/chromium/net/socket/udp_client_socket.h
index 4abdb27ded0..fa87337431f 100644
--- a/chromium/net/socket/udp_client_socket.h
+++ b/chromium/net/socket/udp_client_socket.h
@@ -9,7 +9,6 @@
#include "base/macros.h"
#include "net/base/net_export.h"
-#include "net/base/rand_callback.h"
#include "net/socket/datagram_client_socket.h"
#include "net/socket/udp_socket.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
@@ -23,7 +22,6 @@ struct NetLogSource;
class NET_EXPORT_PRIVATE UDPClientSocket : public DatagramClientSocket {
public:
UDPClientSocket(DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
net::NetLog* net_log,
const net::NetLogSource& source);
~UDPClientSocket() override;
@@ -42,18 +40,39 @@ class NET_EXPORT_PRIVATE UDPClientSocket : public DatagramClientSocket {
int buf_len,
const CompletionCallback& callback,
const NetworkTrafficAnnotationTag& traffic_annotation) override;
+
+ int WriteAsync(
+ const char* buffer,
+ size_t buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
+ int WriteAsync(
+ DatagramBuffers buffers,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
+
+ DatagramBuffers GetUnwrittenBuffers() override;
+
void Close() override;
int GetPeerAddress(IPEndPoint* address) const override;
int GetLocalAddress(IPEndPoint* address) const override;
+ // Switch to use non-blocking IO. Must be called right after construction and
+ // before other calls.
void UseNonBlockingIO() override;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
int SetDoNotFragment() override;
+ void SetMsgConfirm(bool confirm) override;
const NetLogWithSource& NetLog() const override;
void EnableRecvOptimization() override;
- // Switch to use non-blocking IO. Must be called right after construction and
- // before other calls.
+ void SetWriteAsyncEnabled(bool enabled) override;
+ bool WriteAsyncEnabled() override;
+ void SetMaxPacketSize(size_t max_packet_size) override;
+ void SetWriteMultiCoreEnabled(bool enabled) override;
+ void SetSendmmsgEnabled(bool enabled) override;
+ void SetWriteBatchingActive(bool active) override;
+
private:
UDPSocket socket_;
NetworkChangeNotifier::NetworkHandle network_;
diff --git a/chromium/net/socket/udp_server_socket.cc b/chromium/net/socket/udp_server_socket.cc
index d5f107a8aa3..d2f18f4ff4b 100644
--- a/chromium/net/socket/udp_server_socket.cc
+++ b/chromium/net/socket/udp_server_socket.cc
@@ -5,13 +5,12 @@
#include "net/socket/udp_server_socket.h"
#include "net/base/net_errors.h"
-#include "net/base/rand_callback.h"
namespace net {
UDPServerSocket::UDPServerSocket(net::NetLog* net_log,
const net::NetLogSource& source)
- : socket_(DatagramSocket::DEFAULT_BIND, RandIntCallback(), net_log, source),
+ : socket_(DatagramSocket::DEFAULT_BIND, net_log, source),
allow_address_reuse_(false),
allow_broadcast_(false) {}
@@ -67,6 +66,10 @@ int UDPServerSocket::SetDoNotFragment() {
return socket_.SetDoNotFragment();
}
+void UDPServerSocket::SetMsgConfirm(bool confirm) {
+ return socket_.SetMsgConfirm(confirm);
+}
+
void UDPServerSocket::Close() {
socket_.Close();
}
diff --git a/chromium/net/socket/udp_server_socket.h b/chromium/net/socket/udp_server_socket.h
index 5d3cbdb28c1..0d2dc7e3ea0 100644
--- a/chromium/net/socket/udp_server_socket.h
+++ b/chromium/net/socket/udp_server_socket.h
@@ -39,6 +39,7 @@ class NET_EXPORT UDPServerSocket : public DatagramServerSocket {
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
int SetDoNotFragment() override;
+ void SetMsgConfirm(bool confirm) override;
void Close() override;
int GetPeerAddress(IPEndPoint* address) const override;
int GetLocalAddress(IPEndPoint* address) const override;
diff --git a/chromium/net/socket/udp_socket_perftest.cc b/chromium/net/socket/udp_socket_perftest.cc
index 25f0ba349a3..c2c89ad057c 100644
--- a/chromium/net/socket/udp_socket_perftest.cc
+++ b/chromium/net/socket/udp_socket_perftest.cc
@@ -105,9 +105,8 @@ void UDPSocketPerfTest::WriteBenchmark(bool use_nonblocking_io) {
// Setup the client.
IPEndPoint server_address;
CreateUDPAddress("127.0.0.1", kPort, &server_address);
- std::unique_ptr<UDPClientSocket> client(
- new UDPClientSocket(DatagramSocket::DEFAULT_BIND, RandIntCallback(),
- nullptr, NetLogSource()));
+ std::unique_ptr<UDPClientSocket> client(new UDPClientSocket(
+ DatagramSocket::DEFAULT_BIND, nullptr, NetLogSource()));
if (use_nonblocking_io)
client->UseNonBlockingIO();
rv = client->Connect(server_address);
diff --git a/chromium/net/socket/udp_socket_posix.cc b/chromium/net/socket/udp_socket_posix.cc
index fee77caef8b..b3b30e5cee7 100644
--- a/chromium/net/socket/udp_socket_posix.cc
+++ b/chromium/net/socket/udp_socket_posix.cc
@@ -10,10 +10,10 @@
#include <netdb.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
-#include <sys/socket.h>
#include "base/callback.h"
#include "base/callback_helpers.h"
+#include "base/containers/stack_container.h"
#include "base/debug/alias.h"
#include "base/files/file_util.h"
#include "base/logging.h"
@@ -21,6 +21,8 @@
#include "base/metrics/histogram_functions.h"
#include "base/posix/eintr_wrapper.h"
#include "base/rand_util.h"
+#include "base/task_runner_util.h"
+#include "base/task_scheduler/post_task.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "net/base/io_buffer.h"
@@ -94,14 +96,19 @@ int GetIPv4AddressFromIndex(int socket, uint32_t index, uint32_t* address) {
return MapSystemError(errno);
result = reinterpret_cast<sockaddr_in*>(&ifr.ifr_addr);
#elif defined(OS_FUCHSIA)
- netc_get_if_info_t netconfig;
- int size = ioctl_netc_get_if_info(socket, &netconfig);
- if (size < 0)
+ uint32_t num_ifs = 0;
+ if (ioctl_netc_get_num_ifs(socket, &num_ifs) < 0) {
+ PLOG(ERROR) << "ioctl_netc_get_num_ifs";
return MapSystemError(errno);
- for (size_t i = 0; i < netconfig.n_info; ++i) {
- netc_if_info_t* interface = netconfig.info + i;
- if (interface->index == index && interface->addr.ss_family == AF_INET) {
- result = reinterpret_cast<sockaddr_in*>(&(interface->addr));
+ }
+ for (uint32_t i = 0; i < num_ifs; ++i) {
+ netc_if_info_t interface;
+ if (ioctl_netc_get_if_info_at(socket, &i, &interface) < 0) {
+ PLOG(WARNING) << "ioctl_netc_get_if_info_at";
+ continue;
+ }
+ if (interface.index == index && interface.addr.ss_family == AF_INET) {
+ result = reinterpret_cast<sockaddr_in*>(&(interface.addr));
break;
}
}
@@ -187,31 +194,34 @@ const guardid_t kSocketFdGuard = 0xD712BC0BC9A4EAD4;
} // namespace
UDPSocketPosix::UDPSocketPosix(DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
net::NetLog* net_log,
const net::NetLogSource& source)
- : socket_(kInvalidSocket),
+ : write_async_watcher_(std::make_unique<WriteAsyncWatcher>(this)),
+ sender_(new UDPSocketPosixSender()),
+ socket_(kInvalidSocket),
addr_family_(0),
is_connected_(false),
socket_options_(SOCKET_OPTION_MULTICAST_LOOP),
+ sendto_flags_(0),
multicast_interface_(0),
multicast_time_to_live_(1),
bind_type_(bind_type),
- rand_int_cb_(rand_int_cb),
read_socket_watcher_(FROM_HERE),
write_socket_watcher_(FROM_HERE),
read_watcher_(this),
write_watcher_(this),
+ last_async_result_(0),
+ write_async_timer_running_(false),
+ write_async_outstanding_(0),
read_buf_len_(0),
recv_from_address_(NULL),
write_buf_len_(0),
net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::UDP_SOCKET)),
bound_network_(NetworkChangeNotifier::kInvalidNetworkHandle),
- experimental_recv_optimization_enabled_(false) {
+ experimental_recv_optimization_enabled_(false),
+ weak_factory_(this) {
net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE,
source.ToEventParametersCallback());
- if (bind_type == DatagramSocket::RANDOM_BIND)
- DCHECK(!rand_int_cb.is_null());
}
UDPSocketPosix::~UDPSocketPosix() {
@@ -329,6 +339,7 @@ void UDPSocketPosix::Close() {
is_connected_ = false;
tag_ = SocketTag();
+ write_async_timer_.Stop();
sent_activity_monitor_.OnClose();
received_activity_monitor_.OnClose();
}
@@ -398,7 +409,7 @@ int UDPSocketPosix::RecvFrom(IOBuffer* buf,
return nread;
if (!base::MessageLoopForIO::current()->WatchFileDescriptor(
- socket_, true, base::MessageLoopForIO::WATCH_READ,
+ socket_, true, base::MessagePumpForIO::WATCH_READ,
&read_socket_watcher_, &read_watcher_)) {
PLOG(ERROR) << "WatchFileDescriptor failed on read";
int result = MapSystemError(errno);
@@ -443,7 +454,7 @@ int UDPSocketPosix::SendToOrWrite(IOBuffer* buf,
return result;
if (!base::MessageLoopForIO::current()->WatchFileDescriptor(
- socket_, true, base::MessageLoopForIO::WATCH_WRITE,
+ socket_, true, base::MessagePumpForIO::WATCH_WRITE,
&write_socket_watcher_, &write_watcher_)) {
DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno;
int result = MapSystemError(errno);
@@ -644,6 +655,16 @@ int UDPSocketPosix::SetDoNotFragment() {
#endif
}
+void UDPSocketPosix::SetMsgConfirm(bool confirm) {
+#if !defined(OS_MACOSX) && !defined(OS_IOS)
+ if (confirm) {
+ sendto_flags_ |= MSG_CONFIRM;
+ } else {
+ sendto_flags_ &= ~MSG_CONFIRM;
+ }
+#endif // !defined(OS_MACOSX) && !defined(OS_IOS)
+}
+
int UDPSocketPosix::AllowAddressReuse() {
DCHECK_NE(socket_, kInvalidSocket);
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
@@ -862,12 +883,8 @@ int UDPSocketPosix::InternalSendTo(IOBuffer* buf,
}
}
- int result = HANDLE_EINTR(sendto(socket_,
- buf->data(),
- buf_len,
- 0,
- addr,
- storage.addr_len));
+ int result = HANDLE_EINTR(sendto(socket_, buf->data(), buf_len, sendto_flags_,
+ addr, storage.addr_len));
if (result < 0)
result = MapSystemError(errno);
if (result != ERR_IO_PENDING)
@@ -961,14 +978,14 @@ int UDPSocketPosix::DoBind(const IPEndPoint& address) {
}
int UDPSocketPosix::RandomBind(const IPAddress& address) {
- DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null());
+ DCHECK_EQ(bind_type_, DatagramSocket::RANDOM_BIND);
for (int i = 0; i < kBindRetries; ++i) {
- int rv = DoBind(IPEndPoint(address,
- rand_int_cb_.Run(kPortStart, kPortEnd)));
+ int rv = DoBind(IPEndPoint(address, base::RandInt(kPortStart, kPortEnd)));
if (rv != ERR_ADDRESS_IN_USE)
return rv;
}
+
return DoBind(IPEndPoint(address, 0));
}
@@ -1106,12 +1123,14 @@ int UDPSocketPosix::SetDiffServCodePoint(DiffServCodePoint dscp) {
if (dscp == DSCP_NO_CHANGE) {
return OK;
}
- int rv;
+
int dscp_and_ecn = dscp << 2;
- if (addr_family_ == AF_INET) {
- rv = setsockopt(socket_, IPPROTO_IP, IP_TOS,
- &dscp_and_ecn, sizeof(dscp_and_ecn));
- } else {
+ // Set the IPv4 option in all cases to support dual-stack sockets.
+ int rv = setsockopt(socket_, IPPROTO_IP, IP_TOS, &dscp_and_ecn,
+ sizeof(dscp_and_ecn));
+ if (addr_family_ == AF_INET6) {
+ // In the IPv6 case, the previous socksetopt may fail because of a lack of
+ // dual-stack support. Therefore ignore the previous return value.
rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_TCLASS,
&dscp_and_ecn, sizeof(dscp_and_ecn));
}
@@ -1133,4 +1152,344 @@ void UDPSocketPosix::ApplySocketTag(const SocketTag& tag) {
tag_ = tag;
}
+UDPSocketPosixSender::UDPSocketPosixSender() : sendmmsg_enabled_(false) {}
+UDPSocketPosixSender::~UDPSocketPosixSender() {}
+
+SendResult::SendResult() : rv(0), write_count(0) {}
+SendResult::~SendResult() {}
+SendResult::SendResult(int _rv, int _write_count, DatagramBuffers _buffers)
+ : rv(_rv), write_count(_write_count), buffers(std::move(_buffers)) {}
+SendResult::SendResult(SendResult&& other) = default;
+
+SendResult UDPSocketPosixSender::InternalSendBuffers(
+ int fd,
+ DatagramBuffers buffers) const {
+ int rv = 0;
+ int write_count = 0;
+ for (auto& buffer : buffers) {
+ int result = HANDLE_EINTR(Send(fd, buffer->data(), buffer->length(), 0));
+ if (result < 0) {
+ rv = MapSystemError(errno);
+ break;
+ }
+ write_count++;
+ }
+ return SendResult(rv, write_count, std::move(buffers));
+}
+
+#if HAVE_SENDMMSG
+SendResult UDPSocketPosixSender::InternalSendmmsgBuffers(
+ int fd,
+ DatagramBuffers buffers) const {
+ base::StackVector<struct iovec, kWriteAsyncMaxBuffersThreshold + 1> msg_iov;
+ base::StackVector<struct mmsghdr, kWriteAsyncMaxBuffersThreshold + 1> msgvec;
+ int i = 0;
+ for (auto& buffer : buffers) {
+ msg_iov[i].iov_base = const_cast<char*>(buffer->data());
+ msg_iov[i].iov_len = buffer->length();
+ i++;
+ }
+ for (size_t j = 0; j < buffers.size(); j++) {
+ std::memset(&msgvec[j], 0, sizeof(msgvec[j]));
+ msgvec[j].msg_hdr.msg_iov = &msg_iov[j];
+ msgvec[j].msg_hdr.msg_iovlen = 1;
+ }
+ int result = HANDLE_EINTR(Sendmmsg(fd, &msgvec[0], buffers.size(), 0));
+ SendResult send_result(0, 0, std::move(buffers));
+ if (result < 0) {
+ send_result.rv = MapSystemError(errno);
+ } else {
+ send_result.write_count = result;
+ }
+ return send_result;
+}
+#endif
+
+SendResult UDPSocketPosixSender::SendBuffers(int fd, DatagramBuffers buffers) {
+#if HAVE_SENDMMSG
+ if (sendmmsg_enabled_) {
+ auto result = InternalSendmmsgBuffers(fd, std::move(buffers));
+ if (LIKELY(result.rv != ERR_NOT_IMPLEMENTED)) {
+ return result;
+ }
+ DLOG(WARNING) << "senddmsg() not implemented, falling back to send()";
+ sendmmsg_enabled_ = false;
+ buffers = std::move(result.buffers);
+ }
+#endif
+ return InternalSendBuffers(fd, std::move(buffers));
+}
+
+ssize_t UDPSocketPosixSender::Send(int sockfd,
+ const void* buf,
+ size_t len,
+ int flags) const {
+ return send(sockfd, buf, len, flags);
+}
+
+#if HAVE_SENDMMSG
+int UDPSocketPosixSender::Sendmmsg(int sockfd,
+ struct mmsghdr* msgvec,
+ unsigned int vlen,
+ unsigned int flags) const {
+ return sendmmsg(sockfd, msgvec, vlen, flags);
+}
+#endif
+
+int UDPSocketPosix::WriteAsync(
+ const char* buffer,
+ size_t buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
+ DCHECK(datagram_buffer_pool_ != nullptr);
+ IncreaseWriteAsyncOutstanding(1);
+ datagram_buffer_pool_->Enqueue(buffer, buf_len, &pending_writes_);
+ return InternalWriteAsync(callback, traffic_annotation);
+}
+
+int UDPSocketPosix::WriteAsync(
+ DatagramBuffers buffers,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
+ IncreaseWriteAsyncOutstanding(buffers.size());
+ pending_writes_.splice(pending_writes_.end(), std::move(buffers));
+ return InternalWriteAsync(callback, traffic_annotation);
+}
+
+int UDPSocketPosix::InternalWriteAsync(
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
+ CHECK(write_callback_.is_null());
+
+ // Surface error immediately if one is pending.
+ if (last_async_result_ < 0) {
+ return ResetLastAsyncResult();
+ }
+
+ size_t flush_threshold =
+ write_batching_active_ ? kWriteAsyncPostBuffersThreshold : 1;
+ if (pending_writes_.size() >= flush_threshold) {
+ FlushPending();
+ // Surface error immediately if one is pending.
+ if (last_async_result_ < 0) {
+ return ResetLastAsyncResult();
+ }
+ }
+
+ if (!write_async_timer_running_) {
+ write_async_timer_running_ = true;
+ write_async_timer_.Start(FROM_HERE, kWriteAsyncMsThreshold, this,
+ &UDPSocketPosix::OnWriteAsyncTimerFired);
+ }
+
+ int blocking_threshold =
+ write_batching_active_ ? kWriteAsyncMaxBuffersThreshold : 1;
+ if (write_async_outstanding_ >= blocking_threshold) {
+ write_callback_ = callback;
+ return ERR_IO_PENDING;
+ }
+
+ DVLOG(2) << __func__ << " pending " << pending_writes_.size()
+ << " outstanding " << write_async_outstanding_;
+ return ResetWrittenBytes();
+}
+
+DatagramBuffers UDPSocketPosix::GetUnwrittenBuffers() {
+ write_async_outstanding_ -= pending_writes_.size();
+ return std::move(pending_writes_);
+}
+
+void UDPSocketPosix::FlushPending() {
+ // Nothing to do if socket is blocked.
+ if (write_async_watcher_->watching())
+ return;
+
+ if (pending_writes_.empty())
+ return;
+
+ if (write_async_timer_running_)
+ write_async_timer_.Reset();
+
+ int num_pending_writes = static_cast<int>(pending_writes_.size());
+ if (!write_multi_core_enabled_ ||
+ // Don't bother with post if not enough buffers
+ (num_pending_writes <= kWriteAsyncMinBuffersThreshold &&
+ // but not if there is a previous post
+ // outstanding, to prevent out of order transmission.
+ (num_pending_writes == write_async_outstanding_))) {
+ LocalSendBuffers();
+ } else {
+ PostSendBuffers();
+ }
+}
+
+// TODO(ckrasic) Sad face. Do this lazily because many tests exploded
+// otherwise. |threading_and_tasks.md| advises to instantiate a
+// |base::test::ScopedTaskEnvironment| in the test, implementing that
+// for all tests that might exercise QUIC is too daunting. Also, in
+// some tests it seemed like following the advice just broke in other
+// ways.
+base::SequencedTaskRunner* UDPSocketPosix::GetTaskRunner() {
+ if (task_runner_ == nullptr) {
+ task_runner_ = CreateSequencedTaskRunnerWithTraits(base::TaskTraits());
+ }
+ return task_runner_.get();
+}
+
+void UDPSocketPosix::OnWriteAsyncTimerFired() {
+ DVLOG(2) << __func__ << " pending writes " << pending_writes_.size();
+ if (pending_writes_.empty()) {
+ write_async_timer_.Stop();
+ write_async_timer_running_ = false;
+ return;
+ }
+ if (last_async_result_ < 0) {
+ DVLOG(1) << __func__ << " socket not writeable";
+ return;
+ }
+ FlushPending();
+}
+
+void UDPSocketPosix::LocalSendBuffers() {
+ DVLOG(1) << __func__ << " queue " << pending_writes_.size() << " out of "
+ << write_async_outstanding_ << " total";
+ DidSendBuffers(sender_->SendBuffers(socket_, std::move(pending_writes_)));
+}
+
+void UDPSocketPosix::PostSendBuffers() {
+ DVLOG(1) << __func__ << " queue " << pending_writes_.size() << " out of "
+ << write_async_outstanding_ << " total";
+ base::PostTaskAndReplyWithResult(
+ GetTaskRunner(), FROM_HERE,
+ base::BindOnce(&UDPSocketPosixSender::SendBuffers, sender_, socket_,
+ std::move(pending_writes_)),
+ base::BindOnce(&UDPSocketPosix::DidSendBuffers,
+ weak_factory_.GetWeakPtr()));
+}
+
+void UDPSocketPosix::DidSendBuffers(SendResult send_result) {
+ DVLOG(3) << __func__;
+ int write_count = send_result.write_count;
+ DatagramBuffers& buffers = send_result.buffers;
+
+ DCHECK(!buffers.empty());
+ int num_buffers = buffers.size();
+
+ // Dequeue buffers that have been written.
+ if (write_count > 0) {
+ write_async_outstanding_ -= write_count;
+
+ DatagramBuffers::const_iterator it;
+ // Generate logs for written buffers
+ it = buffers.cbegin();
+ for (int i = 0; i < write_count; i++, it++) {
+ auto& buffer = *it;
+ LogWrite(buffer->length(), buffer->data(), NULL);
+ written_bytes_ += buffer->length();
+ }
+ // Return written buffers to pool
+ DatagramBuffers written_buffers;
+ if (write_count == num_buffers) {
+ it = buffers.cend();
+ } else {
+ it = buffers.cbegin();
+ for (int i = 0; i < write_count; i++) {
+ it++;
+ }
+ }
+ written_buffers.splice(written_buffers.cend(), buffers, buffers.cbegin(),
+ it);
+ DCHECK(datagram_buffer_pool_ != nullptr);
+ datagram_buffer_pool_->Dequeue(&written_buffers);
+ }
+
+ // Requeue left-over (unwritten) buffers.
+ if (!buffers.empty()) {
+ DVLOG(2) << __func__ << " requeue " << buffers.size() << " buffers";
+ pending_writes_.splice(pending_writes_.begin(), std::move(buffers));
+ }
+
+ last_async_result_ = send_result.rv;
+ if (last_async_result_ == ERR_IO_PENDING) {
+ DVLOG(2) << __func__ << " WatchFileDescriptor start";
+ if (!WatchFileDescriptor()) {
+ DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno;
+ last_async_result_ = MapSystemError(errno);
+ LogWrite(last_async_result_, NULL, NULL);
+ } else {
+ last_async_result_ = 0;
+ }
+ } else if (last_async_result_ < 0 || pending_writes_.empty()) {
+ DVLOG(2) << __func__ << " WatchFileDescriptor stop: result "
+ << ErrorToShortString(last_async_result_) << " pending_writes "
+ << pending_writes_.size();
+ StopWatchingFileDescriptor();
+ }
+ DCHECK(last_async_result_ != ERR_IO_PENDING);
+
+ if (write_callback_.is_null())
+ return;
+
+ if (last_async_result_ < 0) {
+ DVLOG(1) << last_async_result_;
+ // Update the writer with the latest result.
+ DoWriteCallback(ResetLastAsyncResult());
+ } else if (write_async_outstanding_ < kWriteAsyncCallbackBuffersThreshold) {
+ DVLOG(1) << write_async_outstanding_ << " < "
+ << kWriteAsyncCallbackBuffersThreshold;
+ DoWriteCallback(ResetWrittenBytes());
+ }
+}
+
+void UDPSocketPosix::WriteAsyncWatcher::OnFileCanWriteWithoutBlocking(int) {
+ DVLOG(1) << __func__ << " queue " << socket_->pending_writes_.size()
+ << " out of " << socket_->write_async_outstanding_ << " total";
+ socket_->StopWatchingFileDescriptor();
+ socket_->FlushPending();
+}
+
+bool UDPSocketPosix::WatchFileDescriptor() {
+ if (write_async_watcher_->watching())
+ return true;
+ bool result = InternalWatchFileDescriptor();
+ if (result) {
+ write_async_watcher_->set_watching(true);
+ }
+ return result;
+}
+
+void UDPSocketPosix::StopWatchingFileDescriptor() {
+ if (!write_async_watcher_->watching())
+ return;
+ InternalStopWatchingFileDescriptor();
+ write_async_watcher_->set_watching(false);
+}
+
+bool UDPSocketPosix::InternalWatchFileDescriptor() {
+ return base::MessageLoopForIO::current()->WatchFileDescriptor(
+ socket_, true, base::MessagePumpForIO::WATCH_WRITE,
+ &write_socket_watcher_, write_async_watcher_.get());
+}
+
+void UDPSocketPosix::InternalStopWatchingFileDescriptor() {
+ bool ok = write_socket_watcher_.StopWatchingFileDescriptor();
+ DCHECK(ok);
+}
+
+void UDPSocketPosix::SetMaxPacketSize(size_t max_packet_size) {
+ datagram_buffer_pool_ = std::make_unique<DatagramBufferPool>(max_packet_size);
+}
+
+int UDPSocketPosix::ResetLastAsyncResult() {
+ int result = last_async_result_;
+ last_async_result_ = 0;
+ return result;
+}
+
+int UDPSocketPosix::ResetWrittenBytes() {
+ int bytes = written_bytes_;
+ written_bytes_ = 0;
+ return bytes;
+}
+
} // namespace net
diff --git a/chromium/net/socket/udp_socket_posix.h b/chromium/net/socket/udp_socket_posix.h
index 6595880391d..81cca5911dd 100644
--- a/chromium/net/socket/udp_socket_posix.h
+++ b/chromium/net/socket/udp_socket_posix.h
@@ -6,21 +6,24 @@
#define NET_SOCKET_UDP_SOCKET_POSIX_H_
#include <stdint.h>
+#include <sys/socket.h>
+#include <sys/types.h>
#include <memory>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_pump_for_io.h"
#include "base/threading/thread_checker.h"
#include "base/timer/timer.h"
+#include "build/build_config.h"
#include "net/base/address_family.h"
#include "net/base/completion_callback.h"
+#include "net/base/datagram_buffer.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_export.h"
#include "net/base/network_change_notifier.h"
-#include "net/base/rand_callback.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/datagram_socket.h"
#include "net/socket/diff_serv_code_point.h"
@@ -28,6 +31,14 @@
#include "net/socket/socket_tag.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
+#if defined(__ANDROID__) && defined(__aarch64__)
+#define HAVE_SENDMMSG 1
+#elif defined(OS_LINUX)
+#define HAVE_SENDMMSG 1
+#else
+#define HAVE_SENDMMSG 0
+#endif
+
namespace net {
class IPAddress;
@@ -35,6 +46,77 @@ class NetLog;
struct NetLogSource;
class SocketTag;
+// Sendresult is inspired by sendmmsg, but unlike sendmmsg it is not
+// convenient to require that a positive |write_count| and a negative
+// error code are mutually exclusive.
+struct NET_EXPORT SendResult {
+ explicit SendResult();
+ ~SendResult();
+ SendResult(int rv, int write_count, DatagramBuffers buffers);
+ SendResult(SendResult& other) = delete;
+ SendResult& operator=(SendResult& other) = delete;
+ SendResult(SendResult&& other);
+ SendResult& operator=(SendResult&& other) = default;
+ int rv;
+ // number of successful writes.
+ int write_count;
+ DatagramBuffers buffers;
+};
+
+// Don't delay writes more than this.
+const base::TimeDelta kWriteAsyncMsThreshold =
+ base::TimeDelta::FromMilliseconds(1);
+// Prefer local if number of writes is not more than this.
+const int kWriteAsyncMinBuffersThreshold = 2;
+// Don't allow more than this many outstanding async writes.
+const int kWriteAsyncMaxBuffersThreshold = 16;
+// PostTask immediately when unwritten buffers reaches this.
+const int kWriteAsyncPostBuffersThreshold = kWriteAsyncMaxBuffersThreshold / 2;
+// Don't unblock writer unless pending async writes are less than this.
+const int kWriteAsyncCallbackBuffersThreshold = kWriteAsyncMaxBuffersThreshold;
+
+// To allow mock |Send|/|Sendmsg| in testing. This has to be
+// reference counted thread safe because |SendBuffers| and
+// |SendmmsgBuffers| may be invoked in another thread via PostTask*.
+class NET_EXPORT UDPSocketPosixSender
+ : public base::RefCountedThreadSafe<UDPSocketPosixSender> {
+ public:
+ explicit UDPSocketPosixSender();
+
+ SendResult SendBuffers(int fd, DatagramBuffers buffers);
+
+ void SetSendmmsgEnabled(bool enabled) {
+#if HAVE_SENDMMSG
+ sendmmsg_enabled_ = enabled;
+#endif
+ }
+
+ protected:
+ friend class base::RefCountedThreadSafe<UDPSocketPosixSender>;
+
+ virtual ~UDPSocketPosixSender();
+ virtual ssize_t Send(int sockfd,
+ const void* buf,
+ size_t len,
+ int flags) const;
+#if HAVE_SENDMMSG
+ virtual int Sendmmsg(int sockfd,
+ struct mmsghdr* msgvec,
+ unsigned int vlen,
+ unsigned int flags) const;
+#endif
+
+ SendResult InternalSendBuffers(int fd, DatagramBuffers buffers) const;
+#if HAVE_SENDMMSG
+ SendResult InternalSendmmsgBuffers(int fd, DatagramBuffers buffers) const;
+#endif
+
+ private:
+ UDPSocketPosixSender(const UDPSocketPosixSender&) = delete;
+ UDPSocketPosixSender& operator=(const UDPSocketPosixSender&) = delete;
+ bool sendmmsg_enabled_;
+};
+
class NET_EXPORT UDPSocketPosix {
public:
// Performance helper for NetworkActivityMonitor, it batches
@@ -80,7 +162,6 @@ class NET_EXPORT UDPSocketPosix {
};
UDPSocketPosix(DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
net::NetLog* net_log,
const net::NetLogSource& source);
virtual ~UDPSocketPosix();
@@ -134,6 +215,17 @@ class NET_EXPORT UDPSocketPosix {
const CompletionCallback& callback,
const NetworkTrafficAnnotationTag& traffic_annotation);
+ // Refer to datagram_client_socket.h
+ int WriteAsync(DatagramBuffers buffers,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
+ int WriteAsync(const char* buffer,
+ size_t buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
+
+ DatagramBuffers GetUnwrittenBuffers();
+
// Reads from a socket and receive sender address information.
// |buf| is the buffer to read data into.
// |buf_len| is the maximum amount of data to read.
@@ -177,6 +269,10 @@ class NET_EXPORT UDPSocketPosix {
// return ERR_IO_PENDING.
int SetDoNotFragment();
+ // If |confirm| is true, then the MSG_CONFIRM flag will be passed to
+ // subsequent writes if it's supported by the platform.
+ void SetMsgConfirm(bool confirm);
+
// Returns true if the socket is already connected or bound.
bool is_connected() const { return is_connected_; }
@@ -247,6 +343,27 @@ class NET_EXPORT UDPSocketPosix {
// Apply |tag| to this socket.
void ApplySocketTag(const SocketTag& tag);
+ void SetWriteAsyncEnabled(bool enabled) { write_async_enabled_ = enabled; }
+ bool WriteAsyncEnabled() { return write_async_enabled_; }
+
+ void SetMaxPacketSize(size_t max_packet_size);
+
+ void SetWriteMultiCoreEnabled(bool enabled) {
+ write_multi_core_enabled_ = enabled;
+ }
+
+ void SetSendmmsgEnabled(bool enabled) {
+ DCHECK(sender_ != nullptr);
+ sender_->SetSendmmsgEnabled(enabled);
+ }
+
+ void SetWriteBatchingActive(bool active) { write_batching_active_ = active; }
+
+ void SetWriteAsyncMaxBuffers(int value) {
+ LOG(INFO) << "SetWriteAsyncMaxBuffers: " << value;
+ write_async_max_buffers_ = value;
+ }
+
// Enables experimental optimization. This method should be called
// before the socket is used to read data for the first time.
void enable_experimental_recv_optimization() {
@@ -254,16 +371,64 @@ class NET_EXPORT UDPSocketPosix {
experimental_recv_optimization_enabled_ = true;
};
+ protected:
+ // WriteAsync batching etc. are to improve throughput of large high
+ // bandwidth uploads.
+
+ // Watcher for WriteAsync paths.
+ class WriteAsyncWatcher : public base::MessagePumpForIO::FdWatcher {
+ public:
+ explicit WriteAsyncWatcher(UDPSocketPosix* socket)
+ : socket_(socket), watching_(false) {}
+
+ // MessagePumpForIO::FdWatcher methods
+
+ void OnFileCanReadWithoutBlocking(int /* fd */) override {}
+
+ void OnFileCanWriteWithoutBlocking(int /* fd */) override;
+
+ void set_watching(bool watching) { watching_ = watching; }
+
+ bool watching() { return watching_; }
+
+ private:
+ UDPSocketPosix* const socket_;
+ bool watching_;
+
+ DISALLOW_COPY_AND_ASSIGN(WriteAsyncWatcher);
+ };
+
+ void IncreaseWriteAsyncOutstanding(int increment) {
+ write_async_outstanding_ += increment;
+ }
+
+ virtual bool InternalWatchFileDescriptor();
+ virtual void InternalStopWatchingFileDescriptor();
+
+ void SetWriteCallback(CompletionCallback callback) {
+ write_callback_ = std::move(callback);
+ }
+
+ void DidSendBuffers(SendResult buffers);
+ void FlushPending();
+
+ std::unique_ptr<WriteAsyncWatcher> write_async_watcher_;
+ scoped_refptr<UDPSocketPosixSender> sender_;
+ std::unique_ptr<DatagramBufferPool> datagram_buffer_pool_;
+ // |WriteAsync| pending writes, does not include buffers that have
+ // been |PostTask*|'d.
+ DatagramBuffers pending_writes_;
+
private:
enum SocketOptions {
SOCKET_OPTION_MULTICAST_LOOP = 1 << 0
};
- class ReadWatcher : public base::MessageLoopForIO::Watcher {
+ class ReadWatcher : public base::MessagePumpForIO::FdWatcher {
public:
explicit ReadWatcher(UDPSocketPosix* socket) : socket_(socket) {}
- // MessageLoopForIO::Watcher methods
+ // MessagePumpForIO::FdWatcher methods
void OnFileCanReadWithoutBlocking(int /* fd */) override;
@@ -275,11 +440,11 @@ class NET_EXPORT UDPSocketPosix {
DISALLOW_COPY_AND_ASSIGN(ReadWatcher);
};
- class WriteWatcher : public base::MessageLoopForIO::Watcher {
+ class WriteWatcher : public base::MessagePumpForIO::FdWatcher {
public:
explicit WriteWatcher(UDPSocketPosix* socket) : socket_(socket) {}
- // MessageLoopForIO::Watcher methods
+ // MessagePumpForIO::FdWatcher methods
void OnFileCanReadWithoutBlocking(int /* fd */) override {}
@@ -291,6 +456,11 @@ class NET_EXPORT UDPSocketPosix {
DISALLOW_COPY_AND_ASSIGN(WriteWatcher);
};
+ int InternalWriteAsync(const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
+ bool WatchFileDescriptor();
+ void StopWatchingFileDescriptor();
+
void DoReadCallback(int rv);
void DoWriteCallback(int rv);
void DidCompleteRead();
@@ -345,6 +515,14 @@ class NET_EXPORT UDPSocketPosix {
// Binds to a random port on |address|.
int RandomBind(const IPAddress& address);
+ // Helpers for |WriteAsync|
+ base::SequencedTaskRunner* GetTaskRunner();
+ void OnWriteAsyncTimerFired();
+ void LocalSendBuffers();
+ void PostSendBuffers();
+ int ResetLastAsyncResult();
+ int ResetWrittenBytes();
+
int socket_;
int addr_family_;
@@ -354,6 +532,9 @@ class NET_EXPORT UDPSocketPosix {
// options that should be applied to |socket_| before Bind().
int socket_options_;
+ // Flags passed to sendto().
+ int sendto_flags_;
+
// Multicast interface.
uint32_t multicast_interface_;
@@ -365,22 +546,34 @@ class NET_EXPORT UDPSocketPosix {
// UDPClientSocket, since UDPServerSocket provides Bind.
DatagramSocket::BindType bind_type_;
- // PRNG function for generating port numbers.
- RandIntCallback rand_int_cb_;
-
// These are mutable since they're just cached copies to make
// GetPeerAddress/GetLocalAddress smarter.
mutable std::unique_ptr<IPEndPoint> local_address_;
mutable std::unique_ptr<IPEndPoint> remote_address_;
// The socket's posix wrappers
- base::MessageLoopForIO::FileDescriptorWatcher read_socket_watcher_;
- base::MessageLoopForIO::FileDescriptorWatcher write_socket_watcher_;
+ base::MessagePumpForIO::FdWatchController read_socket_watcher_;
+ base::MessagePumpForIO::FdWatchController write_socket_watcher_;
// The corresponding watchers for reads and writes.
ReadWatcher read_watcher_;
WriteWatcher write_watcher_;
+ // Various bits to support |WriteAsync()|.
+ bool write_async_enabled_ = false;
+ bool write_batching_active_ = false;
+ bool write_multi_core_enabled_ = false;
+ int write_async_max_buffers_ = 16;
+ int written_bytes_ = 0;
+
+ int last_async_result_;
+ base::RepeatingTimer write_async_timer_;
+ bool write_async_timer_running_;
+ // Total writes in flight, including those |PostTask*|'d.
+ int write_async_outstanding_;
+
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
+
// The buffer used by InternalRead() to retry Read requests
scoped_refptr<IOBuffer> read_buf_;
int read_buf_len_;
@@ -418,6 +611,9 @@ class NET_EXPORT UDPSocketPosix {
THREAD_CHECKER(thread_checker_);
+ // Used for alternate writes that are posted for concurrent execution.
+ base::WeakPtrFactory<UDPSocketPosix> weak_factory_;
+
DISALLOW_COPY_AND_ASSIGN(UDPSocketPosix);
};
diff --git a/chromium/net/socket/udp_socket_posix_unittest.cc b/chromium/net/socket/udp_socket_posix_unittest.cc
new file mode 100644
index 00000000000..59ef03958d9
--- /dev/null
+++ b/chromium/net/socket/udp_socket_posix_unittest.cc
@@ -0,0 +1,747 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/socket/udp_socket_posix.h"
+
+#include "net/base/net_errors.h"
+#include "net/log/test_net_log.h"
+#include "net/log/test_net_log_entry.h"
+#include "net/log/test_net_log_util.h"
+#include "net/socket/datagram_socket.h"
+#include "net/test/net_test_suite.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::InvokeWithoutArgs;
+using ::testing::Return;
+
+namespace net {
+
+namespace test {
+
+namespace {
+
+const size_t kMaxPacketSize = 1500;
+const size_t kNumMsgs = 3;
+const std::string kHelloMsg = "Hello world";
+const std::string kSecondMsg = "Second buffer";
+const std::string kThirdMsg = "Third buffer";
+
+int SetWouldBlock() {
+ errno = EWOULDBLOCK;
+ return -1;
+}
+
+#if HAVE_SENDMMSG
+int SetNotImplemented() {
+ errno = ENOSYS;
+ return -1;
+}
+#endif
+
+bool WatcherSetInvalidHandle() {
+ errno = EBADF;
+ return false;
+}
+
+int SetInvalidHandle() {
+ errno = EBADF;
+ return -1;
+}
+
+} // namespace
+
+class MockUDPSocketPosixSender : public UDPSocketPosixSender {
+ public:
+ MOCK_CONST_METHOD4(
+ Send,
+ ssize_t(int sockfd, const void* buf, size_t len, int flags));
+ MOCK_CONST_METHOD4(Sendmmsg,
+ int(int sockfd,
+ struct mmsghdr* msgvec,
+ unsigned int vlen,
+ unsigned int flags));
+
+ public:
+ SendResult InternalSendBuffers(int fd, DatagramBuffers buffers) const {
+ return UDPSocketPosixSender::InternalSendBuffers(fd, std::move(buffers));
+ }
+#if HAVE_SENDMMSG
+ SendResult InternalSendmmsgBuffers(int fd, DatagramBuffers buffers) const {
+ return UDPSocketPosixSender::InternalSendmmsgBuffers(fd,
+ std::move(buffers));
+ }
+#endif
+
+ private:
+ ~MockUDPSocketPosixSender() override{};
+};
+
+class MockUDPSocketPosix : public UDPSocketPosix {
+ public:
+ MockUDPSocketPosix(DatagramSocket::BindType bind_type,
+ net::NetLog* net_log,
+ const net::NetLogSource& source)
+ : UDPSocketPosix(bind_type, net_log, source) {
+ sender_ = new MockUDPSocketPosixSender();
+ }
+
+ MockUDPSocketPosixSender* sender() {
+ return static_cast<MockUDPSocketPosixSender*>(sender_.get());
+ }
+
+ MOCK_METHOD0(InternalWatchFileDescriptor, bool());
+ MOCK_METHOD0(InternalStopWatchingFileDescriptor, void());
+
+ void FlushPending() { UDPSocketPosix::FlushPending(); }
+
+ void DidSendBuffers(SendResult buffers) {
+ UDPSocketPosix::DidSendBuffers(std::move(buffers));
+ }
+
+ void Enqueue(const std::string& msg, DatagramBuffers* buffers) {
+ datagram_buffer_pool_->Enqueue(msg.data(), msg.length(), buffers);
+ }
+
+ void SetWriteCallback(CompletionCallback callback) {
+ UDPSocketPosix::SetWriteCallback(std::move(callback));
+ }
+
+ void IncreaseWriteAsyncOutstanding(int increment) {
+ UDPSocketPosix::IncreaseWriteAsyncOutstanding(increment);
+ }
+
+ void SetPendingWrites(DatagramBuffers buffers) {
+ pending_writes_ = std::move(buffers);
+ }
+
+ void OnFileCanWriteWithoutBlocking() {
+ write_async_watcher_->OnFileCanWriteWithoutBlocking(1);
+ }
+};
+
+class UDPSocketPosixTest : public testing::Test {
+ public:
+ UDPSocketPosixTest()
+ : socket_(DatagramSocket::DEFAULT_BIND, &client_log_, NetLogSource()),
+ callback_fired_(false),
+ weak_factory_(this) {
+ write_callback_ = base::BindRepeating(&UDPSocketPosixTest::OnWriteComplete,
+ weak_factory_.GetWeakPtr());
+ }
+
+ void SetUp() override {
+ NetTestSuite::SetScopedTaskEnvironment(
+ base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME);
+ socket_.SetWriteAsyncEnabled(true);
+ socket_.SetMaxPacketSize(kMaxPacketSize);
+ }
+
+ void TearDown() override { NetTestSuite::ResetScopedTaskEnvironment(); }
+
+ void RunUntilIdle() {
+ NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
+ }
+
+ void FastForwardBy(base::TimeDelta delta) {
+ NetTestSuite::GetScopedTaskEnvironment()->FastForwardBy(delta);
+ }
+
+ void FastForwardUntilNoTasksRemain() {
+ NetTestSuite::GetScopedTaskEnvironment()->FastForwardUntilNoTasksRemain();
+ }
+
+ void AddBuffer(const std::string& msg) {
+ socket_.IncreaseWriteAsyncOutstanding(1);
+ socket_.Enqueue(msg, &buffers_);
+ }
+
+ void AddBuffers() {
+ for (size_t i = 0; i < kNumMsgs; i++) {
+ AddBuffer(msgs_[i]);
+ }
+ }
+
+ void SaveBufferPtrs() {
+ int i = 0;
+ for (auto it = buffers_.cbegin(); it != buffers_.cend(); it++) {
+ buffer_ptrs_[i] = it->get();
+ i++;
+ }
+ }
+
+ void VerifyBufferPtrs() {
+ int i = 0;
+ for (auto it = buffers_.cbegin(); it != buffers_.cend(); it++) {
+ EXPECT_EQ(buffer_ptrs_[i], it->get());
+ i++;
+ }
+ }
+
+ void VerifyBuffersDequeued() {
+ AddBuffers();
+ VerifyBufferPtrs();
+ buffers_.clear();
+ }
+
+ void ResetWriteCallback() {
+ callback_fired_ = false;
+ rv_ = 0;
+ }
+
+ void OnWriteComplete(int rv) {
+ callback_fired_ = true;
+ rv_ = rv;
+ }
+
+ int WriteAsync(int i) {
+ return socket_.WriteAsync(msgs_[i].data(), lengths_[i], write_callback_,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ }
+
+ void ExpectSend(int i) {
+ EXPECT_CALL(*socket_.sender(), Send(_, _, lengths_[i], _))
+ .WillOnce(Return(lengths_[i]));
+ }
+
+ void ExpectSendWillBlock(int i) {
+ EXPECT_CALL(*socket_.sender(), Send(_, _, lengths_[i], _))
+ .WillOnce(InvokeWithoutArgs(SetWouldBlock));
+ EXPECT_CALL(socket_, InternalWatchFileDescriptor()).WillOnce(Return(true));
+ }
+
+ void ExpectSendWillError(int i) {
+ EXPECT_CALL(*socket_.sender(), Send(_, _, lengths_[i], _))
+ .WillOnce(InvokeWithoutArgs(SetInvalidHandle));
+ }
+
+ void ExpectSends() {
+ InSequence dummy;
+ for (size_t i = 0; i < kNumMsgs; i++) {
+ ExpectSend(static_cast<int>(i));
+ }
+ }
+
+ void ExpectSendmmsg() {
+ EXPECT_CALL(*socket_.sender(), Sendmmsg(_, _, kNumMsgs, _))
+ .WillOnce(Return(kNumMsgs));
+ }
+
+ TestNetLog client_log_;
+ MockUDPSocketPosix socket_;
+ DatagramBuffers buffers_;
+ bool callback_fired_;
+ int rv_;
+ std::string msgs_[kNumMsgs] = {kHelloMsg, kSecondMsg, kThirdMsg};
+ int lengths_[kNumMsgs] = {kHelloMsg.length(), kSecondMsg.length(),
+ kThirdMsg.length()};
+ int total_lengths_ =
+ kHelloMsg.length() + kSecondMsg.length() + kThirdMsg.length();
+ DatagramBuffer* buffer_ptrs_[kNumMsgs];
+ CompletionCallback write_callback_;
+#if HAVE_SENDMMSG
+ struct iovec msg_iov_[kNumMsgs];
+ struct mmsghdr msgvec_[kNumMsgs];
+#endif
+ base::WeakPtrFactory<UDPSocketPosixTest> weak_factory_;
+};
+
+TEST_F(UDPSocketPosixTest, InternalSendBuffers) {
+ AddBuffers();
+ ExpectSends();
+ SendResult result = socket_.sender()->SendBuffers(1, std::move(buffers_));
+ DatagramBuffers& buffers = result.buffers;
+ EXPECT_EQ(0, result.rv);
+ EXPECT_EQ(3, result.write_count);
+ EXPECT_EQ(kNumMsgs, buffers.size());
+}
+
+TEST_F(UDPSocketPosixTest, InternalSendBuffersWriteError) {
+ AddBuffers();
+ {
+ InSequence dummy;
+ EXPECT_CALL(*socket_.sender(), Send(_, _, lengths_[0], _))
+ .WillOnce(Return(lengths_[0]));
+ EXPECT_CALL(*socket_.sender(), Send(_, _, lengths_[1], _))
+ .WillOnce(InvokeWithoutArgs(SetWouldBlock));
+ }
+ SendResult result = socket_.sender()->SendBuffers(1, std::move(buffers_));
+ DatagramBuffers& buffers = result.buffers;
+ EXPECT_EQ(ERR_IO_PENDING, result.rv);
+ EXPECT_EQ(1, result.write_count);
+ EXPECT_EQ(kNumMsgs, buffers.size());
+}
+
+#if HAVE_SENDMMSG
+
+TEST_F(UDPSocketPosixTest, InternalSendmmsgBuffers) {
+ AddBuffers();
+ ExpectSendmmsg();
+ SendResult result =
+ socket_.sender()->InternalSendmmsgBuffers(1, std::move(buffers_));
+ DatagramBuffers& buffers = result.buffers;
+ EXPECT_EQ(0, result.rv);
+ EXPECT_EQ(3, result.write_count);
+ EXPECT_EQ(kNumMsgs, buffers.size());
+}
+
+TEST_F(UDPSocketPosixTest, InternalSendmmsgBuffersWriteShort) {
+ AddBuffers();
+ EXPECT_CALL(*socket_.sender(), Sendmmsg(_, _, kNumMsgs, _))
+ .WillOnce(Return(1));
+ SendResult result =
+ socket_.sender()->InternalSendmmsgBuffers(1, std::move(buffers_));
+ DatagramBuffers& buffers = result.buffers;
+ EXPECT_EQ(0, result.rv);
+ EXPECT_EQ(1, result.write_count);
+ EXPECT_EQ(kNumMsgs, buffers.size());
+}
+
+TEST_F(UDPSocketPosixTest, InternalSendmmsgBuffersWriteError) {
+ AddBuffers();
+ EXPECT_CALL(*socket_.sender(), Sendmmsg(_, _, kNumMsgs, _))
+ .WillOnce(InvokeWithoutArgs(SetWouldBlock));
+ SendResult result =
+ socket_.sender()->InternalSendmmsgBuffers(1, std::move(buffers_));
+ DatagramBuffers& buffers = result.buffers;
+ EXPECT_EQ(ERR_IO_PENDING, result.rv);
+ EXPECT_EQ(0, result.write_count);
+ EXPECT_EQ(kNumMsgs, buffers.size());
+}
+
+TEST_F(UDPSocketPosixTest, SendInternalSend) {
+ AddBuffers();
+ ExpectSends();
+ SendResult result = socket_.sender()->SendBuffers(1, std::move(buffers_));
+ EXPECT_EQ(0, result.rv);
+ EXPECT_EQ(3, result.write_count);
+ EXPECT_EQ(kNumMsgs, result.buffers.size());
+}
+
+TEST_F(UDPSocketPosixTest, SendInternalSendmmsg) {
+ socket_.sender()->SetSendmmsgEnabled(true);
+ AddBuffers();
+ ExpectSendmmsg();
+ SendResult result = socket_.sender()->SendBuffers(1, std::move(buffers_));
+ EXPECT_EQ(0, result.rv);
+ EXPECT_EQ(3, result.write_count);
+ EXPECT_EQ(kNumMsgs, result.buffers.size());
+}
+
+TEST_F(UDPSocketPosixTest, SendInternalSendmmsgFallback) {
+ socket_.sender()->SetSendmmsgEnabled(true);
+ AddBuffers();
+ {
+ InSequence dummy;
+ EXPECT_CALL(*socket_.sender(), Sendmmsg(_, _, kNumMsgs, _))
+ .WillOnce(InvokeWithoutArgs(SetNotImplemented));
+ ExpectSends();
+ }
+ SendResult result = socket_.sender()->SendBuffers(1, std::move(buffers_));
+ EXPECT_EQ(0, result.rv);
+ EXPECT_EQ(3, result.write_count);
+ EXPECT_EQ(kNumMsgs, result.buffers.size());
+}
+
+#endif // HAVE_SENDMMSG
+
+TEST_F(UDPSocketPosixTest, DidSendBuffers) {
+ AddBuffers();
+ SaveBufferPtrs();
+ SendResult send_result(0, kNumMsgs, std::move(buffers_));
+ socket_.DidSendBuffers(std::move(send_result));
+ EXPECT_EQ(0u, socket_.GetUnwrittenBuffers().size());
+ VerifyBuffersDequeued();
+ TestNetLogEntry::List client_entries;
+ client_log_.GetEntries(&client_entries);
+ EXPECT_EQ(4u, client_entries.size());
+ EXPECT_TRUE(
+ LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 1,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 2,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 3,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_FALSE(callback_fired_);
+}
+
+TEST_F(UDPSocketPosixTest, DidSendBuffersAsync) {
+ AddBuffers();
+ SendResult send_result(0, kNumMsgs, std::move(buffers_));
+ ResetWriteCallback();
+ socket_.SetWriteCallback(write_callback_);
+ socket_.DidSendBuffers(std::move(send_result));
+ EXPECT_EQ(0u, socket_.GetUnwrittenBuffers().size());
+ TestNetLogEntry::List client_entries;
+ client_log_.GetEntries(&client_entries);
+ EXPECT_EQ(4u, client_entries.size());
+ EXPECT_TRUE(
+ LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 1,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 2,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 3,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(callback_fired_);
+ EXPECT_EQ(rv_, total_lengths_);
+}
+
+TEST_F(UDPSocketPosixTest, DidSendBuffersError) {
+ AddBuffers();
+ SendResult send_result(ERR_INVALID_HANDLE, 1, std::move(buffers_));
+ ResetWriteCallback();
+ socket_.SetWriteCallback(write_callback_);
+ socket_.DidSendBuffers(std::move(send_result));
+ EXPECT_EQ(2u, socket_.GetUnwrittenBuffers().size());
+ TestNetLogEntry::List client_entries;
+ client_log_.GetEntries(&client_entries);
+ EXPECT_EQ(2u, client_entries.size());
+ EXPECT_TRUE(
+ LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 1,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(callback_fired_);
+ EXPECT_EQ(rv_, ERR_INVALID_HANDLE);
+}
+
+TEST_F(UDPSocketPosixTest, DidSendBuffersShort) {
+ AddBuffers();
+ SendResult send_result(0, 1, std::move(buffers_));
+ ResetWriteCallback();
+ socket_.SetWriteCallback(write_callback_);
+ socket_.DidSendBuffers(std::move(send_result));
+ EXPECT_EQ(2u, socket_.GetUnwrittenBuffers().size());
+ TestNetLogEntry::List client_entries;
+ client_log_.GetEntries(&client_entries);
+ EXPECT_EQ(2u, client_entries.size());
+ EXPECT_TRUE(
+ LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 1,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(callback_fired_);
+ EXPECT_EQ(rv_, lengths_[0]);
+}
+
+TEST_F(UDPSocketPosixTest, DidSendBuffersPending) {
+ AddBuffers();
+ SendResult send_result(ERR_IO_PENDING, 1, std::move(buffers_));
+ ResetWriteCallback();
+ socket_.SetWriteCallback(write_callback_);
+ EXPECT_CALL(socket_, InternalWatchFileDescriptor()).WillOnce(Return(true));
+ socket_.DidSendBuffers(std::move(send_result));
+ EXPECT_EQ(2u, socket_.GetUnwrittenBuffers().size());
+ TestNetLogEntry::List client_entries;
+ client_log_.GetEntries(&client_entries);
+ EXPECT_EQ(2u, client_entries.size());
+ EXPECT_TRUE(
+ LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 1,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(callback_fired_);
+ EXPECT_EQ(rv_, lengths_[0]);
+}
+
+TEST_F(UDPSocketPosixTest, DidSendBuffersWatchError) {
+ AddBuffers();
+ SendResult send_result(ERR_IO_PENDING, 1, std::move(buffers_));
+ ResetWriteCallback();
+ socket_.SetWriteCallback(write_callback_);
+ EXPECT_CALL(socket_, InternalWatchFileDescriptor())
+ .WillOnce(InvokeWithoutArgs(WatcherSetInvalidHandle));
+ socket_.DidSendBuffers(std::move(send_result));
+ EXPECT_EQ(2u, socket_.GetUnwrittenBuffers().size());
+ TestNetLogEntry::List client_entries;
+ client_log_.GetEntries(&client_entries);
+ EXPECT_EQ(3u, client_entries.size());
+ EXPECT_TRUE(
+ LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 1,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 2,
+ NetLogEventType::UDP_SEND_ERROR,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(callback_fired_);
+ EXPECT_EQ(rv_, ERR_INVALID_HANDLE);
+}
+
+TEST_F(UDPSocketPosixTest, DidSendBuffersStopWatch) {
+ AddBuffers();
+ SendResult send_result(ERR_IO_PENDING, 1, std::move(buffers_));
+ ResetWriteCallback();
+ socket_.SetWriteCallback(write_callback_);
+ EXPECT_CALL(socket_, InternalWatchFileDescriptor()).WillOnce(Return(true));
+ socket_.DidSendBuffers(std::move(send_result));
+ buffers_ = socket_.GetUnwrittenBuffers();
+ EXPECT_EQ(2u, buffers_.size());
+ TestNetLogEntry::List client_entries;
+ client_log_.GetEntries(&client_entries);
+ EXPECT_EQ(2u, client_entries.size());
+ EXPECT_TRUE(
+ LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 1,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(callback_fired_);
+ EXPECT_EQ(rv_, lengths_[0]);
+
+ SendResult send_result2(0, 2, std::move(buffers_));
+ ResetWriteCallback();
+ socket_.SetWriteCallback(write_callback_);
+ EXPECT_CALL(socket_, InternalStopWatchingFileDescriptor());
+
+ socket_.DidSendBuffers(std::move(send_result2));
+
+ EXPECT_EQ(0u, socket_.GetUnwrittenBuffers().size());
+ client_log_.GetEntries(&client_entries);
+ EXPECT_EQ(4u, client_entries.size());
+ EXPECT_TRUE(
+ LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 1,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 2,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 3,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(callback_fired_);
+ EXPECT_EQ(rv_, lengths_[1] + lengths_[2]);
+}
+
+TEST_F(UDPSocketPosixTest, DidSendBuffersErrorStopWatch) {
+ AddBuffers();
+ SendResult send_result(ERR_IO_PENDING, 1, std::move(buffers_));
+ ResetWriteCallback();
+ socket_.SetWriteCallback(write_callback_);
+ EXPECT_CALL(socket_, InternalWatchFileDescriptor()).WillOnce(Return(true));
+ socket_.DidSendBuffers(std::move(send_result));
+ buffers_ = socket_.GetUnwrittenBuffers();
+ EXPECT_EQ(2u, buffers_.size());
+ TestNetLogEntry::List client_entries;
+ client_log_.GetEntries(&client_entries);
+ EXPECT_EQ(2u, client_entries.size());
+ EXPECT_TRUE(
+ LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 1,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(callback_fired_);
+ EXPECT_EQ(rv_, lengths_[0]);
+
+ SendResult send_result2(ERR_INVALID_HANDLE, 0, std::move(buffers_));
+ ResetWriteCallback();
+ socket_.SetWriteCallback(write_callback_);
+ EXPECT_CALL(socket_, InternalStopWatchingFileDescriptor());
+
+ socket_.DidSendBuffers(std::move(send_result2));
+
+ EXPECT_EQ(2u, socket_.GetUnwrittenBuffers().size());
+ client_log_.GetEntries(&client_entries);
+ EXPECT_EQ(2u, client_entries.size());
+ EXPECT_TRUE(
+ LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 1,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(callback_fired_);
+ EXPECT_EQ(rv_, ERR_INVALID_HANDLE);
+}
+
+TEST_F(UDPSocketPosixTest, DidSendBuffersDelayCallbackWhileTooManyBuffers) {
+ for (int i = 0; i < kWriteAsyncCallbackBuffersThreshold + 2; i++) {
+ AddBuffer(msgs_[0]);
+ }
+ SendResult send_result(0, 2, std::move(buffers_));
+ ResetWriteCallback();
+ socket_.SetWriteCallback(write_callback_);
+ socket_.DidSendBuffers(std::move(send_result));
+ TestNetLogEntry::List client_entries;
+ client_log_.GetEntries(&client_entries);
+ EXPECT_EQ(3u, client_entries.size());
+ EXPECT_TRUE(
+ LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 1,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ EXPECT_TRUE(LogContainsEvent(client_entries, 2,
+ NetLogEventType::UDP_BYTES_SENT,
+ NetLogEventPhase::NONE));
+ // bytes written but no callback because socket_.pending_writes_ is full.
+ EXPECT_FALSE(callback_fired_);
+
+ // now the rest
+ buffers_ = socket_.GetUnwrittenBuffers();
+ EXPECT_EQ(kWriteAsyncCallbackBuffersThreshold,
+ static_cast<int>(buffers_.size()));
+ SendResult send_result2(0, buffers_.size(), std::move(buffers_));
+ ResetWriteCallback();
+ socket_.SetWriteCallback(write_callback_);
+ socket_.DidSendBuffers(std::move(send_result2));
+ EXPECT_TRUE(callback_fired_);
+ // rv includes bytes from previous invocation.
+ EXPECT_EQ(rv_, (kWriteAsyncCallbackBuffersThreshold + 2) * lengths_[0]);
+}
+
+TEST_F(UDPSocketPosixTest, FlushPendingLocal) {
+ socket_.SetWriteMultiCoreEnabled(false);
+ AddBuffers();
+ ExpectSends();
+ socket_.SetPendingWrites(std::move(buffers_));
+ ResetWriteCallback();
+ socket_.SetWriteCallback(write_callback_);
+ socket_.FlushPending();
+ EXPECT_TRUE(callback_fired_);
+ EXPECT_EQ(rv_, total_lengths_);
+}
+
+TEST_F(UDPSocketPosixTest, FlushPendingMultiCore) {
+ socket_.SetWriteMultiCoreEnabled(true);
+ AddBuffers();
+ ExpectSends();
+ socket_.SetPendingWrites(std::move(buffers_));
+ ResetWriteCallback();
+ socket_.SetWriteCallback(write_callback_);
+ socket_.FlushPending();
+ EXPECT_FALSE(callback_fired_);
+ RunUntilIdle();
+ EXPECT_TRUE(callback_fired_);
+ EXPECT_EQ(rv_, total_lengths_);
+}
+
+TEST_F(UDPSocketPosixTest, WriteAsyncNoBatching) {
+ socket_.SetWriteBatchingActive(false);
+ socket_.SetWriteMultiCoreEnabled(true);
+ DatagramBuffers buffers;
+ ExpectSend(0);
+ int rv = WriteAsync(0);
+ EXPECT_EQ(lengths_[0], rv);
+ ExpectSend(1);
+ rv = WriteAsync(1);
+ EXPECT_EQ(lengths_[1], rv);
+ ExpectSend(2);
+ rv = WriteAsync(2);
+ EXPECT_EQ(lengths_[2], rv);
+}
+
+TEST_F(UDPSocketPosixTest, WriteAsyncNoBatchingErrIOPending) {
+ socket_.SetWriteBatchingActive(false);
+ socket_.SetWriteMultiCoreEnabled(true);
+ DatagramBuffers buffers;
+ ExpectSend(0);
+ int rv = WriteAsync(0);
+ EXPECT_EQ(lengths_[0], rv);
+ ExpectSendWillBlock(1);
+ rv = WriteAsync(1);
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_CALL(socket_, InternalStopWatchingFileDescriptor());
+ ExpectSend(1);
+ socket_.OnFileCanWriteWithoutBlocking();
+ EXPECT_TRUE(callback_fired_);
+ EXPECT_EQ(rv_, lengths_[1]);
+}
+
+TEST_F(UDPSocketPosixTest, WriteAsyncNoBatchingError) {
+ socket_.SetWriteBatchingActive(false);
+ socket_.SetWriteMultiCoreEnabled(true);
+ DatagramBuffers buffers;
+ ExpectSend(0);
+ int rv = WriteAsync(0);
+ EXPECT_EQ(lengths_[0], rv);
+ ExpectSendWillError(1);
+ rv = WriteAsync(1);
+ EXPECT_EQ(ERR_INVALID_HANDLE, rv);
+}
+
+TEST_F(UDPSocketPosixTest, WriteAsyncBasicDelay) {
+ socket_.SetWriteBatchingActive(true);
+ socket_.SetWriteMultiCoreEnabled(true);
+ DatagramBuffers buffers;
+ ASSERT_LT(kWriteAsyncMinBuffersThreshold, 3);
+ ASSERT_GT(kWriteAsyncPostBuffersThreshold, 3);
+ int rv = WriteAsync(0);
+ EXPECT_EQ(0, rv);
+ rv = WriteAsync(1);
+ EXPECT_EQ(0, rv);
+ rv = WriteAsync(2);
+ EXPECT_EQ(0, rv);
+ // Cause the write async timer to fire and above writes to flush.
+ ExpectSends();
+ FastForwardBy(kWriteAsyncMsThreshold);
+ RunUntilIdle();
+ rv = WriteAsync(0);
+ EXPECT_EQ(total_lengths_, rv);
+}
+
+TEST_F(UDPSocketPosixTest, WriteAsyncPostBuffersThresholdLocal) {
+ socket_.SetWriteBatchingActive(true);
+ socket_.SetWriteMultiCoreEnabled(false);
+ DatagramBuffers buffers;
+ int rv = 0;
+ for (int i = 0; i < kWriteAsyncPostBuffersThreshold - 1; i++) {
+ WriteAsync(0);
+ EXPECT_EQ(0, rv);
+ }
+ EXPECT_CALL(*socket_.sender(), Send(_, _, lengths_[0], _))
+ .Times(kWriteAsyncPostBuffersThreshold)
+ .WillRepeatedly(Return(lengths_[0]));
+ rv = WriteAsync(0);
+ EXPECT_EQ(kWriteAsyncPostBuffersThreshold * lengths_[0], rv);
+}
+
+TEST_F(UDPSocketPosixTest, WriteAsyncPostBuffersThresholdRemote) {
+ socket_.SetWriteBatchingActive(true);
+ socket_.SetWriteMultiCoreEnabled(true);
+ EXPECT_CALL(*socket_.sender(), Send(_, _, lengths_[0], _))
+ .Times(kWriteAsyncPostBuffersThreshold)
+ .WillRepeatedly(Return(lengths_[0]));
+ DatagramBuffers buffers;
+ int rv = 0;
+ for (int i = 0; i < kWriteAsyncPostBuffersThreshold; i++) {
+ WriteAsync(0);
+ EXPECT_EQ(0, rv);
+ }
+ RunUntilIdle();
+ rv = WriteAsync(0);
+ EXPECT_EQ(kWriteAsyncPostBuffersThreshold * lengths_[0], rv);
+}
+
+TEST_F(UDPSocketPosixTest, WriteAsyncPostBlocks) {
+ socket_.SetWriteBatchingActive(true);
+ socket_.SetWriteMultiCoreEnabled(true);
+ DatagramBuffers buffers;
+ for (int i = 0; i < kWriteAsyncMaxBuffersThreshold; i++) {
+ socket_.Enqueue(msgs_[0], &buffers_);
+ }
+ EXPECT_CALL(*socket_.sender(), Send(_, _, lengths_[0], _))
+ .Times(kWriteAsyncMaxBuffersThreshold)
+ .WillRepeatedly(Return(lengths_[0]));
+ int rv = socket_.WriteAsync(std::move(buffers_), write_callback_,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_FALSE(callback_fired_);
+ RunUntilIdle();
+ EXPECT_TRUE(callback_fired_);
+ EXPECT_EQ(rv_, kWriteAsyncMaxBuffersThreshold * lengths_[0]);
+}
+
+} // namespace test
+
+} // namespace net
diff --git a/chromium/net/socket/udp_socket_unittest.cc b/chromium/net/socket/udp_socket_unittest.cc
index de483878517..af389318217 100644
--- a/chromium/net/socket/udp_socket_unittest.cc
+++ b/chromium/net/socket/udp_socket_unittest.cc
@@ -4,11 +4,12 @@
#include "net/socket/udp_socket.h"
+#include <algorithm>
+
#include "base/bind.h"
#include "base/containers/circular_deque.h"
#include "base/location.h"
#include "base/macros.h"
-#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
@@ -46,6 +47,7 @@
using net::test::IsError;
using net::test::IsOk;
+using testing::Not;
namespace net {
@@ -152,9 +154,8 @@ void UDPSocketTest::ConnectTest(bool use_nonblocking_io) {
// Setup the client.
TestNetLog client_log;
- std::unique_ptr<UDPClientSocket> client(
- new UDPClientSocket(DatagramSocket::DEFAULT_BIND, RandIntCallback(),
- &client_log, NetLogSource()));
+ auto client = std::make_unique<UDPClientSocket>(DatagramSocket::DEFAULT_BIND,
+ &client_log, NetLogSource());
if (use_nonblocking_io)
client->UseNonBlockingIO();
@@ -257,8 +258,8 @@ TEST_F(UDPSocketTest, PartialRecv) {
IPEndPoint server_address;
ASSERT_THAT(server_socket.GetLocalAddress(&server_address), IsOk());
- UDPClientSocket client_socket(DatagramSocket::DEFAULT_BIND, RandIntCallback(),
- nullptr, NetLogSource());
+ UDPClientSocket client_socket(DatagramSocket::DEFAULT_BIND, nullptr,
+ NetLogSource());
ASSERT_THAT(client_socket.Connect(server_address), IsOk());
std::string test_packet("hello world!");
@@ -337,106 +338,82 @@ TEST_F(UDPSocketTest, MAYBE_LocalBroadcast) {
ASSERT_EQ(second_message, str);
}
-// In this test, we verify that random binding logic works, which attempts
-// to bind to a random port and returns if succeeds, otherwise retries for
-// |kBindRetries| number of times.
-
-// To generate the scenario, we first create |kBindRetries| number of
-// UDPClientSockets with default binding policy and connect to the same
-// peer and save the used port numbers. Then we get rid of the last
-// socket, making sure that the local port it was bound to is available.
-// Finally, we create a socket with random binding policy, passing it a
-// test PRNG that would serve used port numbers in the array, one after
-// another. At the end, we make sure that the test socket was bound to the
-// port that became available after deleting the last socket with default
-// binding policy.
-
-// We do not test the randomness of bound ports, but that we are using
-// passed in PRNG correctly, thus, it's the duty of PRNG to produce strong
-// random numbers.
-static const int kBindRetries = 10;
-
-class TestPrng {
- public:
- explicit TestPrng(const base::circular_deque<int>& numbers)
- : numbers_(numbers) {}
- int GetNext(int /* min */, int /* max */) {
- DCHECK(!numbers_.empty());
- int rv = numbers_.front();
- numbers_.pop_front();
- return rv;
- }
- private:
- base::circular_deque<int> numbers_;
-
- DISALLOW_COPY_AND_ASSIGN(TestPrng);
-};
-
-TEST_F(UDPSocketTest, ConnectRandomBind) {
- std::vector<std::unique_ptr<UDPClientSocket>> sockets;
- IPEndPoint peer_address(IPAddress::IPv4Localhost(), 53);
+// ConnectRandomBind verifies RANDOM_BIND is handled correctly. It connects
+// 1000 sockets and then verifies that the allocated port numbers satisfy the
+// following 2 conditions:
+// 1. Range from min port value to max is greater than 10000.
+// 2. There is at least one port in the 5 buckets in the [min, max] range.
+//
+// These conditions are not enough to verify that the port numbers are truly
+// random, but they are enough to protect from most common non-random port
+// allocation strategies (e.g. counter, pool of available ports, etc.) False
+// positive result is theoretically possible, but its probability is negligible.
+//
+// Sometimes times outs on Fuchsia on bots. https://crbug.com/826952
+#if defined(OS_FUCHSIA)
+#define MAYBE_ConnectRandomBind DISABLED_ConnectRandomBind
+#else
+#define MAYBE_ConnectRandomBind ConnectRandomBind
+#endif
+TEST_F(UDPSocketTest, MAYBE_ConnectRandomBind) {
+ const int kIterations = 1000;
- // Create and connect sockets and save port numbers.
- base::circular_deque<int> used_ports;
- for (int i = 0; i < kBindRetries; ++i) {
- UDPClientSocket* socket = new UDPClientSocket(
- DatagramSocket::DEFAULT_BIND, RandIntCallback(), NULL, NetLogSource());
- sockets.push_back(base::WrapUnique(socket));
- EXPECT_THAT(socket->Connect(peer_address), IsOk());
+ std::vector<int> used_ports;
+ for (int i = 0; i < kIterations; ++i) {
+ UDPClientSocket socket(DatagramSocket::RANDOM_BIND, nullptr,
+ NetLogSource());
+ EXPECT_THAT(socket.Connect(IPEndPoint(IPAddress::IPv4Localhost(), 53)),
+ IsOk());
IPEndPoint client_address;
- EXPECT_THAT(socket->GetLocalAddress(&client_address), IsOk());
+ EXPECT_THAT(socket.GetLocalAddress(&client_address), IsOk());
used_ports.push_back(client_address.port());
}
- // Free the last socket, its local port is still in |used_ports|.
- sockets.pop_back();
-
- TestPrng test_prng(used_ports);
- RandIntCallback rand_int_cb =
- base::Bind(&TestPrng::GetNext, base::Unretained(&test_prng));
-
- // Create a socket with random binding policy and connect.
- std::unique_ptr<UDPClientSocket> test_socket(new UDPClientSocket(
- DatagramSocket::RANDOM_BIND, rand_int_cb, NULL, NetLogSource()));
- EXPECT_THAT(test_socket->Connect(peer_address), IsOk());
-
- // Make sure that the last port number in the |used_ports| was used.
- IPEndPoint client_address;
- EXPECT_THAT(test_socket->GetLocalAddress(&client_address), IsOk());
- EXPECT_EQ(used_ports.back(), client_address.port());
-}
+ int min_port = *std::min_element(used_ports.begin(), used_ports.end());
+ int max_port = *std::max_element(used_ports.begin(), used_ports.end());
+ int range = max_port - min_port + 1;
+
+ // Verify that the range of ports used by the random port allocator is wider
+ // than 10k. Assuming that socket implementation limits port range to 16k
+ // ports (default on Fuchsia) probability of false negative is below
+ // 10^-200.
+ static int kMinRange = 10000;
+ EXPECT_GT(range, kMinRange);
+
+ static int kBuckets = 5;
+ std::vector<int> bucket_sizes(kBuckets, 0);
+ for (int port : used_ports) {
+ bucket_sizes[(port - min_port) * kBuckets / range] += 1;
+ }
-// Return a privileged port (under 1024) so binding will fail.
-int PrivilegedRand(int min, int max) {
- // Chosen by fair dice roll. Guaranteed to be random.
- return 4;
+ // Verify that there is at least one value in each bucket. Probability of
+ // false negative is below (kBuckets * (1 - 1 / kBuckets) ^ kIterations),
+ // which is less than 10^-96.
+ for (int size : bucket_sizes) {
+ EXPECT_GT(size, 0);
+ }
}
-#if defined(OS_IOS) && !TARGET_IPHONE_SIMULATOR || defined(OS_FUCHSIA)
-// On iOS this test fails on device (but passes on simulator). See
-// http://crbug.com/227760.
-//
-// On Fuchsia the tests run in an emulator and have permissions to bind to
-// privileged ports.
+#if defined(OS_FUCHSIA)
+// Currently the test fails on Fuchsia because netstack allows to connect IPv4
+// socket to IPv6 address. This issue is tracked by NET-596.
#define MAYBE_ConnectFail DISABLED_ConnectFail
#else
#define MAYBE_ConnectFail ConnectFail
#endif
TEST_F(UDPSocketTest, MAYBE_ConnectFail) {
- IPEndPoint peer_address;
- CreateUDPAddress("0.0.0.0", 53, &peer_address);
+ UDPSocket socket(DatagramSocket::DEFAULT_BIND, nullptr, NetLogSource());
+
+ EXPECT_THAT(socket.Open(ADDRESS_FAMILY_IPV4), IsOk());
+
+ // Connect to an IPv6 address should fail since the socket was created for
+ // IPv4.
+ EXPECT_THAT(socket.Connect(net::IPEndPoint(IPAddress::IPv6Localhost(), 53)),
+ Not(IsOk()));
- std::unique_ptr<UDPSocket> socket(new UDPSocket(DatagramSocket::RANDOM_BIND,
- base::Bind(&PrivilegedRand),
- NULL, NetLogSource()));
- int rv = socket->Open(peer_address.GetFamily());
- EXPECT_THAT(rv, IsOk());
- rv = socket->Connect(peer_address);
- // Connect should have failed since we couldn't bind to that port,
- EXPECT_NE(OK, rv);
// Make sure that UDPSocket actually closed the socket.
- EXPECT_FALSE(socket->is_connected());
+ EXPECT_FALSE(socket.is_connected());
}
// In this test, we verify that connect() on a socket will have the effect
@@ -455,21 +432,20 @@ TEST_F(UDPSocketTest, VerifyConnectBindsAddr) {
// Setup the first server to listen.
IPEndPoint server1_address(IPAddress::IPv4Localhost(), kPort1);
- UDPServerSocket server1(NULL, NetLogSource());
+ UDPServerSocket server1(nullptr, NetLogSource());
server1.AllowAddressReuse();
int rv = server1.Listen(server1_address);
ASSERT_THAT(rv, IsOk());
// Setup the second server to listen.
IPEndPoint server2_address(IPAddress::IPv4Localhost(), kPort2);
- UDPServerSocket server2(NULL, NetLogSource());
+ UDPServerSocket server2(nullptr, NetLogSource());
server2.AllowAddressReuse();
rv = server2.Listen(server2_address);
ASSERT_THAT(rv, IsOk());
// Setup the client, connected to server 1.
- UDPClientSocket client(DatagramSocket::DEFAULT_BIND, RandIntCallback(), NULL,
- NetLogSource());
+ UDPClientSocket client(DatagramSocket::DEFAULT_BIND, nullptr, NetLogSource());
rv = client.Connect(server1_address);
EXPECT_THAT(rv, IsOk());
@@ -526,8 +502,8 @@ TEST_F(UDPSocketTest, ClientGetLocalPeerAddresses) {
EXPECT_TRUE(ip_address.AssignFromIPLiteral(tests[i].local_address));
IPEndPoint local_address(ip_address, 80);
- UDPClientSocket client(DatagramSocket::DEFAULT_BIND, RandIntCallback(),
- NULL, NetLogSource());
+ UDPClientSocket client(DatagramSocket::DEFAULT_BIND, nullptr,
+ NetLogSource());
int rv = client.Connect(remote_address);
if (tests[i].may_fail && rv == ERR_ADDRESS_UNREACHABLE) {
// Connect() may return ERR_ADDRESS_UNREACHABLE for IPv6
@@ -583,8 +559,8 @@ TEST_F(UDPSocketTest, ServerGetPeerAddress) {
TEST_F(UDPSocketTest, ClientSetDoNotFragment) {
for (std::string ip : {"127.0.0.1", "::1"}) {
- UDPClientSocket client(DatagramSocket::DEFAULT_BIND, RandIntCallback(),
- nullptr, NetLogSource());
+ UDPClientSocket client(DatagramSocket::DEFAULT_BIND, nullptr,
+ NetLogSource());
IPAddress ip_address;
EXPECT_TRUE(ip_address.AssignFromIPLiteral(ip));
IPEndPoint remote_address(ip_address, 80);
@@ -659,8 +635,7 @@ TEST_F(UDPSocketTest, MAYBE_JoinMulticastGroup) {
IPAddress group_ip;
EXPECT_TRUE(group_ip.AssignFromIPLiteral(kGroup));
- UDPSocket socket(DatagramSocket::DEFAULT_BIND, RandIntCallback(), NULL,
- NetLogSource());
+ UDPSocket socket(DatagramSocket::DEFAULT_BIND, nullptr, NetLogSource());
EXPECT_THAT(socket.Open(bind_address.GetFamily()), IsOk());
#if defined(OS_FUCHSIA)
@@ -686,8 +661,7 @@ TEST_F(UDPSocketTest, MulticastOptions) {
IPEndPoint bind_address;
CreateUDPAddress("0.0.0.0", kPort, &bind_address);
- UDPSocket socket(DatagramSocket::DEFAULT_BIND, RandIntCallback(), NULL,
- NetLogSource());
+ UDPSocket socket(DatagramSocket::DEFAULT_BIND, nullptr, NetLogSource());
// Before binding.
EXPECT_THAT(socket.SetMulticastLoopbackMode(false), IsOk());
EXPECT_THAT(socket.SetMulticastLoopbackMode(true), IsOk());
@@ -711,8 +685,7 @@ TEST_F(UDPSocketTest, MulticastOptions) {
TEST_F(UDPSocketTest, SetDSCP) {
// Setup the server to listen.
IPEndPoint bind_address;
- UDPSocket client(DatagramSocket::DEFAULT_BIND, RandIntCallback(), NULL,
- NetLogSource());
+ UDPSocket client(DatagramSocket::DEFAULT_BIND, nullptr, NetLogSource());
// We need a real IP, but we won't actually send anything to it.
CreateUDPAddress("8.8.8.8", 9999, &bind_address);
int rv = client.Open(bind_address.GetFamily());
@@ -736,8 +709,7 @@ TEST_F(UDPSocketTest, SetDSCP) {
}
TEST_F(UDPSocketTest, TestBindToNetwork) {
- UDPSocket socket(DatagramSocket::RANDOM_BIND, base::Bind(&PrivilegedRand),
- NULL, NetLogSource());
+ UDPSocket socket(DatagramSocket::RANDOM_BIND, nullptr, NetLogSource());
#if defined(OS_ANDROID)
NetworkChangeNotifierFactoryAndroid ncn_factory;
NetworkChangeNotifier::DisableForTest ncn_disable_for_test;
@@ -870,8 +842,7 @@ TEST_F(UDPSocketTest, SetDSCPFake) {
IPEndPoint bind_address;
// We need a real IP, but we won't actually send anything to it.
CreateUDPAddress("8.8.8.8", 9999, &bind_address);
- UDPSocket client(DatagramSocket::DEFAULT_BIND, RandIntCallback(), NULL,
- NetLogSource());
+ UDPSocket client(DatagramSocket::DEFAULT_BIND, nullptr, NetLogSource());
int rv = client.SetDiffServCodePoint(DSCP_AF41);
EXPECT_THAT(rv, IsError(ERR_SOCKET_NOT_CONNECTED));
@@ -924,8 +895,7 @@ TEST_F(UDPSocketTest, ReadWithSocketOptimization) {
// Setup the client, enable experimental optimization and connected to the
// server.
- UDPClientSocket client(DatagramSocket::DEFAULT_BIND, RandIntCallback(), NULL,
- NetLogSource());
+ UDPClientSocket client(DatagramSocket::DEFAULT_BIND, nullptr, NetLogSource());
client.EnableRecvOptimization();
rv = client.Connect(server_address);
EXPECT_THAT(rv, IsOk());
@@ -967,8 +937,7 @@ TEST_F(UDPSocketTest, ReadWithSocketOptimizationTruncation) {
// Setup the client, enable experimental optimization and connected to the
// server.
- UDPClientSocket client(DatagramSocket::DEFAULT_BIND, RandIntCallback(), NULL,
- NetLogSource());
+ UDPClientSocket client(DatagramSocket::DEFAULT_BIND, nullptr, NetLogSource());
client.EnableRecvOptimization();
rv = client.Connect(server_address);
EXPECT_THAT(rv, IsOk());
@@ -1035,8 +1004,7 @@ TEST_F(UDPSocketTest, Tag) {
IPEndPoint server_address;
ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
- UDPClientSocket client(DatagramSocket::DEFAULT_BIND, RandIntCallback(),
- nullptr, NetLogSource());
+ UDPClientSocket client(DatagramSocket::DEFAULT_BIND, nullptr, NetLogSource());
ASSERT_THAT(client.Connect(server_address), IsOk());
// Verify UDP packets are tagged and counted properly.
diff --git a/chromium/net/socket/udp_socket_win.cc b/chromium/net/socket/udp_socket_win.cc
index 7790d6a4176..f4d6f5e3abc 100644
--- a/chromium/net/socket/udp_socket_win.cc
+++ b/chromium/net/socket/udp_socket_win.cc
@@ -246,7 +246,6 @@ BOOL QwaveAPI::SetFlow(HANDLE handle,
//-----------------------------------------------------------------------------
UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
net::NetLog* net_log,
const net::NetLogSource& source)
: socket_(INVALID_SOCKET),
@@ -256,7 +255,6 @@ UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type,
multicast_interface_(0),
multicast_time_to_live_(1),
bind_type_(bind_type),
- rand_int_cb_(rand_int_cb),
use_non_blocking_io_(false),
read_iobuffer_len_(0),
write_iobuffer_len_(0),
@@ -268,8 +266,6 @@ UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type,
EnsureWinsockInit();
net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE,
source.ToEventParametersCallback());
- if (bind_type == DatagramSocket::RANDOM_BIND)
- DCHECK(!rand_int_cb.is_null());
}
UDPSocketWin::~UDPSocketWin() {
@@ -567,6 +563,8 @@ int UDPSocketWin::SetDoNotFragment() {
return rv == 0 ? OK : MapSystemError(WSAGetLastError());
}
+void UDPSocketWin::SetMsgConfirm(bool confirm) {}
+
int UDPSocketWin::AllowAddressReuse() {
DCHECK_NE(socket_, INVALID_SOCKET);
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
@@ -997,11 +995,11 @@ int UDPSocketWin::DoBind(const IPEndPoint& address) {
}
int UDPSocketWin::RandomBind(const IPAddress& address) {
- DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null());
+ DCHECK_EQ(bind_type_, DatagramSocket::RANDOM_BIND);
for (int i = 0; i < kBindRetries; ++i) {
- int rv = DoBind(IPEndPoint(address, static_cast<uint16_t>(rand_int_cb_.Run(
- kPortStart, kPortEnd))));
+ int rv = DoBind(IPEndPoint(
+ address, static_cast<uint16_t>(base::RandInt(kPortStart, kPortEnd))));
if (rv != ERR_ADDRESS_IN_USE)
return rv;
}
@@ -1225,4 +1223,36 @@ void UDPSocketWin::ApplySocketTag(const SocketTag& tag) {
CHECK(tag == SocketTag());
}
+void UDPSocketWin::SetWriteAsyncEnabled(bool enabled) {}
+bool UDPSocketWin::WriteAsyncEnabled() {
+ return false;
+}
+void UDPSocketWin::SetMaxPacketSize(size_t max_packet_size) {}
+void UDPSocketWin::SetWriteMultiCoreEnabled(bool enabled) {}
+void UDPSocketWin::SetSendmmsgEnabled(bool enabled) {}
+void UDPSocketWin::SetWriteBatchingActive(bool active) {}
+
+int UDPSocketWin::WriteAsync(
+ DatagramBuffers buffers,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
+ NOTIMPLEMENTED();
+ return ERR_NOT_IMPLEMENTED;
+}
+
+int UDPSocketWin::WriteAsync(
+ const char* buffer,
+ size_t buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
+ NOTIMPLEMENTED();
+ return ERR_NOT_IMPLEMENTED;
+}
+
+DatagramBuffers UDPSocketWin::GetUnwrittenBuffers() {
+ DatagramBuffers result;
+ NOTIMPLEMENTED();
+ return result;
+}
+
} // namespace net
diff --git a/chromium/net/socket/udp_socket_win.h b/chromium/net/socket/udp_socket_win.h
index 71094d4dbde..df8f901ab30 100644
--- a/chromium/net/socket/udp_socket_win.h
+++ b/chromium/net/socket/udp_socket_win.h
@@ -20,11 +20,11 @@
#include "base/win/scoped_handle.h"
#include "net/base/address_family.h"
#include "net/base/completion_callback.h"
+#include "net/base/datagram_buffer.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_export.h"
#include "net/base/network_change_notifier.h"
-#include "net/base/rand_callback.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/datagram_socket.h"
#include "net/socket/diff_serv_code_point.h"
@@ -40,7 +40,6 @@ class SocketTag;
class NET_EXPORT UDPSocketWin : public base::win::ObjectWatcher::Delegate {
public:
UDPSocketWin(DatagramSocket::BindType bind_type,
- const RandIntCallback& rand_int_cb,
net::NetLog* net_log,
const net::NetLogSource& source);
~UDPSocketWin() override;
@@ -137,6 +136,9 @@ class NET_EXPORT UDPSocketWin : public base::win::ObjectWatcher::Delegate {
// return ERR_IO_PENDING.
int SetDoNotFragment();
+ // This is a no-op on Windows.
+ void SetMsgConfirm(bool confirm);
+
// Returns true if the socket is already connected or bound.
bool is_connected() const { return is_connected_; }
@@ -205,6 +207,23 @@ class NET_EXPORT UDPSocketWin : public base::win::ObjectWatcher::Delegate {
// to switch to non-blocking IO.
void UseNonBlockingIO();
+ void SetWriteAsyncEnabled(bool enabled);
+ bool WriteAsyncEnabled();
+ void SetMaxPacketSize(size_t max_packet_size);
+ void SetWriteMultiCoreEnabled(bool enabled);
+ void SetSendmmsgEnabled(bool enabled);
+ void SetWriteBatchingActive(bool active);
+
+ int WriteAsync(DatagramBuffers buffers,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
+ int WriteAsync(const char* buffer,
+ size_t buf_len,
+ const CompletionCallback& callback,
+ const NetworkTrafficAnnotationTag& traffic_annotation);
+
+ DatagramBuffers GetUnwrittenBuffers();
+
// Apply |tag| to this socket.
void ApplySocketTag(const SocketTag& tag);
@@ -285,9 +304,6 @@ class NET_EXPORT UDPSocketWin : public base::win::ObjectWatcher::Delegate {
// UDPClientSocket, since UDPServerSocket provides Bind.
DatagramSocket::BindType bind_type_;
- // PRNG function for generating port numbers.
- RandIntCallback rand_int_cb_;
-
// These are mutable since they're just cached copies to make
// GetPeerAddress/GetLocalAddress smarter.
mutable std::unique_ptr<IPEndPoint> local_address_;
diff --git a/chromium/net/socket/websocket_endpoint_lock_manager.cc b/chromium/net/socket/websocket_endpoint_lock_manager.cc
index e316bc52acc..b0cce12141a 100644
--- a/chromium/net/socket/websocket_endpoint_lock_manager.cc
+++ b/chromium/net/socket/websocket_endpoint_lock_manager.cc
@@ -22,9 +22,6 @@ namespace {
// See crbug.com/377613.
const int kUnlockDelayInMs = 10;
-base::LazyInstance<WebSocketEndpointLockManager>::Leaky manager_instance =
- LAZY_INSTANCE_INITIALIZER;
-
} // namespace
WebSocketEndpointLockManager::Waiter::~Waiter() {
@@ -34,8 +31,14 @@ WebSocketEndpointLockManager::Waiter::~Waiter() {
}
}
-WebSocketEndpointLockManager* WebSocketEndpointLockManager::GetInstance() {
- return manager_instance.Pointer();
+WebSocketEndpointLockManager::WebSocketEndpointLockManager()
+ : unlock_delay_(base::TimeDelta::FromMilliseconds(kUnlockDelayInMs)),
+ pending_unlock_count_(0),
+ weak_factory_(this) {}
+
+WebSocketEndpointLockManager::~WebSocketEndpointLockManager() {
+ DCHECK_EQ(lock_info_map_.size(), pending_unlock_count_);
+ DCHECK(socket_lock_info_map_.empty());
}
int WebSocketEndpointLockManager::LockEndpoint(const IPEndPoint& endpoint,
@@ -115,15 +118,6 @@ WebSocketEndpointLockManager::LockInfo::LockInfo(const LockInfo& rhs)
DCHECK(!rhs.queue);
}
-WebSocketEndpointLockManager::WebSocketEndpointLockManager()
- : unlock_delay_(base::TimeDelta::FromMilliseconds(kUnlockDelayInMs)),
- pending_unlock_count_(0) {}
-
-WebSocketEndpointLockManager::~WebSocketEndpointLockManager() {
- DCHECK_EQ(lock_info_map_.size(), pending_unlock_count_);
- DCHECK(socket_lock_info_map_.empty());
-}
-
void WebSocketEndpointLockManager::UnlockEndpointAfterDelay(
const IPEndPoint& endpoint) {
DVLOG(3) << "Delaying " << unlock_delay_.InMilliseconds()
@@ -132,7 +126,7 @@ void WebSocketEndpointLockManager::UnlockEndpointAfterDelay(
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::Bind(&WebSocketEndpointLockManager::DelayedUnlockEndpoint,
- base::Unretained(this), endpoint),
+ weak_factory_.GetWeakPtr(), endpoint),
unlock_delay_);
}
diff --git a/chromium/net/socket/websocket_endpoint_lock_manager.h b/chromium/net/socket/websocket_endpoint_lock_manager.h
index 6999b8a7743..3adedfb7e43 100644
--- a/chromium/net/socket/websocket_endpoint_lock_manager.h
+++ b/chromium/net/socket/websocket_endpoint_lock_manager.h
@@ -8,9 +8,9 @@
#include <stddef.h>
#include <map>
+#include <memory>
#include "base/containers/linked_list.h"
-#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/time/time.h"
@@ -49,7 +49,8 @@ class NET_EXPORT_PRIVATE WebSocketEndpointLockManager {
virtual void GotEndpointLock() = 0;
};
- static WebSocketEndpointLockManager* GetInstance();
+ WebSocketEndpointLockManager();
+ ~WebSocketEndpointLockManager();
// Returns OK if lock was acquired immediately, ERR_IO_PENDING if not. If the
// lock was not acquired, then |waiter->GotEndpointLock()| will be called when
@@ -88,8 +89,6 @@ class NET_EXPORT_PRIVATE WebSocketEndpointLockManager {
base::TimeDelta SetUnlockDelayForTesting(base::TimeDelta new_delay);
private:
- friend struct base::LazyInstanceTraitsBase<net::WebSocketEndpointLockManager>;
-
struct LockInfo {
typedef base::LinkedList<Waiter> WaiterQueue;
@@ -122,9 +121,6 @@ class NET_EXPORT_PRIVATE WebSocketEndpointLockManager {
typedef std::map<IPEndPoint, LockInfo> LockInfoMap;
typedef std::map<StreamSocket*, LockInfoMap::iterator> SocketLockInfoMap;
- WebSocketEndpointLockManager();
- ~WebSocketEndpointLockManager();
-
void UnlockEndpointAfterDelay(const IPEndPoint& endpoint);
void DelayedUnlockEndpoint(const IPEndPoint& endpoint);
void EraseSocket(LockInfoMap::iterator lock_info_it);
@@ -146,6 +142,8 @@ class NET_EXPORT_PRIVATE WebSocketEndpointLockManager {
// Number of sockets currently pending unlock.
size_t pending_unlock_count_;
+ base::WeakPtrFactory<WebSocketEndpointLockManager> weak_factory_;
+
DISALLOW_COPY_AND_ASSIGN(WebSocketEndpointLockManager);
};
diff --git a/chromium/net/socket/websocket_endpoint_lock_manager_unittest.cc b/chromium/net/socket/websocket_endpoint_lock_manager_unittest.cc
index c80e780f3c1..4958372d72a 100644
--- a/chromium/net/socket/websocket_endpoint_lock_manager_unittest.cc
+++ b/chromium/net/socket/websocket_endpoint_lock_manager_unittest.cc
@@ -134,50 +134,50 @@ class BlockingWaiter : public FakeWaiter {
class WebSocketEndpointLockManagerTest : public ::testing::Test {
protected:
- WebSocketEndpointLockManagerTest()
- : instance_(WebSocketEndpointLockManager::GetInstance()) {}
+ WebSocketEndpointLockManagerTest() {
+ websocket_endpoint_lock_manager_.SetUnlockDelayForTesting(
+ base::TimeDelta());
+ }
+
~WebSocketEndpointLockManagerTest() override {
// Permit any pending asynchronous unlock operations to complete.
RunUntilIdle();
// If this check fails then subsequent tests may fail.
- CHECK(instance_->IsEmpty());
+ CHECK(websocket_endpoint_lock_manager_.IsEmpty());
}
- WebSocketEndpointLockManager* instance() const { return instance_; }
-
IPEndPoint DummyEndpoint() {
return IPEndPoint(IPAddress::IPv4Localhost(), 80);
}
void UnlockDummyEndpoint(int times) {
for (int i = 0; i < times; ++i) {
- instance()->UnlockEndpoint(DummyEndpoint());
+ websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
RunUntilIdle();
}
}
static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
- WebSocketEndpointLockManager* const instance_;
- ScopedWebSocketEndpointZeroUnlockDelay zero_unlock_delay_;
+ WebSocketEndpointLockManager websocket_endpoint_lock_manager_;
};
-TEST_F(WebSocketEndpointLockManagerTest, GetInstanceWorks) {
- // All the work is done by the test framework.
-}
-
TEST_F(WebSocketEndpointLockManagerTest, LockEndpointReturnsOkOnce) {
FakeWaiter waiters[2];
- EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiters[0]), IsOk());
- EXPECT_EQ(ERR_IO_PENDING,
- instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
+ EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
+ &waiters[0]),
+ IsOk());
+ EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
+ DummyEndpoint(), &waiters[1]));
UnlockDummyEndpoint(2);
}
TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledOnOk) {
FakeWaiter waiter;
- EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiter), IsOk());
+ EXPECT_THAT(
+ websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(), &waiter),
+ IsOk());
RunUntilIdle();
EXPECT_FALSE(waiter.called());
@@ -186,9 +186,11 @@ TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledOnOk) {
TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledImmediately) {
FakeWaiter waiters[2];
- EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiters[0]), IsOk());
- EXPECT_EQ(ERR_IO_PENDING,
- instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
+ EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
+ &waiters[0]),
+ IsOk());
+ EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
+ DummyEndpoint(), &waiters[1]));
RunUntilIdle();
EXPECT_FALSE(waiters[1].called());
@@ -197,10 +199,12 @@ TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockNotCalledImmediately) {
TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockCalledWhenUnlocked) {
FakeWaiter waiters[2];
- EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiters[0]), IsOk());
- EXPECT_EQ(ERR_IO_PENDING,
- instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
- instance()->UnlockEndpoint(DummyEndpoint());
+ EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
+ &waiters[0]),
+ IsOk());
+ EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
+ DummyEndpoint(), &waiters[1]));
+ websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
RunUntilIdle();
EXPECT_TRUE(waiters[1].called());
@@ -210,20 +214,22 @@ TEST_F(WebSocketEndpointLockManagerTest, GotEndpointLockCalledWhenUnlocked) {
TEST_F(WebSocketEndpointLockManagerTest,
EndpointUnlockedIfWaiterAlreadyDeleted) {
FakeWaiter first_lock_holder;
- EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &first_lock_holder),
+ EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
+ &first_lock_holder),
IsOk());
{
FakeWaiter short_lived_waiter;
- EXPECT_EQ(ERR_IO_PENDING,
- instance()->LockEndpoint(DummyEndpoint(), &short_lived_waiter));
+ EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
+ DummyEndpoint(), &short_lived_waiter));
}
- instance()->UnlockEndpoint(DummyEndpoint());
+ websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
RunUntilIdle();
FakeWaiter second_lock_holder;
- EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &second_lock_holder),
+ EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(
+ DummyEndpoint(), &second_lock_holder),
IsOk());
UnlockDummyEndpoint(1);
@@ -232,12 +238,15 @@ TEST_F(WebSocketEndpointLockManagerTest,
TEST_F(WebSocketEndpointLockManagerTest, RememberSocketWorks) {
FakeWaiter waiters[2];
FakeStreamSocket dummy_socket;
- EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiters[0]), IsOk());
- EXPECT_EQ(ERR_IO_PENDING,
- instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
+ EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
+ &waiters[0]),
+ IsOk());
+ EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
+ DummyEndpoint(), &waiters[1]));
- instance()->RememberSocket(&dummy_socket, DummyEndpoint());
- instance()->UnlockSocket(&dummy_socket);
+ websocket_endpoint_lock_manager_.RememberSocket(&dummy_socket,
+ DummyEndpoint());
+ websocket_endpoint_lock_manager_.UnlockSocket(&dummy_socket);
RunUntilIdle();
EXPECT_TRUE(waiters[1].called());
@@ -250,11 +259,14 @@ TEST_F(WebSocketEndpointLockManagerTest, SocketAssociationForgottenOnUnlock) {
FakeWaiter waiter;
FakeStreamSocket dummy_socket;
- EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiter), IsOk());
- instance()->RememberSocket(&dummy_socket, DummyEndpoint());
- instance()->UnlockEndpoint(DummyEndpoint());
+ EXPECT_THAT(
+ websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(), &waiter),
+ IsOk());
+ websocket_endpoint_lock_manager_.RememberSocket(&dummy_socket,
+ DummyEndpoint());
+ websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
RunUntilIdle();
- EXPECT_TRUE(instance()->IsEmpty());
+ EXPECT_TRUE(websocket_endpoint_lock_manager_.IsEmpty());
}
// When ownership of the endpoint is passed to a new waiter, the new waiter can
@@ -262,15 +274,19 @@ TEST_F(WebSocketEndpointLockManagerTest, SocketAssociationForgottenOnUnlock) {
TEST_F(WebSocketEndpointLockManagerTest, NextWaiterCanCallRememberSocketAgain) {
FakeWaiter waiters[2];
FakeStreamSocket dummy_sockets[2];
- EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiters[0]), IsOk());
- EXPECT_EQ(ERR_IO_PENDING,
- instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
+ EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
+ &waiters[0]),
+ IsOk());
+ EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
+ DummyEndpoint(), &waiters[1]));
- instance()->RememberSocket(&dummy_sockets[0], DummyEndpoint());
- instance()->UnlockEndpoint(DummyEndpoint());
+ websocket_endpoint_lock_manager_.RememberSocket(&dummy_sockets[0],
+ DummyEndpoint());
+ websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
RunUntilIdle();
EXPECT_TRUE(waiters[1].called());
- instance()->RememberSocket(&dummy_sockets[1], DummyEndpoint());
+ websocket_endpoint_lock_manager_.RememberSocket(&dummy_sockets[1],
+ DummyEndpoint());
UnlockDummyEndpoint(1);
}
@@ -281,14 +297,17 @@ TEST_F(WebSocketEndpointLockManagerTest,
FakeWaiter waiters[3];
FakeStreamSocket dummy_socket;
- EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiters[0]), IsOk());
- EXPECT_EQ(ERR_IO_PENDING,
- instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
- EXPECT_EQ(ERR_IO_PENDING,
- instance()->LockEndpoint(DummyEndpoint(), &waiters[2]));
- instance()->RememberSocket(&dummy_socket, DummyEndpoint());
- instance()->UnlockEndpoint(DummyEndpoint());
- instance()->UnlockSocket(&dummy_socket);
+ EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
+ &waiters[0]),
+ IsOk());
+ EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
+ DummyEndpoint(), &waiters[1]));
+ EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
+ DummyEndpoint(), &waiters[2]));
+ websocket_endpoint_lock_manager_.RememberSocket(&dummy_socket,
+ DummyEndpoint());
+ websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
+ websocket_endpoint_lock_manager_.UnlockSocket(&dummy_socket);
RunUntilIdle();
EXPECT_TRUE(waiters[1].called());
EXPECT_FALSE(waiters[2].called());
@@ -299,11 +318,13 @@ TEST_F(WebSocketEndpointLockManagerTest,
// UnlockEndpoint() should always be asynchronous.
TEST_F(WebSocketEndpointLockManagerTest, UnlockEndpointIsAsynchronous) {
FakeWaiter waiters[2];
- EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &waiters[0]), IsOk());
- EXPECT_EQ(ERR_IO_PENDING,
- instance()->LockEndpoint(DummyEndpoint(), &waiters[1]));
+ EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
+ &waiters[0]),
+ IsOk());
+ EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
+ DummyEndpoint(), &waiters[1]));
- instance()->UnlockEndpoint(DummyEndpoint());
+ websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
EXPECT_FALSE(waiters[1].called());
RunUntilIdle();
EXPECT_TRUE(waiters[1].called());
@@ -323,19 +344,21 @@ TEST_F(WebSocketEndpointLockManagerTest, UnlockEndpointIsDelayed) {
// easily enough for normal compiles even on Android, so the fact that there
// is a delay is still checked on every platform.
const base::TimeDelta unlock_delay = base::TimeDelta::FromMilliseconds(1);
- instance()->SetUnlockDelayForTesting(unlock_delay);
+ websocket_endpoint_lock_manager_.SetUnlockDelayForTesting(unlock_delay);
FakeWaiter fake_waiter;
BlockingWaiter blocking_waiter;
- EXPECT_THAT(instance()->LockEndpoint(DummyEndpoint(), &fake_waiter), IsOk());
- EXPECT_EQ(ERR_IO_PENDING,
- instance()->LockEndpoint(DummyEndpoint(), &blocking_waiter));
+ EXPECT_THAT(websocket_endpoint_lock_manager_.LockEndpoint(DummyEndpoint(),
+ &fake_waiter),
+ IsOk());
+ EXPECT_EQ(ERR_IO_PENDING, websocket_endpoint_lock_manager_.LockEndpoint(
+ DummyEndpoint(), &blocking_waiter));
TimeTicks before_unlock = TimeTicks::Now();
- instance()->UnlockEndpoint(DummyEndpoint());
+ websocket_endpoint_lock_manager_.UnlockEndpoint(DummyEndpoint());
blocking_waiter.WaitForLock();
TimeTicks after_unlock = TimeTicks::Now();
EXPECT_GE(after_unlock - before_unlock, unlock_delay);
- instance()->SetUnlockDelayForTesting(base::TimeDelta());
+ websocket_endpoint_lock_manager_.SetUnlockDelayForTesting(base::TimeDelta());
UnlockDummyEndpoint(1);
}
diff --git a/chromium/net/socket/websocket_transport_client_socket_pool.cc b/chromium/net/socket/websocket_transport_client_socket_pool.cc
index 5ef8809159a..cfef27fa3db 100644
--- a/chromium/net/socket/websocket_transport_client_socket_pool.cc
+++ b/chromium/net/socket/websocket_transport_client_socket_pool.cc
@@ -40,6 +40,7 @@ WebSocketTransportConnectJob::WebSocketTransportConnectJob(
HostResolver* host_resolver,
ClientSocketHandle* handle,
Delegate* delegate,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
NetLog* pool_net_log,
const NetLogWithSource& request_net_log)
: ConnectJob(group_name,
@@ -57,6 +58,7 @@ WebSocketTransportConnectJob::WebSocketTransportConnectJob(
next_state_(STATE_NONE),
race_result_(TransportConnectJob::RACE_UNKNOWN),
handle_(handle),
+ websocket_endpoint_lock_manager_(websocket_endpoint_lock_manager),
callback_(callback),
request_net_log_(request_net_log),
had_ipv4_(false),
@@ -173,13 +175,13 @@ int WebSocketTransportConnectJob::DoTransportConnect() {
if (!ipv4_addresses.empty()) {
had_ipv4_ = true;
ipv4_job_.reset(new WebSocketTransportConnectSubJob(
- ipv4_addresses, this, SUB_JOB_IPV4));
+ ipv4_addresses, this, SUB_JOB_IPV4, websocket_endpoint_lock_manager_));
}
if (!ipv6_addresses.empty()) {
had_ipv6_ = true;
ipv6_job_.reset(new WebSocketTransportConnectSubJob(
- ipv6_addresses, this, SUB_JOB_IPV6));
+ ipv6_addresses, this, SUB_JOB_IPV6, websocket_endpoint_lock_manager_));
result = ipv6_job_->Start();
switch (result) {
case OK:
@@ -286,6 +288,7 @@ WebSocketTransportClientSocketPool::WebSocketTransportClientSocketPool(
int max_sockets_per_group,
HostResolver* host_resolver,
ClientSocketFactory* client_socket_factory,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
NetLog* net_log)
: TransportClientSocketPool(max_sockets,
max_sockets_per_group,
@@ -297,6 +300,7 @@ WebSocketTransportClientSocketPool::WebSocketTransportClientSocketPool(
pool_net_log_(net_log),
client_socket_factory_(client_socket_factory),
host_resolver_(host_resolver),
+ websocket_endpoint_lock_manager_(websocket_endpoint_lock_manager),
max_sockets_(max_sockets),
handed_out_socket_count_(0),
flushing_(false),
@@ -313,12 +317,13 @@ WebSocketTransportClientSocketPool::~WebSocketTransportClientSocketPool() {
// static
void WebSocketTransportClientSocketPool::UnlockEndpoint(
- ClientSocketHandle* handle) {
+ ClientSocketHandle* handle,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager) {
DCHECK(handle->is_initialized());
DCHECK(handle->socket());
IPEndPoint address;
if (handle->socket()->GetPeerAddress(&address) == OK)
- WebSocketEndpointLockManager::GetInstance()->UnlockEndpoint(address);
+ websocket_endpoint_lock_manager->UnlockEndpoint(address);
}
int WebSocketTransportClientSocketPool::RequestSocket(
@@ -365,7 +370,8 @@ int WebSocketTransportClientSocketPool::RequestSocket(
new WebSocketTransportConnectJob(
group_name, priority, respect_limits, casted_params,
ConnectionTimeout(), callback, client_socket_factory_, host_resolver_,
- handle, &connect_job_delegate_, pool_net_log_, request_net_log));
+ handle, &connect_job_delegate_, websocket_endpoint_lock_manager_,
+ pool_net_log_, request_net_log));
int result = connect_job->Connect();
@@ -427,7 +433,7 @@ void WebSocketTransportClientSocketPool::ReleaseSocket(
const std::string& group_name,
std::unique_ptr<StreamSocket> socket,
int id) {
- WebSocketEndpointLockManager::GetInstance()->UnlockSocket(socket.get());
+ websocket_endpoint_lock_manager_->UnlockSocket(socket.get());
CHECK_GT(handed_out_socket_count_, 0);
--handed_out_socket_count_;
@@ -562,7 +568,7 @@ void WebSocketTransportClientSocketPool::OnConnectJobComplete(
// See comment in FlushWithError.
if (flushing_) {
std::unique_ptr<StreamSocket> socket = job->PassSocket();
- WebSocketEndpointLockManager::GetInstance()->UnlockSocket(socket.get());
+ websocket_endpoint_lock_manager_->UnlockSocket(socket.get());
return;
}
diff --git a/chromium/net/socket/websocket_transport_client_socket_pool.h b/chromium/net/socket/websocket_transport_client_socket_pool.h
index c8248812f81..c88d5b4d87d 100644
--- a/chromium/net/socket/websocket_transport_client_socket_pool.h
+++ b/chromium/net/socket/websocket_transport_client_socket_pool.h
@@ -55,6 +55,7 @@ class NET_EXPORT_PRIVATE WebSocketTransportConnectJob : public ConnectJob {
HostResolver* host_resolver,
ClientSocketHandle* handle,
Delegate* delegate,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
NetLog* pool_net_log,
const NetLogWithSource& request_net_log);
~WebSocketTransportConnectJob() override;
@@ -73,7 +74,6 @@ class NET_EXPORT_PRIVATE WebSocketTransportConnectJob : public ConnectJob {
private:
friend class WebSocketTransportConnectSubJob;
- friend class WebSocketEndpointLockManager;
enum State {
STATE_RESOLVE_HOST,
@@ -124,6 +124,7 @@ class NET_EXPORT_PRIVATE WebSocketTransportConnectJob : public ConnectJob {
base::OneShotTimer fallback_timer_;
TransportConnectJob::RaceResult race_result_;
ClientSocketHandle* const handle_;
+ WebSocketEndpointLockManager* const websocket_endpoint_lock_manager_;
CompletionCallback callback_;
NetLogWithSource request_net_log_;
@@ -136,11 +137,13 @@ class NET_EXPORT_PRIVATE WebSocketTransportConnectJob : public ConnectJob {
class NET_EXPORT_PRIVATE WebSocketTransportClientSocketPool
: public TransportClientSocketPool {
public:
- WebSocketTransportClientSocketPool(int max_sockets,
- int max_sockets_per_group,
- HostResolver* host_resolver,
- ClientSocketFactory* client_socket_factory,
- NetLog* net_log);
+ WebSocketTransportClientSocketPool(
+ int max_sockets,
+ int max_sockets_per_group,
+ HostResolver* host_resolver,
+ ClientSocketFactory* client_socket_factory,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
+ NetLog* net_log);
~WebSocketTransportClientSocketPool() override;
@@ -149,7 +152,9 @@ class NET_EXPORT_PRIVATE WebSocketTransportClientSocketPool
// This only works if the socket is connected, however the caller does not
// need to explicitly check for this. Instead, ensure that dead sockets are
// returned to ReleaseSocket() in a timely fashion.
- static void UnlockEndpoint(ClientSocketHandle* handle);
+ static void UnlockEndpoint(
+ ClientSocketHandle* handle,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager);
// ClientSocketPool implementation.
int RequestSocket(const std::string& group_name,
@@ -263,6 +268,7 @@ class NET_EXPORT_PRIVATE WebSocketTransportClientSocketPool
NetLog* const pool_net_log_;
ClientSocketFactory* const client_socket_factory_;
HostResolver* const host_resolver_;
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager_;
const int max_sockets_;
int handed_out_socket_count_;
bool flushing_;
diff --git a/chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc b/chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc
index 65a51cfec93..c3f666452af 100644
--- a/chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc
+++ b/chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc
@@ -67,14 +67,18 @@ class WebSocketTransportClientSocketPoolTest : public ::testing::Test {
kMaxSocketsPerGroup,
host_resolver_.get(),
&client_socket_factory_,
- nullptr) {}
+ &websocket_endpoint_lock_manager_,
+ nullptr) {
+ websocket_endpoint_lock_manager_.SetUnlockDelayForTesting(
+ base::TimeDelta());
+ }
~WebSocketTransportClientSocketPoolTest() override {
RunUntilIdle();
// ReleaseAllConnections() calls RunUntilIdle() after releasing each
// connection.
ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
- EXPECT_TRUE(WebSocketEndpointLockManager::GetInstance()->IsEmpty());
+ EXPECT_TRUE(websocket_endpoint_lock_manager_.IsEmpty());
}
static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
@@ -111,9 +115,9 @@ class WebSocketTransportClientSocketPoolTest : public ::testing::Test {
scoped_refptr<TransportSocketParams> params_;
std::unique_ptr<MockHostResolver> host_resolver_;
MockTransportClientSocketFactory client_socket_factory_;
+ WebSocketEndpointLockManager websocket_endpoint_lock_manager_;
WebSocketTransportClientSocketPool pool_;
ClientSocketPoolTest test_base_;
- ScopedWebSocketEndpointZeroUnlockDelay zero_unlock_delay_;
private:
DISALLOW_COPY_AND_ASSIGN(WebSocketTransportClientSocketPoolTest);
@@ -484,7 +488,8 @@ TEST_F(WebSocketTransportClientSocketPoolTest,
EXPECT_THAT(StartRequest("a", kDefaultPriority), IsError(ERR_IO_PENDING));
EXPECT_THAT(request(0)->WaitForResult(), IsOk());
EXPECT_FALSE(request(1)->handle()->is_initialized());
- WebSocketTransportClientSocketPool::UnlockEndpoint(request(0)->handle());
+ WebSocketTransportClientSocketPool::UnlockEndpoint(
+ request(0)->handle(), &websocket_endpoint_lock_manager_);
RunUntilIdle();
EXPECT_TRUE(request(1)->handle()->is_initialized());
}
@@ -511,9 +516,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest,
// socket which finishes first.
TEST_F(WebSocketTransportClientSocketPoolTest,
IPv6FallbackSocketIPv4FinishesFirst) {
- WebSocketTransportClientSocketPool pool(kMaxSockets, kMaxSocketsPerGroup,
- host_resolver_.get(),
- &client_socket_factory_, nullptr);
+ WebSocketTransportClientSocketPool pool(
+ kMaxSockets, kMaxSocketsPerGroup, host_resolver_.get(),
+ &client_socket_factory_, &websocket_endpoint_lock_manager_, nullptr);
MockTransportClientSocketFactory::ClientSocketType case_types[] = {
// This is the IPv6 socket.
@@ -550,9 +555,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest,
// finish first.
TEST_F(WebSocketTransportClientSocketPoolTest,
IPv6FallbackSocketIPv6FinishesFirst) {
- WebSocketTransportClientSocketPool pool(kMaxSockets, kMaxSocketsPerGroup,
- host_resolver_.get(),
- &client_socket_factory_, nullptr);
+ WebSocketTransportClientSocketPool pool(
+ kMaxSockets, kMaxSocketsPerGroup, host_resolver_.get(),
+ &client_socket_factory_, &websocket_endpoint_lock_manager_, nullptr);
MockTransportClientSocketFactory::ClientSocketType case_types[] = {
// This is the IPv6 socket.
@@ -588,9 +593,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest,
TEST_F(WebSocketTransportClientSocketPoolTest,
IPv6NoIPv4AddressesToFallbackTo) {
- WebSocketTransportClientSocketPool pool(kMaxSockets, kMaxSocketsPerGroup,
- host_resolver_.get(),
- &client_socket_factory_, nullptr);
+ WebSocketTransportClientSocketPool pool(
+ kMaxSockets, kMaxSocketsPerGroup, host_resolver_.get(),
+ &client_socket_factory_, &websocket_endpoint_lock_manager_, nullptr);
client_socket_factory_.set_default_client_socket_type(
MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
@@ -618,9 +623,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest,
}
TEST_F(WebSocketTransportClientSocketPoolTest, IPv4HasNoFallback) {
- WebSocketTransportClientSocketPool pool(kMaxSockets, kMaxSocketsPerGroup,
- host_resolver_.get(),
- &client_socket_factory_, nullptr);
+ WebSocketTransportClientSocketPool pool(
+ kMaxSockets, kMaxSocketsPerGroup, host_resolver_.get(),
+ &client_socket_factory_, &websocket_endpoint_lock_manager_, nullptr);
client_socket_factory_.set_default_client_socket_type(
MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
@@ -649,9 +654,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest, IPv4HasNoFallback) {
// If all IPv6 addresses fail to connect synchronously, then IPv4 connections
// proceeed immediately.
TEST_F(WebSocketTransportClientSocketPoolTest, IPv6InstantFail) {
- WebSocketTransportClientSocketPool pool(kMaxSockets, kMaxSocketsPerGroup,
- host_resolver_.get(),
- &client_socket_factory_, nullptr);
+ WebSocketTransportClientSocketPool pool(
+ kMaxSockets, kMaxSocketsPerGroup, host_resolver_.get(),
+ &client_socket_factory_, &websocket_endpoint_lock_manager_, nullptr);
MockTransportClientSocketFactory::ClientSocketType case_types[] = {
// First IPv6 socket.
@@ -684,9 +689,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest, IPv6InstantFail) {
// If all IPv6 addresses fail before the IPv4 fallback timeout, then the IPv4
// connections proceed immediately.
TEST_F(WebSocketTransportClientSocketPoolTest, IPv6RapidFail) {
- WebSocketTransportClientSocketPool pool(kMaxSockets, kMaxSocketsPerGroup,
- host_resolver_.get(),
- &client_socket_factory_, nullptr);
+ WebSocketTransportClientSocketPool pool(
+ kMaxSockets, kMaxSocketsPerGroup, host_resolver_.get(),
+ &client_socket_factory_, &websocket_endpoint_lock_manager_, nullptr);
MockTransportClientSocketFactory::ClientSocketType case_types[] = {
// First IPv6 socket.
@@ -727,9 +732,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest, IPv6RapidFail) {
// can only happen if the sockets are different types, since sockets of the same
// type do not race).
TEST_F(WebSocketTransportClientSocketPoolTest, FirstSuccessWins) {
- WebSocketTransportClientSocketPool pool(kMaxSockets, kMaxSocketsPerGroup,
- host_resolver_.get(),
- &client_socket_factory_, nullptr);
+ WebSocketTransportClientSocketPool pool(
+ kMaxSockets, kMaxSocketsPerGroup, host_resolver_.get(),
+ &client_socket_factory_, &websocket_endpoint_lock_manager_, nullptr);
client_socket_factory_.set_default_client_socket_type(
MockTransportClientSocketFactory::MOCK_TRIGGERABLE_CLIENT_SOCKET);
@@ -764,9 +769,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest, FirstSuccessWins) {
// We should not report failure until all connections have failed.
TEST_F(WebSocketTransportClientSocketPoolTest, LastFailureWins) {
- WebSocketTransportClientSocketPool pool(kMaxSockets, kMaxSocketsPerGroup,
- host_resolver_.get(),
- &client_socket_factory_, nullptr);
+ WebSocketTransportClientSocketPool pool(
+ kMaxSockets, kMaxSocketsPerGroup, host_resolver_.get(),
+ &client_socket_factory_, &websocket_endpoint_lock_manager_, nullptr);
client_socket_factory_.set_default_client_socket_type(
MockTransportClientSocketFactory::MOCK_DELAYED_FAILING_CLIENT_SOCKET);
@@ -805,9 +810,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest, LastFailureWins) {
// because it takes 4 minutes. Run with --gtest_also_run_disabled_tests if you
// want to run it.
TEST_F(WebSocketTransportClientSocketPoolTest, DISABLED_OverallTimeoutApplies) {
- WebSocketTransportClientSocketPool pool(kMaxSockets, kMaxSocketsPerGroup,
- host_resolver_.get(),
- &client_socket_factory_, nullptr);
+ WebSocketTransportClientSocketPool pool(
+ kMaxSockets, kMaxSocketsPerGroup, host_resolver_.get(),
+ &client_socket_factory_, &websocket_endpoint_lock_manager_, nullptr);
const base::TimeDelta connect_job_timeout = pool.ConnectionTimeout();
client_socket_factory_.set_default_client_socket_type(
@@ -839,7 +844,8 @@ TEST_F(WebSocketTransportClientSocketPoolTest, MaxSocketsEnforced) {
host_resolver_->set_synchronous_mode(true);
for (int i = 0; i < kMaxSockets; ++i) {
ASSERT_THAT(StartRequest("a", kDefaultPriority), IsOk());
- WebSocketTransportClientSocketPool::UnlockEndpoint(request(i)->handle());
+ WebSocketTransportClientSocketPool::UnlockEndpoint(
+ request(i)->handle(), &websocket_endpoint_lock_manager_);
RunUntilIdle();
}
EXPECT_THAT(StartRequest("a", kDefaultPriority), IsError(ERR_IO_PENDING));
@@ -854,7 +860,8 @@ TEST_F(WebSocketTransportClientSocketPoolTest, MaxSocketsEnforcedWhenPending) {
RunUntilIdle();
EXPECT_TRUE(request(i)->handle()->is_initialized());
EXPECT_TRUE(request(i)->handle()->socket());
- WebSocketTransportClientSocketPool::UnlockEndpoint(request(i)->handle());
+ WebSocketTransportClientSocketPool::UnlockEndpoint(
+ request(i)->handle(), &websocket_endpoint_lock_manager_);
}
// Now there are 32 sockets connected, and one stalled.
RunUntilIdle();
@@ -866,7 +873,8 @@ TEST_F(WebSocketTransportClientSocketPoolTest, StalledSocketReleased) {
host_resolver_->set_synchronous_mode(true);
for (int i = 0; i < kMaxSockets; ++i) {
ASSERT_THAT(StartRequest("a", kDefaultPriority), IsOk());
- WebSocketTransportClientSocketPool::UnlockEndpoint(request(i)->handle());
+ WebSocketTransportClientSocketPool::UnlockEndpoint(
+ request(i)->handle(), &websocket_endpoint_lock_manager_);
RunUntilIdle();
}
@@ -1067,7 +1075,8 @@ TEST_F(WebSocketTransportClientSocketPoolTest, EndpointLockIsOnlyReleasedOnce) {
EXPECT_THAT(StartRequest("a", kDefaultPriority), IsError(ERR_IO_PENDING));
EXPECT_THAT(StartRequest("a", kDefaultPriority), IsError(ERR_IO_PENDING));
// First socket completes handshake.
- WebSocketTransportClientSocketPool::UnlockEndpoint(request(0)->handle());
+ WebSocketTransportClientSocketPool::UnlockEndpoint(
+ request(0)->handle(), &websocket_endpoint_lock_manager_);
RunUntilIdle();
// First socket is closed.
request(0)->handle()->Reset();
diff --git a/chromium/net/socket/websocket_transport_connect_sub_job.cc b/chromium/net/socket/websocket_transport_connect_sub_job.cc
index 97d36596656..20232cf7a5b 100644
--- a/chromium/net/socket/websocket_transport_connect_sub_job.cc
+++ b/chromium/net/socket/websocket_transport_connect_sub_job.cc
@@ -16,12 +16,14 @@ namespace net {
WebSocketTransportConnectSubJob::WebSocketTransportConnectSubJob(
const AddressList& addresses,
WebSocketTransportConnectJob* parent_job,
- SubJobType type)
+ SubJobType type,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager)
: parent_job_(parent_job),
addresses_(addresses),
current_address_index_(0),
next_state_(STATE_NONE),
- type_(type) {}
+ type_(type),
+ websocket_endpoint_lock_manager_(websocket_endpoint_lock_manager) {}
WebSocketTransportConnectSubJob::~WebSocketTransportConnectSubJob() {
// We don't worry about cancelling the TCP connect, since ~StreamSocket will
@@ -30,8 +32,7 @@ WebSocketTransportConnectSubJob::~WebSocketTransportConnectSubJob() {
DCHECK_EQ(STATE_OBTAIN_LOCK_COMPLETE, next_state_);
// The ~Waiter destructor will remove this object from the waiting list.
} else if (next_state_ == STATE_TRANSPORT_CONNECT_COMPLETE) {
- WebSocketEndpointLockManager::GetInstance()->UnlockEndpoint(
- CurrentAddress());
+ websocket_endpoint_lock_manager_->UnlockEndpoint(CurrentAddress());
}
}
@@ -120,8 +121,8 @@ int WebSocketTransportConnectSubJob::DoLoop(int result) {
}
int WebSocketTransportConnectSubJob::DoEndpointLock() {
- int rv = WebSocketEndpointLockManager::GetInstance()->LockEndpoint(
- CurrentAddress(), this);
+ int rv =
+ websocket_endpoint_lock_manager_->LockEndpoint(CurrentAddress(), this);
next_state_ = STATE_OBTAIN_LOCK_COMPLETE;
return rv;
}
@@ -146,10 +147,8 @@ int WebSocketTransportConnectSubJob::DoTransportConnect() {
int WebSocketTransportConnectSubJob::DoTransportConnectComplete(int result) {
next_state_ = STATE_DONE;
- WebSocketEndpointLockManager* endpoint_lock_manager =
- WebSocketEndpointLockManager::GetInstance();
if (result != OK) {
- endpoint_lock_manager->UnlockEndpoint(CurrentAddress());
+ websocket_endpoint_lock_manager_->UnlockEndpoint(CurrentAddress());
if (current_address_index_ + 1 < addresses_.size()) {
// Try falling back to the next address in the list.
@@ -161,8 +160,8 @@ int WebSocketTransportConnectSubJob::DoTransportConnectComplete(int result) {
return result;
}
- endpoint_lock_manager->RememberSocket(transport_socket_.get(),
- CurrentAddress());
+ websocket_endpoint_lock_manager_->RememberSocket(transport_socket_.get(),
+ CurrentAddress());
return result;
}
diff --git a/chromium/net/socket/websocket_transport_connect_sub_job.h b/chromium/net/socket/websocket_transport_connect_sub_job.h
index 958eaa7a556..e1b933f2f4e 100644
--- a/chromium/net/socket/websocket_transport_connect_sub_job.h
+++ b/chromium/net/socket/websocket_transport_connect_sub_job.h
@@ -23,6 +23,7 @@ class ClientSocketFactory;
class IPEndPoint;
class NetLogWithSource;
class StreamSocket;
+class WebSocketEndpointLockManager;
// Attempts to connect to a subset of the addresses required by a
// WebSocketTransportConnectJob, specifically either the IPv4 or IPv6
@@ -33,9 +34,11 @@ class WebSocketTransportConnectSubJob
public:
typedef WebSocketTransportConnectJob::SubJobType SubJobType;
- WebSocketTransportConnectSubJob(const AddressList& addresses,
- WebSocketTransportConnectJob* parent_job,
- SubJobType type);
+ WebSocketTransportConnectSubJob(
+ const AddressList& addresses,
+ WebSocketTransportConnectJob* parent_job,
+ SubJobType type,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager);
~WebSocketTransportConnectSubJob() override;
@@ -85,6 +88,7 @@ class WebSocketTransportConnectSubJob
State next_state_;
const SubJobType type_;
+ WebSocketEndpointLockManager* const websocket_endpoint_lock_manager_;
std::unique_ptr<StreamSocket> transport_socket_;
diff --git a/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl.cc b/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl.cc
index 4069f33e7c9..e9145f54602 100644
--- a/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl.cc
+++ b/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl.cc
@@ -58,7 +58,8 @@ void BidirectionalStreamSpdyImpl::Start(
const NetLogWithSource& net_log,
bool /*send_request_headers_automatically*/,
BidirectionalStreamImpl::Delegate* delegate,
- std::unique_ptr<base::Timer> timer) {
+ std::unique_ptr<base::Timer> timer,
+ const NetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK(!stream_);
DCHECK(timer);
@@ -75,13 +76,12 @@ void BidirectionalStreamSpdyImpl::Start(
request_info_ = request_info;
- // TODO(https://crbug.com/656607): Add proper annotation here.
int rv = stream_request_.StartRequest(
SPDY_BIDIRECTIONAL_STREAM, spdy_session_, request_info_->url,
request_info_->priority, request_info_->socket_tag, net_log,
base::Bind(&BidirectionalStreamSpdyImpl::OnStreamInitialized,
weak_factory_.GetWeakPtr()),
- NO_TRAFFIC_ANNOTATION_BUG_656607);
+ traffic_annotation);
if (rv != ERR_IO_PENDING)
OnStreamInitialized(rv);
}
diff --git a/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl.h b/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl.h
index c4c11ed5952..0962e78f4a5 100644
--- a/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl.h
+++ b/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl.h
@@ -47,7 +47,8 @@ class NET_EXPORT_PRIVATE BidirectionalStreamSpdyImpl
const NetLogWithSource& net_log,
bool send_request_headers_automatically,
BidirectionalStreamImpl::Delegate* delegate,
- std::unique_ptr<base::Timer> timer) override;
+ std::unique_ptr<base::Timer> timer,
+ const NetworkTrafficAnnotationTag& traffic_annotation) override;
void SendRequestHeaders() override;
int ReadData(IOBuffer* buf, int buf_len) override;
void SendvData(const std::vector<scoped_refptr<IOBuffer>>& buffers,
diff --git a/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc b/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc
index 76a50ac83c5..4a88949f296 100644
--- a/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc
+++ b/chromium/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc
@@ -25,6 +25,7 @@
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -133,7 +134,8 @@ class TestDelegateBase : public BidirectionalStreamImpl::Delegate {
const NetLogWithSource& net_log) {
stream_->Start(request, net_log,
/*send_request_headers_automatically=*/false, this,
- std::make_unique<base::Timer>(false, false));
+ std::make_unique<base::Timer>(false, false),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
not_expect_callback_ = false;
}
diff --git a/chromium/net/spdy/chromium/buffered_spdy_framer.cc b/chromium/net/spdy/chromium/buffered_spdy_framer.cc
index a797362361a..0b5e76db109 100644
--- a/chromium/net/spdy/chromium/buffered_spdy_framer.cc
+++ b/chromium/net/spdy/chromium/buffered_spdy_framer.cc
@@ -140,7 +140,11 @@ void BufferedSpdyFramer::OnSettings() {
visitor_->OnSettings();
}
-void BufferedSpdyFramer::OnSetting(SpdyKnownSettingsId id, uint32_t value) {
+void BufferedSpdyFramer::OnSettingOld(SpdyKnownSettingsId id, uint32_t value) {
+ visitor_->OnSetting(id, value);
+}
+
+void BufferedSpdyFramer::OnSetting(SpdySettingsId id, uint32_t value) {
visitor_->OnSetting(id, value);
}
diff --git a/chromium/net/spdy/chromium/buffered_spdy_framer.h b/chromium/net/spdy/chromium/buffered_spdy_framer.h
index 71ae7836626..e7cbc050754 100644
--- a/chromium/net/spdy/chromium/buffered_spdy_framer.h
+++ b/chromium/net/spdy/chromium/buffered_spdy_framer.h
@@ -70,9 +70,9 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface {
// Called when a SETTINGS frame is received.
virtual void OnSettings() = 0;
- // Called when an individual setting within a SETTINGS frame has been parsed
- // and validated.
- virtual void OnSetting(SpdyKnownSettingsId id, uint32_t value) = 0;
+ // Called when an individual setting within a SETTINGS frame has been parsed.
+ // Note that |id| may or may not be a SETTINGS ID defined in the HTTP/2 spec.
+ virtual void OnSetting(SpdySettingsId id, uint32_t value) = 0;
// Called when a SETTINGS frame is received with the ACK flag set.
virtual void OnSettingsAck() = 0;
@@ -158,7 +158,8 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer
SpdyStreamId stream_id) override;
void OnHeaderFrameEnd(SpdyStreamId stream_id) override;
void OnSettings() override;
- void OnSetting(SpdyKnownSettingsId id, uint32_t value) override;
+ void OnSettingOld(SpdyKnownSettingsId id, uint32_t value) override;
+ void OnSetting(SpdySettingsId id, uint32_t value) override;
void OnSettingsAck() override;
void OnSettingsEnd() override;
void OnPing(SpdyPingId unique_id, bool is_ack) override;
diff --git a/chromium/net/spdy/chromium/buffered_spdy_framer_unittest.cc b/chromium/net/spdy/chromium/buffered_spdy_framer_unittest.cc
index b9a983a8645..a35e4e19bf2 100644
--- a/chromium/net/spdy/chromium/buffered_spdy_framer_unittest.cc
+++ b/chromium/net/spdy/chromium/buffered_spdy_framer_unittest.cc
@@ -80,7 +80,7 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface {
void OnSettingsEnd() override {}
- void OnSetting(SpdyKnownSettingsId id, uint32_t value) override {
+ void OnSetting(SpdySettingsId id, uint32_t value) override {
setting_count_++;
}
diff --git a/chromium/net/spdy/chromium/spdy_http_stream.cc b/chromium/net/spdy/chromium/spdy_http_stream.cc
index df05b4fed71..c852d8b6203 100644
--- a/chromium/net/spdy/chromium/spdy_http_stream.cc
+++ b/chromium/net/spdy/chromium/spdy_http_stream.cc
@@ -23,6 +23,7 @@
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_with_source.h"
#include "net/spdy/chromium/spdy_http_utils.h"
+#include "net/spdy/chromium/spdy_log_util.h"
#include "net/spdy/chromium/spdy_session.h"
#include "net/spdy/core/spdy_header_block.h"
#include "net/spdy/core/spdy_protocol.h"
@@ -92,13 +93,12 @@ int SpdyHttpStream::InitializeStream(const HttpRequestInfo* request_info,
}
}
- // TODO(https://crbug.com/656607): Add proper annotation here.
int rv = stream_request_.StartRequest(
SPDY_REQUEST_RESPONSE_STREAM, spdy_session_, request_info_->url, priority,
request_info_->socket_tag, stream_net_log,
base::BindOnce(&SpdyHttpStream::OnStreamCreated,
weak_factory_.GetWeakPtr(), std::move(callback)),
- NO_TRAFFIC_ANNOTATION_BUG_656607);
+ NetworkTrafficAnnotationTag(request_info->traffic_annotation));
if (rv == OK) {
stream_ = stream_request_.ReleaseStream().get();
diff --git a/chromium/net/spdy/chromium/spdy_http_stream_unittest.cc b/chromium/net/spdy/chromium/spdy_http_stream_unittest.cc
index ecd3db54a53..f01654277b0 100644
--- a/chromium/net/spdy/chromium/spdy_http_stream_unittest.cc
+++ b/chromium/net/spdy/chromium/spdy_http_stream_unittest.cc
@@ -31,6 +31,7 @@
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -196,6 +197,8 @@ TEST_F(SpdyHttpStreamTest, SendRequest) {
HttpRequestInfo request;
request.method = "GET";
request.url = url_;
+ request.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
TestCompletionCallback callback;
HttpResponseInfo response;
HttpRequestHeaders headers;
@@ -252,6 +255,8 @@ TEST_F(SpdyHttpStreamTest, RequestInfoDestroyedBeforeRead) {
std::make_unique<HttpRequestInfo>();
request->method = "GET";
request->url = url_;
+ request->traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
TestCompletionCallback callback;
HttpResponseInfo response;
HttpRequestHeaders headers;
@@ -313,6 +318,8 @@ TEST_F(SpdyHttpStreamTest, LoadTimingTwoRequests) {
HttpRequestInfo request1;
request1.method = "GET";
request1.url = url_;
+ request1.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
TestCompletionCallback callback1;
HttpResponseInfo response1;
HttpRequestHeaders headers1;
@@ -323,6 +330,8 @@ TEST_F(SpdyHttpStreamTest, LoadTimingTwoRequests) {
HttpRequestInfo request2;
request2.method = "GET";
request2.url = url_;
+ request2.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
TestCompletionCallback callback2;
HttpResponseInfo response2;
HttpRequestHeaders headers2;
@@ -413,6 +422,8 @@ TEST_F(SpdyHttpStreamTest, SendChunkedPost) {
HttpRequestInfo request;
request.method = "POST";
request.url = url_;
+ request.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
request.upload_data_stream = &upload_stream;
ASSERT_THAT(upload_stream.Init(TestCompletionCallback().callback(),
@@ -467,6 +478,8 @@ TEST_F(SpdyHttpStreamTest, SendChunkedPostLastEmpty) {
HttpRequestInfo request;
request.method = "POST";
request.url = url_;
+ request.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
request.upload_data_stream = &upload_stream;
ASSERT_THAT(upload_stream.Init(TestCompletionCallback().callback(),
@@ -520,6 +533,8 @@ TEST_F(SpdyHttpStreamTest, ConnectionClosedDuringChunkedPost) {
HttpRequestInfo request;
request.method = "POST";
request.url = url_;
+ request.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
request.upload_data_stream = &upload_stream;
ASSERT_THAT(upload_stream.Init(TestCompletionCallback().callback(),
@@ -590,6 +605,8 @@ TEST_F(SpdyHttpStreamTest, DelayedSendChunkedPost) {
HttpRequestInfo request;
request.method = "POST";
request.url = url_;
+ request.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
request.upload_data_stream = &upload_stream;
ASSERT_THAT(upload_stream.Init(TestCompletionCallback().callback(),
@@ -685,6 +702,8 @@ TEST_F(SpdyHttpStreamTest, DelayedSendChunkedPostWithEmptyFinalDataFrame) {
HttpRequestInfo request;
request.method = "POST";
request.url = url_;
+ request.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
request.upload_data_stream = &upload_stream;
ASSERT_THAT(upload_stream.Init(TestCompletionCallback().callback(),
@@ -769,6 +788,8 @@ TEST_F(SpdyHttpStreamTest, ChunkedPostWithEmptyPayload) {
HttpRequestInfo request;
request.method = "POST";
request.url = url_;
+ request.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
request.upload_data_stream = &upload_stream;
ASSERT_THAT(upload_stream.Init(TestCompletionCallback().callback(),
@@ -833,6 +854,8 @@ TEST_F(SpdyHttpStreamTest, SpdyURLTest) {
HttpRequestInfo request;
request.method = "GET";
request.url = GURL(full_url);
+ request.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
TestCompletionCallback callback;
HttpResponseInfo response;
HttpRequestHeaders headers;
@@ -846,7 +869,7 @@ TEST_F(SpdyHttpStreamTest, SpdyURLTest) {
EXPECT_THAT(http_stream->SendRequest(headers, &response, callback.callback()),
IsError(ERR_IO_PENDING));
- EXPECT_EQ(base_url, http_stream->stream()->GetUrlFromHeaders().spec());
+ EXPECT_EQ(base_url, http_stream->stream()->url().spec());
callback.WaitForResult();
@@ -883,6 +906,8 @@ TEST_F(SpdyHttpStreamTest, DelayedSendChunkedPostWithWindowUpdate) {
HttpRequestInfo request;
request.method = "POST";
request.url = url_;
+ request.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
request.upload_data_stream = &upload_stream;
ASSERT_THAT(upload_stream.Init(TestCompletionCallback().callback(),
@@ -989,6 +1014,8 @@ TEST_F(SpdyHttpStreamTest, DataReadErrorSynchronous) {
HttpRequestInfo request;
request.method = "POST";
request.url = url_;
+ request.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
request.upload_data_stream = &upload_data_stream;
TestCompletionCallback callback;
@@ -1042,6 +1069,8 @@ TEST_F(SpdyHttpStreamTest, DataReadErrorAsynchronous) {
HttpRequestInfo request;
request.method = "POST";
request.url = url_;
+ request.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
request.upload_data_stream = &upload_data_stream;
TestCompletionCallback callback;
@@ -1079,6 +1108,8 @@ TEST_F(SpdyHttpStreamTest, RequestCallbackCancelsStream) {
HttpRequestInfo request;
request.method = "POST";
request.url = url_;
+ request.traffic_annotation =
+ MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ChunkedUploadDataStream upload_stream(0);
request.upload_data_stream = &upload_stream;
diff --git a/chromium/net/spdy/chromium/spdy_http_utils.cc b/chromium/net/spdy/chromium/spdy_http_utils.cc
index 0cb8c3a26cb..74356b35a4d 100644
--- a/chromium/net/spdy/chromium/spdy_http_utils.cc
+++ b/chromium/net/spdy/chromium/spdy_http_utils.cc
@@ -114,7 +114,7 @@ void CreateSpdyHeadersFromHttpRequestForWebSocket(
const HttpRequestHeaders& request_headers,
SpdyHeaderBlock* headers) {
(*headers)[kHttp2MethodHeader] = "CONNECT";
- (*headers)[kHttp2AuthorityHeader] = GetHostAndPort(url);
+ (*headers)[kHttp2AuthorityHeader] = GetHostAndOptionalPort(url);
(*headers)[kHttp2SchemeHeader] = "https";
(*headers)[kHttp2PathHeader] = url.PathForRequest();
(*headers)[kHttp2ProtocolHeader] = "websocket";
diff --git a/chromium/net/spdy/chromium/spdy_log_util.cc b/chromium/net/spdy/chromium/spdy_log_util.cc
index 4ef8e06e0ca..b1d20b78f38 100644
--- a/chromium/net/spdy/chromium/spdy_log_util.cc
+++ b/chromium/net/spdy/chromium/spdy_log_util.cc
@@ -36,4 +36,20 @@ std::unique_ptr<base::ListValue> ElideSpdyHeaderBlockForNetLog(
return headers_list;
}
+std::unique_ptr<base::Value> SpdyHeaderBlockNetLogCallback(
+ const SpdyHeaderBlock* headers,
+ NetLogCaptureMode capture_mode) {
+ auto dict = std::make_unique<base::DictionaryValue>();
+ auto headers_dict = std::make_unique<base::DictionaryValue>();
+ for (SpdyHeaderBlock::const_iterator it = headers->begin();
+ it != headers->end(); ++it) {
+ headers_dict->SetKey(
+ it->first.as_string(),
+ base::Value(ElideHeaderValueForNetLog(
+ capture_mode, it->first.as_string(), it->second.as_string())));
+ }
+ dict->Set("headers", std::move(headers_dict));
+ return std::move(dict);
+}
+
} // namespace net
diff --git a/chromium/net/spdy/chromium/spdy_log_util.h b/chromium/net/spdy/chromium/spdy_log_util.h
index 86635eaf1ce..92b8bee398b 100644
--- a/chromium/net/spdy/chromium/spdy_log_util.h
+++ b/chromium/net/spdy/chromium/spdy_log_util.h
@@ -9,6 +9,8 @@
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
+#include "net/http/http_log_util.h"
+#include "net/log/net_log.h"
#include "net/log/net_log_capture_mode.h"
#include "net/spdy/core/spdy_header_block.h"
#include "net/spdy/platform/api/spdy_string.h"
@@ -30,6 +32,11 @@ NET_EXPORT_PRIVATE std::unique_ptr<base::ListValue>
ElideSpdyHeaderBlockForNetLog(const SpdyHeaderBlock& headers,
NetLogCaptureMode capture_mode);
+// Converts a SpdyHeaderBlock into NetLog event parameters.
+NET_EXPORT_PRIVATE std::unique_ptr<base::Value> SpdyHeaderBlockNetLogCallback(
+ const SpdyHeaderBlock* headers,
+ NetLogCaptureMode capture_mode);
+
} // namespace net
#endif // NET_SPDY_CHROMIUM_SPDY_LOG_UTIL_H_
diff --git a/chromium/net/spdy/chromium/spdy_network_transaction_unittest.cc b/chromium/net/spdy/chromium/spdy_network_transaction_unittest.cc
index 3fdf3e5198a..9d3202ac0ab 100644
--- a/chromium/net/spdy/chromium/spdy_network_transaction_unittest.cc
+++ b/chromium/net/spdy/chromium/spdy_network_transaction_unittest.cc
@@ -29,6 +29,7 @@
#include "net/http/http_network_session.h"
#include "net/http/http_network_session_peer.h"
#include "net/http/http_network_transaction.h"
+#include "net/http/http_response_info.h"
#include "net/http/http_server_properties.h"
#include "net/http/http_transaction_test_util.h"
#include "net/log/net_log_event_type.h"
@@ -592,6 +593,43 @@ TEST_F(SpdyNetworkTransactionTest, Get) {
EXPECT_EQ("hello!", out.response_data);
}
+TEST_F(SpdyNetworkTransactionTest, SetPriority) {
+ for (bool set_priority_before_starting_transaction : {true, false}) {
+ SpdyTestUtil spdy_test_util;
+ SpdySerializedFrame req(
+ spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
+ MockWrite writes[] = {CreateMockWrite(req, 0)};
+
+ SpdySerializedFrame resp(
+ spdy_test_util.ConstructSpdyGetReply(nullptr, 0, 1));
+ SpdySerializedFrame body(spdy_test_util.ConstructSpdyDataFrame(1, true));
+ MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(body, 2),
+ MockRead(ASYNC, 0, 3)};
+
+ SequencedSocketData data(reads, arraysize(reads), writes,
+ arraysize(writes));
+ NormalSpdyTransactionHelper helper(request_, HIGHEST, log_, nullptr);
+ helper.RunPreTestSetup();
+ helper.AddData(&data);
+
+ if (set_priority_before_starting_transaction) {
+ helper.trans()->SetPriority(LOWEST);
+ EXPECT_TRUE(helper.StartDefaultTest());
+ } else {
+ EXPECT_TRUE(helper.StartDefaultTest());
+ helper.trans()->SetPriority(LOWEST);
+ }
+
+ helper.FinishDefaultTest();
+ helper.VerifyDataConsumed();
+
+ TransactionHelperResult out = helper.output();
+ EXPECT_THAT(out.rv, IsOk());
+ EXPECT_EQ("HTTP/1.1 200", out.status_line);
+ EXPECT_EQ("hello!", out.response_data);
+ }
+}
+
TEST_F(SpdyNetworkTransactionTest, GetAtEachPriority) {
for (RequestPriority p = MINIMUM_PRIORITY; p <= MAXIMUM_PRIORITY;
p = RequestPriority(p + 1)) {
@@ -4498,7 +4536,8 @@ TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredRetry) {
TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) {
request_.method = "GET";
auto session_deps = std::make_unique<SpdySessionDependencies>(
- ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy:70"));
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
// Do not force SPDY so that second socket can negotiate HTTP/1.1.
NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
std::move(session_deps));
@@ -4586,7 +4625,8 @@ TEST_F(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) {
// Test to make sure we can correctly connect through a proxy.
TEST_F(SpdyNetworkTransactionTest, ProxyConnect) {
auto session_deps = std::make_unique<SpdySessionDependencies>(
- ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70"));
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
std::move(session_deps));
helper.RunPreTestSetup();
@@ -4610,10 +4650,9 @@ TEST_F(SpdyNetworkTransactionTest, ProxyConnect) {
CreateMockRead(resp, 3), CreateMockRead(body, 4),
MockRead(ASYNC, 0, 0, 5),
};
- auto data = std::make_unique<SequencedSocketData>(reads, arraysize(reads),
- writes, arraysize(writes));
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
- helper.AddData(data.get());
+ helper.AddData(&data);
TestCompletionCallback callback;
int rv = trans->Start(&request_, callback.callback(), log_);
@@ -4643,7 +4682,7 @@ TEST_F(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) {
// that the session pool key used does is just "DIRECT".
auto session_deps = std::make_unique<SpdySessionDependencies>(
ProxyResolutionService::CreateFixedFromPacResult(
- "DIRECT; PROXY myproxy:70"));
+ "DIRECT; PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
// When setting up the first transaction, we store the SpdySessionPool so that
// we can use the same pool in the second transaction.
NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
@@ -4720,19 +4759,20 @@ TEST_F(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) {
MockRead(ASYNC, 0, 5) // EOF
};
- auto data_proxy = std::make_unique<SequencedSocketData>(
- reads2, arraysize(reads2), writes2, arraysize(writes2));
+ SequencedSocketData data_proxy(reads2, arraysize(reads2), writes2,
+ arraysize(writes2));
// Create another request to www.example.org, but this time through a proxy.
request_.method = "GET";
request_.url = GURL("https://www.example.org/foo.dat");
auto session_deps_proxy = std::make_unique<SpdySessionDependencies>(
- ProxyResolutionService::CreateFixedFromPacResult("PROXY myproxy:70"));
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
NormalSpdyTransactionHelper helper_proxy(request_, DEFAULT_PRIORITY, log_,
std::move(session_deps_proxy));
helper_proxy.RunPreTestSetup();
- helper_proxy.AddData(data_proxy.get());
+ helper_proxy.AddData(&data_proxy);
HttpNetworkTransaction* trans_proxy = helper_proxy.trans();
TestCompletionCallback callback_proxy;
@@ -6858,7 +6898,8 @@ TEST_F(SpdyNetworkTransactionTest, InsecureUrlCreatesSecureSpdySession) {
// Need secure proxy so that insecure URL can use HTTP/2.
auto session_deps = std::make_unique<SpdySessionDependencies>(
- ProxyResolutionService::CreateFixedFromPacResult("HTTPS myproxy:70"));
+ ProxyResolutionService::CreateFixedFromPacResult(
+ "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS));
NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
std::move(session_deps));
@@ -7119,7 +7160,7 @@ TEST_F(SpdyNetworkTransactionTest, WebSocketOverHTTP2) {
SpdyHeaderBlock websocket_request_headers;
websocket_request_headers[kHttp2MethodHeader] = "CONNECT";
- websocket_request_headers[kHttp2AuthorityHeader] = "www.example.org:443";
+ websocket_request_headers[kHttp2AuthorityHeader] = "www.example.org";
websocket_request_headers[kHttp2SchemeHeader] = "https";
websocket_request_headers[kHttp2PathHeader] = "/";
websocket_request_headers[kHttp2ProtocolHeader] = "websocket";
@@ -7213,6 +7254,80 @@ TEST_F(SpdyNetworkTransactionTest, WebSocketOverHTTP2) {
helper.VerifyDataConsumed();
}
+TEST_F(SpdyNetworkTransactionTest, WebSocketNegotiatesHttp2) {
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("wss://www.example.org/");
+ request.traffic_annotation =
+ net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
+ EXPECT_TRUE(HostPortPair::FromURL(request_.url)
+ .Equals(HostPortPair::FromURL(request.url)));
+ request.extra_headers.SetHeader("Connection", "Upgrade");
+ request.extra_headers.SetHeader("Upgrade", "websocket");
+ request.extra_headers.SetHeader("Origin", "http://www.example.org");
+ request.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
+
+ NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
+ helper.RunPreTestSetup();
+
+ StaticSocketDataProvider data(nullptr, 0, nullptr, 0);
+
+ auto ssl_provider = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
+ // Test that request has empty |alpn_protos|, that is, HTTP/2 is disabled.
+ ssl_provider->next_protos_expected_in_ssl_config = NextProtoVector{};
+ // Force socket to use HTTP/1.1, the default protocol without ALPN.
+ ssl_provider->next_proto = kProtoHTTP2;
+ ssl_provider->ssl_info.cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
+ helper.AddDataWithSSLSocketDataProvider(&data, std::move(ssl_provider));
+
+ HttpNetworkTransaction* trans = helper.trans();
+ TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
+ trans->SetWebSocketHandshakeStreamCreateHelper(
+ &websocket_stream_create_helper);
+
+ TestCompletionCallback callback;
+ int rv = trans->Start(&request, callback.callback(), log_);
+ ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
+ rv = callback.WaitForResult();
+ ASSERT_THAT(rv, IsError(ERR_NOT_IMPLEMENTED));
+
+ helper.VerifyDataConsumed();
+}
+
+// Plaintext WebSocket over HTTP/2 is not implemented, see
+// https://crbug.com/684681.
+TEST_F(SpdyNetworkTransactionTest, PlaintextWebSocketOverHttp2Proxy) {
+ SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
+ nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 80)));
+ MockWrite writes[] = {CreateMockWrite(req, 0)};
+
+ SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
+ MockRead reads[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
+
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
+
+ request_.url = GURL("ws://www.example.org/");
+ auto session_deps = std::make_unique<SpdySessionDependencies>(
+ ProxyResolutionService::CreateFixed("https://proxy:70",
+ TRAFFIC_ANNOTATION_FOR_TESTS));
+ NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
+ std::move(session_deps));
+ helper.RunPreTestSetup();
+ helper.AddData(&data);
+
+ HttpNetworkTransaction* trans = helper.trans();
+ TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
+ trans->SetWebSocketHandshakeStreamCreateHelper(
+ &websocket_stream_create_helper);
+
+ EXPECT_TRUE(helper.StartDefaultTest());
+ helper.WaitForCallbackToComplete();
+ EXPECT_THAT(helper.output().rv, IsError(ERR_NOT_IMPLEMENTED));
+
+ helper.VerifyDataConsumed();
+}
+
// Regression test for https://crbug.com/819101. Open two identical plaintext
// websocket requests over proxy. The HttpStreamFactoryImpl::Job for the second
// request should reuse the first connection.
@@ -7230,7 +7345,8 @@ TEST_F(SpdyNetworkTransactionTest, TwoWebSocketRequestsOverHttp2Proxy) {
request_.url = GURL("ws://www.example.org/");
auto session_deps = std::make_unique<SpdySessionDependencies>(
- ProxyResolutionService::CreateFixed("https://proxy:70"));
+ ProxyResolutionService::CreateFixed("https://proxy:70",
+ TRAFFIC_ANNOTATION_FOR_TESTS));
NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
std::move(session_deps));
helper.RunPreTestSetup();
@@ -7262,6 +7378,136 @@ TEST_F(SpdyNetworkTransactionTest, TwoWebSocketRequestsOverHttp2Proxy) {
helper.VerifyDataConsumed();
}
+TEST_F(SpdyNetworkTransactionTest, SecureWebSocketOverHttp2Proxy) {
+ SpdySerializedFrame connect_request(spdy_util_.ConstructSpdyConnect(
+ nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
+ const char kWebSocketRequest[] =
+ "GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: Upgrade\r\n"
+ "Upgrade: websocket\r\n"
+ "Origin: http://www.example.org\r\n"
+ "Sec-WebSocket-Version: 13\r\n"
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
+ "Sec-WebSocket-Extensions: permessage-deflate; "
+ "client_max_window_bits\r\n\r\n";
+ SpdySerializedFrame websocket_request(
+ spdy_util_.ConstructSpdyDataFrame(1, kWebSocketRequest, false));
+ MockWrite writes[] = {CreateMockWrite(connect_request, 0),
+ CreateMockWrite(websocket_request, 2)};
+
+ SpdySerializedFrame connect_response(
+ spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
+ const char kWebSocketResponse[] =
+ "HTTP/1.1 101 Switching Protocols\r\n"
+ "Upgrade: websocket\r\n"
+ "Connection: Upgrade\r\n"
+ "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n";
+ SpdySerializedFrame websocket_response(
+ spdy_util_.ConstructSpdyDataFrame(1, kWebSocketResponse, false));
+ MockRead reads[] = {CreateMockRead(connect_response, 1),
+ CreateMockRead(websocket_response, 3),
+ MockRead(ASYNC, 0, 4)};
+
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
+
+ request_.url = GURL("wss://www.example.org/");
+ request_.extra_headers.SetHeader("Connection", "Upgrade");
+ request_.extra_headers.SetHeader("Upgrade", "websocket");
+ request_.extra_headers.SetHeader("Origin", "http://www.example.org");
+ request_.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
+ auto session_deps = std::make_unique<SpdySessionDependencies>(
+ ProxyResolutionService::CreateFixed("https://proxy:70",
+ TRAFFIC_ANNOTATION_FOR_TESTS));
+ NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
+ std::move(session_deps));
+ helper.RunPreTestSetup();
+ helper.AddData(&data);
+
+ // Add SSL data for the tunneled connection.
+ SSLSocketDataProvider ssl_provider(ASYNC, OK);
+ ssl_provider.ssl_info.cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
+ // A WebSocket request should not advertise HTTP/2 support.
+ ssl_provider.next_protos_expected_in_ssl_config = NextProtoVector{};
+ // This test uses WebSocket over HTTP/1.1.
+ ssl_provider.next_proto = kProtoHTTP11;
+ helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
+ &ssl_provider);
+
+ HttpNetworkTransaction* trans = helper.trans();
+ TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
+ trans->SetWebSocketHandshakeStreamCreateHelper(
+ &websocket_stream_create_helper);
+
+ EXPECT_TRUE(helper.StartDefaultTest());
+ helper.WaitForCallbackToComplete();
+ EXPECT_THAT(helper.output().rv, IsOk());
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
+ response->connection_info);
+ EXPECT_TRUE(response->was_alpn_negotiated);
+ EXPECT_FALSE(response->was_fetched_via_spdy);
+ EXPECT_EQ(70, response->socket_address.port());
+ ASSERT_TRUE(response->headers);
+ EXPECT_EQ("HTTP/1.1 101 Switching Protocols",
+ response->headers->GetStatusLine());
+
+ base::RunLoop().RunUntilIdle();
+ helper.VerifyDataConsumed();
+}
+
+// Regression test for https://crbug.com/828865.
+TEST_F(SpdyNetworkTransactionTest,
+ SecureWebSocketOverHttp2ProxyNegotiatesHttp2) {
+ SpdySerializedFrame connect_request(spdy_util_.ConstructSpdyConnect(
+ nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
+ MockWrite writes[] = {CreateMockWrite(connect_request, 0)};
+ SpdySerializedFrame connect_response(
+ spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
+ MockRead reads[] = {CreateMockRead(connect_response, 1),
+ MockRead(ASYNC, 0, 2)};
+ SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
+
+ request_.url = GURL("wss://www.example.org/");
+ request_.extra_headers.SetHeader("Connection", "Upgrade");
+ request_.extra_headers.SetHeader("Upgrade", "websocket");
+ request_.extra_headers.SetHeader("Origin", "http://www.example.org");
+ request_.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
+ auto session_deps = std::make_unique<SpdySessionDependencies>(
+ ProxyResolutionService::CreateFixed("https://proxy:70",
+ TRAFFIC_ANNOTATION_FOR_TESTS));
+ NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_,
+ std::move(session_deps));
+ helper.RunPreTestSetup();
+ helper.AddData(&data);
+
+ // Add SSL data for the tunneled connection.
+ SSLSocketDataProvider ssl_provider(ASYNC, OK);
+ ssl_provider.ssl_info.cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
+ // A WebSocket request should not advertise HTTP/2 support.
+ ssl_provider.next_protos_expected_in_ssl_config = NextProtoVector{};
+ // The server should not negotiate HTTP/2 over the tunnelled connection,
+ // but it must be handled gracefully if it does.
+ ssl_provider.next_proto = kProtoHTTP2;
+ helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
+ &ssl_provider);
+
+ HttpNetworkTransaction* trans = helper.trans();
+ TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
+ trans->SetWebSocketHandshakeStreamCreateHelper(
+ &websocket_stream_create_helper);
+
+ EXPECT_TRUE(helper.StartDefaultTest());
+ helper.WaitForCallbackToComplete();
+ EXPECT_THAT(helper.output().rv, IsError(ERR_NOT_IMPLEMENTED));
+
+ base::RunLoop().RunUntilIdle();
+ helper.VerifyDataConsumed();
+}
+
#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
} // namespace net
diff --git a/chromium/net/spdy/chromium/spdy_session.cc b/chromium/net/spdy/chromium/spdy_session.cc
index 588ba6f56af..7a89b554a2d 100644
--- a/chromium/net/spdy/chromium/spdy_session.cc
+++ b/chromium/net/spdy/chromium/spdy_session.cc
@@ -25,8 +25,7 @@
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "base/values.h"
-#include "crypto/ec_private_key.h"
-#include "crypto/ec_signature_creator.h"
+#include "net/base/url_util.h"
#include "net/cert/asn1_util.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/ct_policy_status.h"
@@ -152,7 +151,7 @@ enum PushedStreamVaryResponseHeaderValues ParseVaryInPushedResponse(
return kVaryHasNoAcceptEncoding;
}
-bool IsSpdySettingAtDefaultInitialValue(SpdyKnownSettingsId setting_id,
+bool IsSpdySettingAtDefaultInitialValue(SpdySettingsId setting_id,
uint32_t value) {
switch (setting_id) {
case SETTINGS_HEADER_TABLE_SIZE:
@@ -252,7 +251,7 @@ std::unique_ptr<base::Value> NetLogSpdySendSettingsCallback(
auto settings_list = std::make_unique<base::ListValue>();
for (SettingsMap::const_iterator it = settings->begin();
it != settings->end(); ++it) {
- const SpdyKnownSettingsId id = it->first;
+ const SpdySettingsId id = it->first;
const uint32_t value = it->second;
settings_list->AppendString(SpdyStringPrintf(
"[id:%u (%s) value:%u]", id, SettingsIdToString(id).c_str(), value));
@@ -262,7 +261,7 @@ std::unique_ptr<base::Value> NetLogSpdySendSettingsCallback(
}
std::unique_ptr<base::Value> NetLogSpdyRecvSettingCallback(
- SpdyKnownSettingsId id,
+ SpdySettingsId id,
uint32_t value,
NetLogCaptureMode /* capture_mode */) {
auto dict = std::make_unique<base::DictionaryValue>();
@@ -626,10 +625,11 @@ int SpdyStreamRequest::StartRequest(
DCHECK(!session_);
DCHECK(!stream_);
DCHECK(callback_.is_null());
+ DCHECK(url.is_valid()) << url.possibly_invalid_spec();
type_ = type;
session_ = session;
- url_ = url;
+ url_ = SimplifyUrlForRequest(url);
priority_ = priority;
socket_tag_ = socket_tag;
net_log_ = net_log;
@@ -1693,7 +1693,7 @@ void SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
}
// Cross-origin push validation.
- GURL associated_url(associated_it->second->GetUrlFromHeaders());
+ GURL associated_url(associated_it->second->url());
if (associated_url.GetOrigin() != gurl.GetOrigin()) {
if (is_trusted_proxy_) {
if (!gurl.SchemeIs(url::kHttpScheme)) {
@@ -1737,11 +1737,32 @@ void SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
stream_id),
base::TimeDelta::FromSeconds(kPushedStreamLifetimeSeconds));
- // TODO(https://crbug.com/656607): Add proper annotation here.
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("spdy_push_stream", R"(
+ semantics {
+ sender: "Spdy Session"
+ description:
+ "When a web server needs to push a response to a client, an "
+ "incoming stream is created to reply the client with pushed "
+ "message instead of a message from the network."
+ trigger:
+ "A request by a server to push a response to the client."
+ data: "None."
+ destination: OTHER
+ destination_other:
+ "This stream is not used for sending data."
+ }
+ policy {
+ cookies_allowed: NO
+ setting: "This feature cannot be disabled."
+ policy_exception_justification: "Essential for navigation."
+ }
+ )");
+
auto stream = std::make_unique<SpdyStream>(
SPDY_PUSH_STREAM, GetWeakPtr(), gurl, request_priority,
stream_initial_send_window_size_, stream_max_recv_window_size_, net_log_,
- NO_TRAFFIC_ANNOTATION_BUG_656607);
+ traffic_annotation);
stream->set_stream_id(stream_id);
// Convert RequestPriority to a SpdyPriority to send in a PRIORITY frame.
@@ -2901,7 +2922,7 @@ void SpdySession::OnSettingsAck() {
net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_SETTINGS_ACK);
}
-void SpdySession::OnSetting(SpdyKnownSettingsId id, uint32_t value) {
+void SpdySession::OnSetting(SpdySettingsId id, uint32_t value) {
CHECK(in_io_loop_);
HandleSetting(id, value);
diff --git a/chromium/net/spdy/chromium/spdy_session.h b/chromium/net/spdy/chromium/spdy_session.h
index 09fa118c041..54c16b443e3 100644
--- a/chromium/net/spdy/chromium/spdy_session.h
+++ b/chromium/net/spdy/chromium/spdy_session.h
@@ -53,6 +53,10 @@
#include "url/gurl.h"
#include "url/scheme_host_port.h"
+namespace crypto {
+class ECPrivateKey;
+}
+
namespace net {
namespace test {
@@ -782,7 +786,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface,
void OnStreamPadding(SpdyStreamId stream_id, size_t len) override;
void OnSettings() override;
void OnSettingsAck() override;
- void OnSetting(SpdyKnownSettingsId id, uint32_t value) override;
+ void OnSetting(SpdySettingsId id, uint32_t value) override;
void OnSettingsEnd() override {}
void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override;
void OnPushPromise(SpdyStreamId stream_id,
diff --git a/chromium/net/spdy/chromium/spdy_session_pool.cc b/chromium/net/spdy/chromium/spdy_session_pool.cc
index c1134e66364..50894382ec8 100644
--- a/chromium/net/spdy/chromium/spdy_session_pool.cc
+++ b/chromium/net/spdy/chromium/spdy_session_pool.cc
@@ -19,6 +19,7 @@
#include "net/base/trace_constants.h"
#include "net/http/http_network_session.h"
#include "net/http/http_server_properties.h"
+#include "net/http/http_stream_request.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_source.h"
#include "net/log/net_log_with_source.h"
@@ -149,17 +150,10 @@ base::WeakPtr<SpdySession> SpdySessionPool::FindAvailableSession(
net_log.AddEvent(
NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION,
it->second->net_log().source().ToEventParametersCallback());
- } else {
- if (!enable_ip_based_pooling) {
- // Remove session from available sessions and from aliases, and remove
- // key from the session's pooled alias set, so that a new session can be
- // created with this |key|.
- it->second->RemovePooledAlias(key);
- UnmapKey(key);
- RemoveAliases(key);
- return base::WeakPtr<SpdySession>();
- }
+ return it->second;
+ }
+ if (enable_ip_based_pooling) {
UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet",
FOUND_EXISTING_FROM_IP_POOL,
SPDY_SESSION_GET_MAX);
@@ -167,8 +161,16 @@ base::WeakPtr<SpdySession> SpdySessionPool::FindAvailableSession(
NetLogEventType::
HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL,
it->second->net_log().source().ToEventParametersCallback());
+ return it->second;
}
- return it->second;
+
+ // Remove session from available sessions and from aliases, and remove
+ // key from the session's pooled alias set, so that a new session can be
+ // created with this |key|.
+ it->second->RemovePooledAlias(key);
+ UnmapKey(key);
+ RemoveAliases(key);
+ return base::WeakPtr<SpdySession>();
}
if (!enable_ip_based_pooling)
@@ -403,7 +405,7 @@ void SpdySessionPool::OnNewSpdySessionReady(
auto iter = spdy_session_request_map_.find(spdy_session_key);
if (iter == spdy_session_request_map_.end())
return;
- HttpStreamFactoryImpl::Request* request = *iter->second.begin();
+ HttpStreamRequest* request = *iter->second.begin();
request->Complete(was_alpn_negotiated, negotiated_protocol, using_spdy);
RemoveRequestFromSpdySessionRequestMap(request);
if (request->stream_type() == HttpStreamRequest::BIDIRECTIONAL_STREAM) {
@@ -446,7 +448,7 @@ void SpdySessionPool::ResumePendingRequests(
void SpdySessionPool::AddRequestToSpdySessionRequestMap(
const SpdySessionKey& spdy_session_key,
- HttpStreamFactoryImpl::Request* request) {
+ HttpStreamRequest* request) {
if (request->HasSpdySessionKey())
return;
RequestSet& request_set = spdy_session_request_map_[spdy_session_key];
@@ -456,7 +458,7 @@ void SpdySessionPool::AddRequestToSpdySessionRequestMap(
}
void SpdySessionPool::RemoveRequestFromSpdySessionRequestMap(
- HttpStreamFactoryImpl::Request* request) {
+ HttpStreamRequest* request) {
if (!request->HasSpdySessionKey())
return;
const SpdySessionKey& spdy_session_key = request->GetSpdySessionKey();
diff --git a/chromium/net/spdy/chromium/spdy_session_pool.h b/chromium/net/spdy/chromium/spdy_session_pool.h
index 8de7365a172..84c185c7863 100644
--- a/chromium/net/spdy/chromium/spdy_session_pool.h
+++ b/chromium/net/spdy/chromium/spdy_session_pool.h
@@ -23,8 +23,8 @@
#include "net/base/network_change_notifier.h"
#include "net/base/proxy_server.h"
#include "net/cert/cert_database.h"
-#include "net/http/http_stream_factory_impl_request.h"
#include "net/proxy_resolution/proxy_config.h"
+#include "net/quic/core/quic_versions.h"
#include "net/spdy/chromium/http2_push_promise_index.h"
#include "net/spdy/chromium/server_push_delegate.h"
#include "net/spdy/chromium/spdy_session_key.h"
@@ -43,6 +43,7 @@ namespace net {
class ClientSocketHandle;
class HostResolver;
class HttpServerProperties;
+class HttpStreamRequest;
class NetLogWithSource;
class SpdySession;
class TransportSecurityState;
@@ -185,19 +186,17 @@ class NET_EXPORT SpdySessionPool
// Adds |request| to |spdy_session_request_map_| under |spdy_session_key| Key.
// Sets |spdy_session_key| as |request|'s SpdySessionKey.
- void AddRequestToSpdySessionRequestMap(
- const SpdySessionKey& spdy_session_key,
- HttpStreamFactoryImpl::Request* request);
+ void AddRequestToSpdySessionRequestMap(const SpdySessionKey& spdy_session_key,
+ HttpStreamRequest* request);
// Removes |request| from |spdy_session_request_map_|. No-op if |request| does
// not have a SpdySessionKey.
- void RemoveRequestFromSpdySessionRequestMap(
- HttpStreamFactoryImpl::Request* request);
+ void RemoveRequestFromSpdySessionRequestMap(HttpStreamRequest* request);
private:
friend class SpdySessionPoolPeer; // For testing.
- typedef std::set<HttpStreamFactoryImpl::Request*> RequestSet;
+ typedef std::set<HttpStreamRequest*> RequestSet;
typedef std::map<SpdySessionKey, RequestSet> SpdySessionRequestMap;
typedef std::set<SpdySession*> SessionSet;
typedef std::vector<base::WeakPtr<SpdySession> > WeakSessionList;
diff --git a/chromium/net/spdy/chromium/spdy_session_pool_unittest.cc b/chromium/net/spdy/chromium/spdy_session_pool_unittest.cc
index 870052ba649..3f35d1e59a2 100644
--- a/chromium/net/spdy/chromium/spdy_session_pool_unittest.cc
+++ b/chromium/net/spdy/chromium/spdy_session_pool_unittest.cc
@@ -178,13 +178,12 @@ TEST_F(SpdySessionPoolTest, CloseCurrentIdleSessions) {
CreateNetworkSession();
// Set up session 1
- const SpdyString kTestHost1("www.example.org");
- HostPortPair test_host_port_pair1(kTestHost1, 80);
+ const GURL url1("https://www.example.org");
+ HostPortPair test_host_port_pair1(HostPortPair::FromURL(url1));
SpdySessionKey key1(test_host_port_pair1, ProxyServer::Direct(),
PRIVACY_MODE_DISABLED, SocketTag());
base::WeakPtr<SpdySession> session1 =
CreateSpdySession(http_session_.get(), key1, NetLogWithSource());
- GURL url1(kTestHost1);
base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
SPDY_BIDIRECTIONAL_STREAM, session1, url1, MEDIUM, NetLogWithSource());
ASSERT_TRUE(spdy_stream1);
@@ -193,13 +192,12 @@ TEST_F(SpdySessionPoolTest, CloseCurrentIdleSessions) {
StaticSocketDataProvider data2(reads, arraysize(reads), nullptr, 0);
data2.set_connect_data(connect_data);
session_deps_.socket_factory->AddSocketDataProvider(&data2);
- const SpdyString kTestHost2("mail.example.org");
- HostPortPair test_host_port_pair2(kTestHost2, 80);
+ const GURL url2("https://mail.example.org");
+ HostPortPair test_host_port_pair2(HostPortPair::FromURL(url2));
SpdySessionKey key2(test_host_port_pair2, ProxyServer::Direct(),
PRIVACY_MODE_DISABLED, SocketTag());
base::WeakPtr<SpdySession> session2 =
CreateSpdySession(http_session_.get(), key2, NetLogWithSource());
- GURL url2(kTestHost2);
base::WeakPtr<SpdyStream> spdy_stream2 = CreateStreamSynchronously(
SPDY_BIDIRECTIONAL_STREAM, session2, url2, MEDIUM, NetLogWithSource());
ASSERT_TRUE(spdy_stream2);
@@ -208,13 +206,12 @@ TEST_F(SpdySessionPoolTest, CloseCurrentIdleSessions) {
StaticSocketDataProvider data3(reads, arraysize(reads), nullptr, 0);
data3.set_connect_data(connect_data);
session_deps_.socket_factory->AddSocketDataProvider(&data3);
- const SpdyString kTestHost3("mail.example.com");
- HostPortPair test_host_port_pair3(kTestHost3, 80);
+ const GURL url3("https://mail.example.com");
+ HostPortPair test_host_port_pair3(HostPortPair::FromURL(url3));
SpdySessionKey key3(test_host_port_pair3, ProxyServer::Direct(),
PRIVACY_MODE_DISABLED, SocketTag());
base::WeakPtr<SpdySession> session3 =
CreateSpdySession(http_session_.get(), key3, NetLogWithSource());
- GURL url3(kTestHost3);
base::WeakPtr<SpdyStream> spdy_stream3 = CreateStreamSynchronously(
SPDY_BIDIRECTIONAL_STREAM, session3, url3, MEDIUM, NetLogWithSource());
ASSERT_TRUE(spdy_stream3);
@@ -347,7 +344,7 @@ void SpdySessionPoolTest::RunIPPoolingTest(
SpdySessionKey key;
AddressList addresses;
} test_hosts[] = {
- {"http:://www.example.org", "www.example.org",
+ {"http://www.example.org", "www.example.org",
"192.0.2.33,192.168.0.1,192.168.0.5"},
{"http://mail.example.org", "mail.example.org",
"192.168.0.2,192.168.0.3,192.168.0.5,192.0.2.33"},
diff --git a/chromium/net/spdy/chromium/spdy_session_unittest.cc b/chromium/net/spdy/chromium/spdy_session_unittest.cc
index bc40c21675b..37d53b40cd7 100644
--- a/chromium/net/spdy/chromium/spdy_session_unittest.cc
+++ b/chromium/net/spdy/chromium/spdy_session_unittest.cc
@@ -52,6 +52,7 @@
using net::test::IsError;
using net::test::IsOk;
using net::test::TestServerPushDelegate;
+using testing::_;
namespace net {
@@ -84,7 +85,10 @@ base::TimeTicks InstantaneousReads() {
class MockRequireCTDelegate : public TransportSecurityState::RequireCTDelegate {
public:
- MOCK_METHOD1(IsCTRequiredForHost, CTRequirementLevel(const SpdyString& host));
+ MOCK_METHOD3(IsCTRequiredForHost,
+ CTRequirementLevel(const std::string& host,
+ const X509Certificate* chain,
+ const HashValueVector& hashes));
};
} // namespace
@@ -1927,12 +1931,11 @@ TEST_F(SpdySessionTest, WaitingForWrongPing) {
TEST_F(SpdySessionTest, OnSettings) {
session_deps_.host_resolver->set_synchronous_mode(true);
- const SpdyKnownSettingsId kSpdyKnownSettingsId =
- SETTINGS_MAX_CONCURRENT_STREAMS;
+ const SpdySettingsId kSpdySettingsId = SETTINGS_MAX_CONCURRENT_STREAMS;
SettingsMap new_settings;
const uint32_t max_concurrent_streams = kInitialMaxConcurrentStreams + 1;
- new_settings[kSpdyKnownSettingsId] = max_concurrent_streams;
+ new_settings[kSpdySettingsId] = max_concurrent_streams;
SpdySerializedFrame settings_frame(
spdy_util_.ConstructSpdySettings(new_settings));
MockRead reads[] = {
@@ -2726,10 +2729,9 @@ TEST_F(SpdySessionTest, CloseTwoStalledCreateStream) {
// TODO(rtenneti): Define a helper class/methods and move the common code in
// this file.
SettingsMap new_settings;
- const SpdyKnownSettingsId kSpdyKnownSettingsId1 =
- SETTINGS_MAX_CONCURRENT_STREAMS;
+ const SpdySettingsId kSpdySettingsId1 = SETTINGS_MAX_CONCURRENT_STREAMS;
const uint32_t max_concurrent_streams = 1;
- new_settings[kSpdyKnownSettingsId1] = max_concurrent_streams;
+ new_settings[kSpdySettingsId1] = max_concurrent_streams;
SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
SpdySerializedFrame req1(spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
@@ -4477,7 +4479,7 @@ void SpdySessionTest::RunResumeAfterUnstallTest(
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
EXPECT_EQ(ERR_IO_PENDING,
stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
stall_function.Run(stream.get());
@@ -4614,7 +4616,7 @@ TEST_F(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) {
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1),
MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream1->GetUrlFromHeaders().spec());
+ EXPECT_EQ(kDefaultUrl, stream1->url().spec());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, stream1->stream_id());
@@ -4624,7 +4626,7 @@ TEST_F(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) {
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2),
MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream2->GetUrlFromHeaders().spec());
+ EXPECT_EQ(kDefaultUrl, stream2->url().spec());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(3u, stream2->stream_id());
@@ -4718,7 +4720,7 @@ TEST_F(SpdySessionTest, ResumeSessionWithStalledStream) {
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1),
MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream1->GetUrlFromHeaders().spec());
+ EXPECT_EQ(kDefaultUrl, stream1->url().spec());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, stream1->stream_id());
@@ -4728,7 +4730,7 @@ TEST_F(SpdySessionTest, ResumeSessionWithStalledStream) {
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2),
MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream2->GetUrlFromHeaders().spec());
+ EXPECT_EQ(kDefaultUrl, stream2->url().spec());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(3u, stream2->stream_id());
@@ -4870,7 +4872,7 @@ TEST_F(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1),
MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream1->GetUrlFromHeaders().spec());
+ EXPECT_EQ(kDefaultUrl, stream1->url().spec());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, stream1->stream_id());
@@ -4880,7 +4882,7 @@ TEST_F(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2),
MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream2->GetUrlFromHeaders().spec());
+ EXPECT_EQ(kDefaultUrl, stream2->url().spec());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(3u, stream2->stream_id());
@@ -4890,7 +4892,7 @@ TEST_F(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
EXPECT_EQ(ERR_IO_PENDING, stream3->SendRequestHeaders(std::move(headers3),
MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream3->GetUrlFromHeaders().spec());
+ EXPECT_EQ(kDefaultUrl, stream3->url().spec());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(5u, stream3->stream_id());
@@ -4995,7 +4997,7 @@ TEST_F(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1),
MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream1->GetUrlFromHeaders().spec());
+ EXPECT_EQ(kDefaultUrl, stream1->url().spec());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, stream1->stream_id());
@@ -5005,7 +5007,7 @@ TEST_F(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2),
MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream2->GetUrlFromHeaders().spec());
+ EXPECT_EQ(kDefaultUrl, stream2->url().spec());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(3u, stream2->stream_id());
@@ -6024,15 +6026,15 @@ TEST_F(SendInitialSettingsOnNewSpdySessionTest, OverwriteValues) {
// Unknown parameters should still be sent to the server.
TEST_F(SendInitialSettingsOnNewSpdySessionTest, UnknownSettings) {
// The following parameters are not defined in the HTTP/2 specification.
- session_deps_.http2_settings[static_cast<SpdyKnownSettingsId>(7)] = 1234;
- session_deps_.http2_settings[static_cast<SpdyKnownSettingsId>(25)] = 5678;
+ session_deps_.http2_settings[7] = 1234;
+ session_deps_.http2_settings[25] = 5678;
SettingsMap expected_settings;
expected_settings[SETTINGS_HEADER_TABLE_SIZE] = kSpdyMaxHeaderTableSize;
expected_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
kSpdyMaxConcurrentPushedStreams;
- expected_settings[static_cast<SpdyKnownSettingsId>(7)] = 1234;
- expected_settings[static_cast<SpdyKnownSettingsId>(25)] = 5678;
+ expected_settings[7] = 1234;
+ expected_settings[25] = 5678;
RunInitialSettingsTest(expected_settings);
}
@@ -6555,9 +6557,10 @@ TEST(CanPoolTest, CanNotPoolWithBadCTWhenCTRequired) {
ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
MockRequireCTDelegate require_ct_delegate;
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost("www.example.org"))
+ EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost("www.example.org", _, _))
.WillRepeatedly(Return(CTRequirementLevel::NOT_REQUIRED));
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost("mail.example.org"))
+ EXPECT_CALL(require_ct_delegate,
+ IsCTRequiredForHost("mail.example.org", _, _))
.WillRepeatedly(Return(CTRequirementLevel::REQUIRED));
TransportSecurityState tss;
@@ -6581,9 +6584,10 @@ TEST(CanPoolTest, CanPoolWithBadCTWhenCTNotRequired) {
ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
MockRequireCTDelegate require_ct_delegate;
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost("www.example.org"))
+ EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost("www.example.org", _, _))
.WillRepeatedly(Return(CTRequirementLevel::NOT_REQUIRED));
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost("mail.example.org"))
+ EXPECT_CALL(require_ct_delegate,
+ IsCTRequiredForHost("mail.example.org", _, _))
.WillRepeatedly(Return(CTRequirementLevel::NOT_REQUIRED));
TransportSecurityState tss;
@@ -6607,9 +6611,10 @@ TEST(CanPoolTest, CanPoolWithGoodCTWhenCTRequired) {
ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS;
MockRequireCTDelegate require_ct_delegate;
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost("www.example.org"))
+ EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost("www.example.org", _, _))
.WillRepeatedly(Return(CTRequirementLevel::NOT_REQUIRED));
- EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost("mail.example.org"))
+ EXPECT_CALL(require_ct_delegate,
+ IsCTRequiredForHost("mail.example.org", _, _))
.WillRepeatedly(Return(CTRequirementLevel::REQUIRED));
TransportSecurityState tss;
diff --git a/chromium/net/spdy/chromium/spdy_stream.cc b/chromium/net/spdy/chromium/spdy_stream.cc
index 5c38ee45f64..dee8a868ff5 100644
--- a/chromium/net/spdy/chromium/spdy_stream.cc
+++ b/chromium/net/spdy/chromium/spdy_stream.cc
@@ -392,9 +392,13 @@ void SpdyStream::OnHeadersReceived(const SpdyHeaderBlock& response_headers,
return;
}
- // Ignore informational headers.
+ // Ignore informational headers like 103 Early Hints.
// TODO(bnc): Add support for 103 Early Hints, https://crbug.com/671310.
- if (status / 100 == 1) {
+ // However, do not ignore 101 Switching Protocols, because broken
+ // servers might send this as a response to a WebSocket request,
+ // in which case it needs to pass through so that the WebSocket layer
+ // can signal an error.
+ if (status / 100 == 1 && status != 101) {
return;
}
}
@@ -473,7 +477,6 @@ void SpdyStream::OnPushPromiseHeadersReceived(SpdyHeaderBlock headers,
io_state_ = STATE_RESERVED_REMOTE;
request_headers_ = std::move(headers);
request_headers_valid_ = true;
- url_from_header_block_ = std::move(url);
}
void SpdyStream::OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) {
@@ -706,7 +709,6 @@ int SpdyStream::SendRequestHeaders(SpdyHeaderBlock request_headers,
CHECK_EQ(io_state_, STATE_IDLE);
request_headers_ = std::move(request_headers);
request_headers_valid_ = true;
- url_from_header_block_ = GetUrlFromHeaderBlock(request_headers_);
pending_send_status_ = send_status;
session_->EnqueueStreamWrite(
GetWeakPtr(), SpdyFrameType::HEADERS,
@@ -731,6 +733,12 @@ bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info) const {
return session_->GetSSLInfo(ssl_info);
}
+Error SpdyStream::GetTokenBindingSignature(crypto::ECPrivateKey* key,
+ TokenBindingType tb_type,
+ std::vector<uint8_t>* out) const {
+ return session_->GetTokenBindingSignature(key, tb_type, out);
+}
+
bool SpdyStream::WasAlpnNegotiated() const {
return session_->WasAlpnNegotiated();
}
@@ -801,7 +809,6 @@ size_t SpdyStream::EstimateMemoryUsage() const {
// once scoped_refptr support is in.
return SpdyEstimateMemoryUsage(url_) +
SpdyEstimateMemoryUsage(request_headers_) +
- SpdyEstimateMemoryUsage(url_from_header_block_) +
SpdyEstimateMemoryUsage(pending_recv_data_) +
SpdyEstimateMemoryUsage(response_headers_);
}
diff --git a/chromium/net/spdy/chromium/spdy_stream.h b/chromium/net/spdy/chromium/spdy_stream.h
index a47deebc30a..8095dc2c305 100644
--- a/chromium/net/spdy/chromium/spdy_stream.h
+++ b/chromium/net/spdy/chromium/spdy_stream.h
@@ -28,9 +28,14 @@
#include "net/spdy/core/spdy_protocol.h"
#include "net/spdy/platform/api/spdy_string.h"
#include "net/ssl/ssl_client_cert_type.h"
+#include "net/ssl/token_binding.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"
+namespace crypto {
+class ECPrivateKey;
+}
+
namespace net {
class IPEndPoint;
@@ -329,6 +334,13 @@ class NET_EXPORT_PRIVATE SpdyStream {
// Fills SSL info in |ssl_info| and returns true when SSL is in use.
bool GetSSLInfo(SSLInfo* ssl_info) const;
+ // Generates the signature used in Token Binding using |*key| and for a Token
+ // Binding of type |tb_type|, putting the signature in |*out|. Returns OK or
+ // ERR_FAILED.
+ Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
+ TokenBindingType tb_type,
+ std::vector<uint8_t>* out) const;
+
// Returns true if ALPN was negotiated for the underlying socket.
bool WasAlpnNegotiated() const;
@@ -379,10 +391,6 @@ class NET_EXPORT_PRIVATE SpdyStream {
const SpdyHeaderBlock& request_headers() { return request_headers_; }
- // Get the URL from the appropriate stream headers, or the empty
- // GURL() if it is unknown.
- const GURL& GetUrlFromHeaders() const { return url_from_header_block_; }
-
// Returns the estimate of dynamically allocated memory in bytes.
size_t EstimateMemoryUsage() const;
@@ -484,9 +492,6 @@ class NET_EXPORT_PRIVATE SpdyStream {
bool request_headers_valid_;
SpdyHeaderBlock request_headers_;
- // The URL from the request headers.
- GURL url_from_header_block_;
-
// Data waiting to be sent, and the close state of the local endpoint
// after the data is fully written.
scoped_refptr<DrainableIOBuffer> pending_send_data_;
diff --git a/chromium/net/spdy/chromium/spdy_stream_unittest.cc b/chromium/net/spdy/chromium/spdy_stream_unittest.cc
index dfdba6a9a1b..bc1ea24cbb5 100644
--- a/chromium/net/spdy/chromium/spdy_stream_unittest.cc
+++ b/chromium/net/spdy/chromium/spdy_stream_unittest.cc
@@ -192,17 +192,15 @@ TEST_F(SpdyStreamTest, SendDataAfterOpen) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
@@ -270,17 +268,15 @@ TEST_F(SpdyStreamTest, Trailers) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateWithTrailers delegate(stream, kPostBodyStringPiece);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
@@ -339,17 +335,15 @@ TEST_F(SpdyStreamTest, PushedStream) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateDoNothing delegate(stream);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
EXPECT_THAT(
stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
data.RunUntilPaused();
@@ -372,7 +366,7 @@ TEST_F(SpdyStreamTest, PushedStream) {
&push_stream, NetLogWithSource()),
IsOk());
ASSERT_TRUE(push_stream);
- EXPECT_EQ(kPushUrl, push_stream->GetUrlFromHeaders().spec());
+ EXPECT_EQ(kPushUrl, push_stream->url().spec());
LoadTimingInfo load_timing_info;
EXPECT_TRUE(push_stream->GetLoadTimingInfo(&load_timing_info));
@@ -430,17 +424,15 @@ TEST_F(SpdyStreamTest, StreamError) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, log.bound());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
@@ -501,18 +493,16 @@ TEST_F(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
SpdyString body_data(3 * kMaxSpdyFrameChunkSize, 'x');
StreamDelegateWithBody delegate(stream, body_data);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
@@ -554,18 +544,16 @@ TEST_F(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
SpdyString body_data(3 * kMaxSpdyFrameChunkSize, 'x');
StreamDelegateSendImmediate delegate(stream, body_data);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
@@ -604,17 +592,15 @@ TEST_F(SpdyStreamTest, UpperCaseHeaders) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateDoNothing delegate(stream);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
EXPECT_THAT(
stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
@@ -664,17 +650,15 @@ TEST_F(SpdyStreamTest, UpperCaseHeadersOnPush) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateDoNothing delegate(stream);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
EXPECT_THAT(
stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
data.RunUntilPaused();
@@ -721,16 +705,14 @@ TEST_F(SpdyStreamTest, HeadersMustHaveStatus) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateDoNothing delegate(stream);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
NO_MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
@@ -789,17 +771,15 @@ TEST_F(SpdyStreamTest, HeadersMustHaveStatusOnPushedStream) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateDoNothing delegate(stream);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
EXPECT_THAT(
stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsOk());
EXPECT_EQ("200", delegate.GetResponseHeaderValue(kHttp2StatusHeader));
@@ -841,16 +821,14 @@ TEST_F(SpdyStreamTest, HeadersMustPreceedData) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateDoNothing delegate(stream);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
NO_MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
}
@@ -897,17 +875,15 @@ TEST_F(SpdyStreamTest, HeadersMustPreceedDataOnPushedStream) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateDoNothing delegate(stream);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
EXPECT_THAT(
stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsOk());
EXPECT_EQ("200", delegate.GetResponseHeaderValue(kHttp2StatusHeader));
@@ -962,16 +938,14 @@ TEST_F(SpdyStreamTest, TrailersMustNotFollowTrailers) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateDoNothing delegate(stream);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
NO_MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
@@ -1021,16 +995,14 @@ TEST_F(SpdyStreamTest, DataMustNotFollowTrailers) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateDoNothing delegate(stream);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
NO_MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
@@ -1074,16 +1046,14 @@ TEST_F(SpdyStreamTest, InformationalHeaders) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateDoNothing delegate(stream);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
NO_MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsOk());
EXPECT_EQ("200", delegate.GetResponseHeaderValue(kHttp2StatusHeader));
@@ -1126,16 +1096,14 @@ TEST_F(SpdyStreamTest, StatusMustBeNumber) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateDoNothing delegate(stream);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
NO_MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
@@ -1180,16 +1148,14 @@ TEST_F(SpdyStreamTest, StatusCannotHaveExtraText) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateDoNothing delegate(stream);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
NO_MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
@@ -1232,16 +1198,14 @@ TEST_F(SpdyStreamTest, StatusMustBePresent) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateDoNothing delegate(stream);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers),
NO_MORE_DATA_TO_SEND));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
@@ -1284,6 +1248,8 @@ TEST_F(SpdyStreamTest, IncreaseSendWindowSizeOverflow) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, log.bound());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
+
StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
stream->SetDelegate(&delegate);
@@ -1291,7 +1257,6 @@ TEST_F(SpdyStreamTest, IncreaseSendWindowSizeOverflow) {
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
data.RunUntilPaused();
@@ -1369,18 +1334,17 @@ void SpdyStreamTest::RunResumeAfterUnstallRequestResponseTest(
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateWithBody delegate(stream, kPostBodyStringPiece);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
EXPECT_FALSE(stream->send_stalled_by_flow_control());
SpdyHeaderBlock headers(
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
StallStream(stream);
@@ -1446,17 +1410,15 @@ void SpdyStreamTest::RunResumeAfterUnstallBidirectionalTest(
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
data.RunUntilPaused();
@@ -1525,17 +1487,15 @@ TEST_F(SpdyStreamTest, ReceivedBytes) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_REQUEST_RESPONSE_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateDoNothing delegate(stream);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
EXPECT_THAT(
stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND),
IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
int64_t reply_frame_len = reply.size();
int64_t data_header_len = kDataFrameMinimumSize;
@@ -1598,17 +1558,15 @@ TEST_F(SpdyStreamTest, DataOnHalfClosedRemoveStream) {
base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
SPDY_BIDIRECTIONAL_STREAM, session, url_, LOWEST, NetLogWithSource());
ASSERT_TRUE(stream);
+ EXPECT_EQ(kDefaultUrl, stream->url().spec());
StreamDelegateDoNothing delegate(stream);
stream->SetDelegate(&delegate);
- EXPECT_TRUE(stream->GetUrlFromHeaders().is_empty());
-
SpdyHeaderBlock headers(
spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kPostBodyLength));
EXPECT_THAT(stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND),
IsError(ERR_IO_PENDING));
- EXPECT_EQ(kDefaultUrl, stream->GetUrlFromHeaders().spec());
EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_PROTOCOL_ERROR));
diff --git a/chromium/net/spdy/chromium/spdy_test_util_common.cc b/chromium/net/spdy/chromium/spdy_test_util_common.cc
index ff573aba4b5..ed115348ad3 100644
--- a/chromium/net/spdy/chromium/spdy_test_util_common.cc
+++ b/chromium/net/spdy/chromium/spdy_test_util_common.cc
@@ -7,6 +7,7 @@
#include <cstddef>
#include <utility>
+#include "base/base64.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
@@ -99,8 +100,7 @@ void AppendToHeaderBlock(const char* const extra_headers[],
for (int i = 0; i < extra_header_count; i++) {
SpdyStringPiece key(extra_headers[i * 2]);
SpdyStringPiece value(extra_headers[i * 2 + 1]);
- DCHECK(!key.empty()) << "Empty header key.";
- DCHECK(!value.empty()) << "Empty header value.";
+ DCHECK(!key.empty()) << "Header key must not be empty.";
headers->AppendValueOrAddHeader(key, value);
}
}
@@ -190,7 +190,7 @@ class PriorityGetter : public BufferedSpdyFramerVisitorInterface {
void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {}
void OnSettings() override {}
void OnSettingsAck() override {}
- void OnSetting(SpdyKnownSettingsId id, uint32_t value) override {}
+ void OnSetting(SpdySettingsId id, uint32_t value) override {}
void OnSettingsEnd() override {}
void OnPing(SpdyPingId unique_id, bool is_ack) override {}
void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override {}
@@ -1059,4 +1059,55 @@ SpdyHeaderBlock SpdyTestUtil::ConstructHeaderBlock(SpdyStringPiece method,
return headers;
}
+namespace test {
+HashValue GetTestHashValue(uint8_t label) {
+ HashValue hash_value(HASH_VALUE_SHA256);
+ memset(hash_value.data(), label, hash_value.size());
+ return hash_value;
+}
+
+SpdyString GetTestPin(uint8_t label) {
+ HashValue hash_value = GetTestHashValue(label);
+ SpdyString base64;
+ base::Base64Encode(SpdyStringPiece(reinterpret_cast<char*>(hash_value.data()),
+ hash_value.size()),
+ &base64);
+
+ return SpdyString("pin-sha256=\"") + base64 + "\"";
+}
+
+void AddPin(TransportSecurityState* state,
+ const SpdyString& host,
+ uint8_t primary_label,
+ uint8_t backup_label) {
+ SpdyString primary_pin = GetTestPin(primary_label);
+ SpdyString backup_pin = GetTestPin(backup_label);
+ SpdyString header = "max-age = 10000; " + primary_pin + "; " + backup_pin;
+
+ // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
+ SSLInfo ssl_info;
+ ssl_info.is_issued_by_known_root = true;
+ ssl_info.public_key_hashes.push_back(GetTestHashValue(primary_label));
+ EXPECT_TRUE(state->AddHPKPHeader(host, header, ssl_info));
+}
+
+TestServerPushDelegate::TestServerPushDelegate() = default;
+
+TestServerPushDelegate::~TestServerPushDelegate() = default;
+
+void TestServerPushDelegate::OnPush(
+ std::unique_ptr<ServerPushHelper> push_helper,
+ const NetLogWithSource& session_net_log) {
+ push_helpers[push_helper->GetURL()] = std::move(push_helper);
+}
+
+bool TestServerPushDelegate::CancelPush(GURL url) {
+ auto itr = push_helpers.find(url);
+ DCHECK(itr != push_helpers.end());
+ itr->second->Cancel();
+ push_helpers.erase(itr);
+ return true;
+}
+
+} // namespace test
} // namespace net
diff --git a/chromium/net/spdy/chromium/spdy_test_util_common.h b/chromium/net/spdy/chromium/spdy_test_util_common.h
index c7187b38457..44e01782750 100644
--- a/chromium/net/spdy/chromium/spdy_test_util_common.h
+++ b/chromium/net/spdy/chromium/spdy_test_util_common.h
@@ -29,7 +29,7 @@
#include "net/http/http_response_info.h"
#include "net/http/http_server_properties_impl.h"
#include "net/http/transport_security_state.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/socket/socket_test_util.h"
#include "net/spdy/chromium/spdy_session.h"
#include "net/spdy/core/spdy_protocol.h"
@@ -46,12 +46,14 @@ namespace net {
class CTVerifier;
class CTPolicyEnforcer;
+class HashValue;
class HostPortPair;
class NetLogWithSource;
class SpdySessionKey;
class SpdySessionPool;
class SpdyStream;
class SpdyStreamRequest;
+class TransportSecurityState;
// Default upload data used by both, mock objects and framer when creating
// data frames.
@@ -495,6 +497,38 @@ class SpdyTestUtil {
std::map<int, std::vector<int>> priority_to_stream_id_list_;
};
+namespace test {
+
+// Returns a SHA1 HashValue in which each byte has the value |label|.
+HashValue GetTestHashValue(uint8_t label);
+
+// Returns SHA1 pinning header for the of the base64 encoding of
+// GetTestHashValue(|label|).
+SpdyString GetTestPin(uint8_t label);
+
+// Adds a pin for |host| to |state|.
+void AddPin(TransportSecurityState* state,
+ const SpdyString& host,
+ uint8_t primary_label,
+ uint8_t backup_label);
+
+// A test implementation of ServerPushDelegate that caches all the pushed
+// request and provides a interface to cancel the push given url.
+class TestServerPushDelegate : public ServerPushDelegate {
+ public:
+ TestServerPushDelegate();
+ ~TestServerPushDelegate() override;
+
+ void OnPush(std::unique_ptr<ServerPushHelper> push_helper,
+ const NetLogWithSource& session_net_log) override;
+
+ bool CancelPush(GURL url);
+
+ private:
+ std::map<GURL, std::unique_ptr<ServerPushHelper>> push_helpers;
+};
+
+} // namespace test
} // namespace net
#endif // NET_SPDY_CHROMIUM_SPDY_TEST_UTIL_COMMON_H_
diff --git a/chromium/net/spdy/core/hpack/hpack_encoder.cc b/chromium/net/spdy/core/hpack/hpack_encoder.cc
index 824b0a3e3eb..09c4d08802c 100644
--- a/chromium/net/spdy/core/hpack/hpack_encoder.cc
+++ b/chromium/net/spdy/core/hpack/hpack_encoder.cc
@@ -85,12 +85,6 @@ HpackEncoder::HpackEncoder(const HpackHuffmanTable& table)
HpackEncoder::~HpackEncoder() = default;
-void HpackEncoder::EncodeHeaderSet(const Representations& representations,
- SpdyString* output) {
- RepresentationIterator iter(representations);
- EncodeRepresentations(&iter, output);
-}
-
bool HpackEncoder::EncodeHeaderSet(const SpdyHeaderBlock& header_set,
SpdyString* output) {
// Separate header set into pseudo-headers and regular headers.
diff --git a/chromium/net/spdy/core/hpack/hpack_encoder.h b/chromium/net/spdy/core/hpack/hpack_encoder.h
index 030afa5d2b1..aa60045d0af 100644
--- a/chromium/net/spdy/core/hpack/hpack_encoder.h
+++ b/chromium/net/spdy/core/hpack/hpack_encoder.h
@@ -50,10 +50,6 @@ class SPDY_EXPORT_PRIVATE HpackEncoder {
explicit HpackEncoder(const HpackHuffmanTable& table);
~HpackEncoder();
- // Encodes a sequence of Representations into the given string.
- void EncodeHeaderSet(const Representations& representations,
- SpdyString* output);
-
// Encodes the given header set into the given string. Returns
// whether or not the encoding was successful.
bool EncodeHeaderSet(const SpdyHeaderBlock& header_set, SpdyString* output);
diff --git a/chromium/net/spdy/core/hpack/hpack_entry.cc b/chromium/net/spdy/core/hpack/hpack_entry.cc
index a948877cd6d..84e21f5f54b 100644
--- a/chromium/net/spdy/core/hpack/hpack_entry.cc
+++ b/chromium/net/spdy/core/hpack/hpack_entry.cc
@@ -7,6 +7,7 @@
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "net/spdy/platform/api/spdy_estimate_memory_usage.h"
+#include "net/spdy/platform/api/spdy_string_utils.h"
namespace net {
@@ -75,11 +76,10 @@ size_t HpackEntry::Size() const {
}
SpdyString HpackEntry::GetDebugString() const {
- return "{ name: \"" + SpdyString(name_ref_) + "\", value: \"" +
- SpdyString(value_ref_) +
- "\", index: " + base::NumberToString(insertion_index_) +
- (IsStatic() ? " static" : (IsLookup() ? " lookup" : " dynamic")) +
- " }";
+ return SpdyStringPrintf(
+ "{ name: \"%.*s\", value: \"%.*s\", index: %d %s }", name_ref_.size(),
+ name_ref_.data(), value_ref_.size(), value_ref_.data(), insertion_index_,
+ (IsStatic() ? " static" : (IsLookup() ? " lookup" : " dynamic")));
}
size_t HpackEntry::EstimateMemoryUsage() const {
diff --git a/chromium/net/spdy/core/http2_frame_decoder_adapter.cc b/chromium/net/spdy/core/http2_frame_decoder_adapter.cc
index 2922d8fa5e4..288dd45599c 100644
--- a/chromium/net/spdy/core/http2_frame_decoder_adapter.cc
+++ b/chromium/net/spdy/core/http2_frame_decoder_adapter.cc
@@ -34,6 +34,7 @@
#include "net/spdy/core/spdy_headers_handler_interface.h"
#include "net/spdy/core/spdy_protocol.h"
#include "net/spdy/platform/api/spdy_estimate_memory_usage.h"
+#include "net/spdy/platform/api/spdy_flags.h"
#include "net/spdy/platform/api/spdy_ptr_util.h"
#include "net/spdy/platform/api/spdy_string_utils.h"
@@ -474,16 +475,23 @@ void Http2DecoderAdapter::OnSettingsStart(const Http2FrameHeader& header) {
void Http2DecoderAdapter::OnSetting(const Http2SettingFields& setting_fields) {
DVLOG(1) << "OnSetting: " << setting_fields;
const auto parameter = static_cast<SpdySettingsId>(setting_fields.parameter);
+ if (GetSpdyRestartFlag(http2_propagate_unknown_settings)) {
+ visitor()->OnSetting(parameter, setting_fields.value);
+ if (extension_ != nullptr) {
+ extension_->OnSetting(parameter, setting_fields.value);
+ }
+ return;
+ }
SpdyKnownSettingsId setting_id;
if (!ParseSettingsId(parameter, &setting_id)) {
if (extension_ == nullptr) {
- DVLOG(1) << "Ignoring unknown setting id: " << setting_fields;
+ DVLOG(1) << "No extension for unknown setting id: " << setting_fields;
} else {
extension_->OnSetting(parameter, setting_fields.value);
}
return;
}
- visitor()->OnSetting(setting_id, setting_fields.value);
+ visitor()->OnSettingOld(setting_id, setting_fields.value);
}
void Http2DecoderAdapter::OnSettingsEnd() {
diff --git a/chromium/net/spdy/core/http2_frame_decoder_adapter.h b/chromium/net/spdy/core/http2_frame_decoder_adapter.h
index b8cf74101e3..65276416901 100644
--- a/chromium/net/spdy/core/http2_frame_decoder_adapter.h
+++ b/chromium/net/spdy/core/http2_frame_decoder_adapter.h
@@ -396,7 +396,13 @@ class SPDY_EXPORT_PRIVATE SpdyFramerVisitorInterface {
// Called when a complete setting within a SETTINGS frame has been parsed and
// validated.
- virtual void OnSetting(SpdyKnownSettingsId id, uint32_t value) = 0;
+ // TODO(diannahu): Remove with deprecation of
+ // GetSpdyRestartFlag(http2_propagate_unknown_settings).
+ virtual void OnSettingOld(SpdyKnownSettingsId id, uint32_t value) = 0;
+
+ // Called when a complete setting within a SETTINGS frame has been parsed.
+ // Note that |id| may or may not be a SETTINGS ID defined in the HTTP/2 spec.
+ virtual void OnSetting(SpdySettingsId id, uint32_t value) = 0;
// Called when a SETTINGS frame is received with the ACK flag set.
virtual void OnSettingsAck() {}
@@ -485,7 +491,7 @@ class SPDY_EXPORT_PRIVATE ExtensionVisitorInterface {
public:
virtual ~ExtensionVisitorInterface() {}
- // Called when non-standard SETTINGS are received.
+ // Called when SETTINGS are received, including non-standard SETTINGS.
virtual void OnSetting(SpdySettingsId id, uint32_t value) = 0;
// Called when non-standard frames are received.
diff --git a/chromium/net/spdy/core/mock_spdy_framer_visitor.h b/chromium/net/spdy/core/mock_spdy_framer_visitor.h
index 4efbe538454..7bf02ddd814 100644
--- a/chromium/net/spdy/core/mock_spdy_framer_visitor.h
+++ b/chromium/net/spdy/core/mock_spdy_framer_visitor.h
@@ -40,7 +40,8 @@ class MockSpdyFramerVisitor : public SpdyFramerVisitorInterface {
MOCK_METHOD2(OnRstStream,
void(SpdyStreamId stream_id, SpdyErrorCode error_code));
MOCK_METHOD0(OnSettings, void());
- MOCK_METHOD2(OnSetting, void(SpdyKnownSettingsId id, uint32_t value));
+ MOCK_METHOD2(OnSettingOld, void(SpdyKnownSettingsId id, uint32_t value));
+ MOCK_METHOD2(OnSetting, void(SpdySettingsId id, uint32_t value));
MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack));
MOCK_METHOD0(OnSettingsEnd, void());
MOCK_METHOD2(OnGoAway,
diff --git a/chromium/net/spdy/core/spdy_deframer_visitor.cc b/chromium/net/spdy/core/spdy_deframer_visitor.cc
index 99ee8998662..f92dcedbc0e 100644
--- a/chromium/net/spdy/core/spdy_deframer_visitor.cc
+++ b/chromium/net/spdy/core/spdy_deframer_visitor.cc
@@ -16,6 +16,7 @@
#include "net/spdy/core/spdy_frame_reader.h"
#include "net/spdy/core/spdy_protocol.h"
#include "net/spdy/core/spdy_test_utils.h"
+#include "net/spdy/platform/api/spdy_flags.h"
#include "net/spdy/platform/api/spdy_ptr_util.h"
#include "net/spdy/platform/api/spdy_string_piece.h"
@@ -164,7 +165,8 @@ class SpdyTestDeframerImpl : public SpdyTestDeframer,
SpdyStreamId promised_stream_id,
bool end) override;
void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override;
- void OnSetting(SpdyKnownSettingsId id, uint32_t value) override;
+ void OnSettingOld(SpdyKnownSettingsId id, uint32_t value) override;
+ void OnSetting(SpdySettingsId id, uint32_t value) override;
void OnSettings() override;
void OnSettingsAck() override;
void OnSettingsEnd() override;
@@ -602,10 +604,11 @@ void SpdyTestDeframerImpl::OnRstStream(SpdyStreamId stream_id,
SpdyMakeUnique<SpdyRstStreamIR>(stream_id, error_code));
}
-// Called for an individual setting. There is no negotiation, the sender is
+// Called for an individual setting. There is no negotiation; the sender is
// stating the value that the sender is using.
-void SpdyTestDeframerImpl::OnSetting(SpdyKnownSettingsId id, uint32_t value) {
- DVLOG(1) << "OnSetting id: " << id << std::hex << " value: " << value;
+void SpdyTestDeframerImpl::OnSettingOld(SpdyKnownSettingsId id,
+ uint32_t value) {
+ DVLOG(1) << "OnSettingOld id: " << id << std::hex << " value: " << value;
CHECK_EQ(frame_type_, SETTINGS) << " frame_type_="
<< Http2FrameTypeToString(frame_type_);
CHECK(settings_);
@@ -613,6 +616,20 @@ void SpdyTestDeframerImpl::OnSetting(SpdyKnownSettingsId id, uint32_t value) {
settings_ir_->AddSetting(id, value);
}
+// Called for an individual setting. There is no negotiation; the sender is
+// stating the value that the sender is using.
+void SpdyTestDeframerImpl::OnSetting(SpdySettingsId id, uint32_t value) {
+ DVLOG(1) << "OnSetting id: " << id << std::hex << " value: " << value;
+ CHECK_EQ(frame_type_, SETTINGS)
+ << " frame_type_=" << Http2FrameTypeToString(frame_type_);
+ CHECK(settings_);
+ SpdyKnownSettingsId known_id;
+ if (ParseSettingsId(id, &known_id)) {
+ settings_->push_back(std::make_pair(known_id, value));
+ settings_ir_->AddSetting(known_id, value);
+ }
+}
+
// Called at the start of a SETTINGS frame with setting entries, but not the
// (required) ACK of a SETTINGS frame. There is no stream_id because
// the settings apply to the entire connection, not to an individual stream.
diff --git a/chromium/net/spdy/core/spdy_framer.cc b/chromium/net/spdy/core/spdy_framer.cc
index 1943fb4074e..484ce25bec1 100644
--- a/chromium/net/spdy/core/spdy_framer.cc
+++ b/chromium/net/spdy/core/spdy_framer.cc
@@ -15,7 +15,6 @@
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
-#include "net/quic/platform/api/quic_flags.h"
#include "net/spdy/core/hpack/hpack_constants.h"
#include "net/spdy/core/spdy_bitmasks.h"
#include "net/spdy/core/spdy_bug_tracker.h"
diff --git a/chromium/net/spdy/core/spdy_framer_test.cc b/chromium/net/spdy/core/spdy_framer_test.cc
index 4b7cf59c461..d2336f7b8e2 100644
--- a/chromium/net/spdy/core/spdy_framer_test.cc
+++ b/chromium/net/spdy/core/spdy_framer_test.cc
@@ -15,7 +15,6 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
-#include "net/quic/platform/api/quic_flags.h"
#include "net/spdy/core/array_output_buffer.h"
#include "net/spdy/core/hpack/hpack_constants.h"
#include "net/spdy/core/mock_spdy_framer_visitor.h"
@@ -334,7 +333,12 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
++fin_frame_count_;
}
- void OnSetting(SpdyKnownSettingsId id, uint32_t value) override {
+ void OnSettingOld(SpdyKnownSettingsId id, uint32_t value) override {
+ VLOG(1) << "OnSetting(" << id << ", " << std::hex << value << ")";
+ ++setting_count_;
+ }
+
+ void OnSetting(SpdySettingsId id, uint32_t value) override {
VLOG(1) << "OnSetting(" << id << ", " << std::hex << value << ")";
++setting_count_;
}
@@ -3008,14 +3012,19 @@ TEST_P(SpdyFramerTest, ReadUnknownSettingsId) {
TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
- // In HTTP/2, we ignore unknown settings because of extensions.
- EXPECT_EQ(0, visitor.setting_count_);
+ // In HTTP/2, we ignore unknown settings because of extensions. However, we
+ // pass the SETTINGS to the visitor, which can decide how to handle them.
+ if (GetSpdyRestartFlag(http2_propagate_unknown_settings)) {
+ EXPECT_EQ(1, visitor.setting_count_);
+ } else {
+ EXPECT_EQ(0, visitor.setting_count_);
+ }
EXPECT_EQ(0, visitor.error_count_);
}
-TEST_P(SpdyFramerTest, ReadUnknownSettingsWithExtension) {
+TEST_P(SpdyFramerTest, ReadKnownAndUnknownSettingsWithExtension) {
const unsigned char kH2FrameData[] = {
- 0x00, 0x00, 0x0c, // Length: 12
+ 0x00, 0x00, 0x12, // Length: 18
0x04, // Type: SETTINGS
0x00, // Flags: none
0x00, 0x00, 0x00, 0x00, // Stream: 0
@@ -3023,6 +3032,8 @@ TEST_P(SpdyFramerTest, ReadUnknownSettingsWithExtension) {
0x00, 0x00, 0x00, 0x02, // Value: 2
0x00, 0x5f, // Param: 95
0x00, 0x01, 0x00, 0x02, // Value: 65538
+ 0x00, 0x02, // Param: ENABLE_PUSH
+ 0x00, 0x00, 0x00, 0x01, // Value: 1
};
TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
@@ -3030,13 +3041,26 @@ TEST_P(SpdyFramerTest, ReadUnknownSettingsWithExtension) {
visitor.set_extension_visitor(&extension);
visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData));
- // In HTTP/2, we ignore unknown settings because of extensions.
- EXPECT_EQ(0, visitor.setting_count_);
+ // In HTTP/2, we ignore unknown settings because of extensions. However, we
+ // pass the SETTINGS to the visitor, which can decide how to handle them.
+ if (GetSpdyRestartFlag(http2_propagate_unknown_settings)) {
+ EXPECT_EQ(3, visitor.setting_count_);
+ } else {
+ EXPECT_EQ(1, visitor.setting_count_);
+ }
EXPECT_EQ(0, visitor.error_count_);
- EXPECT_THAT(
- extension.settings_received_,
- testing::ElementsAre(testing::Pair(16, 2), testing::Pair(95, 65538)));
+ if (GetSpdyRestartFlag(http2_propagate_unknown_settings)) {
+ // The extension receives all SETTINGS, including the non-standard SETTINGS.
+ EXPECT_THAT(
+ extension.settings_received_,
+ testing::ElementsAre(testing::Pair(16, 2), testing::Pair(95, 65538),
+ testing::Pair(2, 1)));
+ } else {
+ EXPECT_THAT(
+ extension.settings_received_,
+ testing::ElementsAre(testing::Pair(16, 2), testing::Pair(95, 65538)));
+ }
}
// Tests handling of SETTINGS frame with entries out of order.
@@ -3888,7 +3912,11 @@ TEST_P(SpdyFramerTest, SettingsFrameFlags) {
EXPECT_CALL(visitor, OnError(_));
} else {
EXPECT_CALL(visitor, OnSettings());
- EXPECT_CALL(visitor, OnSetting(SETTINGS_INITIAL_WINDOW_SIZE, 16));
+ if (GetSpdyRestartFlag(http2_propagate_unknown_settings)) {
+ EXPECT_CALL(visitor, OnSetting(SETTINGS_INITIAL_WINDOW_SIZE, 16));
+ } else {
+ EXPECT_CALL(visitor, OnSettingOld(SETTINGS_INITIAL_WINDOW_SIZE, 16));
+ }
EXPECT_CALL(visitor, OnSettingsEnd());
}
diff --git a/chromium/net/spdy/core/spdy_header_block.cc b/chromium/net/spdy/core/spdy_header_block.cc
index fb2c4cb0c9b..a182c9c678a 100644
--- a/chromium/net/spdy/core/spdy_header_block.cc
+++ b/chromium/net/spdy/core/spdy_header_block.cc
@@ -11,10 +11,7 @@
#include "base/logging.h"
#include "base/macros.h"
-#include "base/values.h"
#include "net/base/arena.h"
-#include "net/http/http_log_util.h"
-#include "net/log/net_log_capture_mode.h"
#include "net/spdy/platform/api/spdy_estimate_memory_usage.h"
#include "net/spdy/platform/api/spdy_ptr_util.h"
#include "net/spdy/platform/api/spdy_string_utils.h"
@@ -363,22 +360,6 @@ SpdyHeaderBlock::Storage* SpdyHeaderBlock::GetStorage() {
return storage_.get();
}
-std::unique_ptr<base::Value> SpdyHeaderBlockNetLogCallback(
- const SpdyHeaderBlock* headers,
- NetLogCaptureMode capture_mode) {
- auto dict = std::make_unique<base::DictionaryValue>();
- auto headers_dict = std::make_unique<base::DictionaryValue>();
- for (SpdyHeaderBlock::const_iterator it = headers->begin();
- it != headers->end(); ++it) {
- headers_dict->SetKey(
- it->first.as_string(),
- base::Value(ElideHeaderValueForNetLog(
- capture_mode, it->first.as_string(), it->second.as_string())));
- }
- dict->Set("headers", std::move(headers_dict));
- return std::move(dict);
-}
-
SpdyStringPiece SpdyHeaderBlock::WriteKey(const SpdyStringPiece key) {
key_size_ += key.size();
return GetStorage()->Write(key);
diff --git a/chromium/net/spdy/core/spdy_header_block.h b/chromium/net/spdy/core/spdy_header_block.h
index 248ec73f0be..e5a934fbbce 100644
--- a/chromium/net/spdy/core/spdy_header_block.h
+++ b/chromium/net/spdy/core/spdy_header_block.h
@@ -15,19 +15,12 @@
#include "base/macros.h"
#include "net/base/linked_hash_map.h"
-#include "net/log/net_log.h"
#include "net/spdy/platform/api/spdy_export.h"
#include "net/spdy/platform/api/spdy_string.h"
#include "net/spdy/platform/api/spdy_string_piece.h"
-namespace base {
-class Value;
-}
-
namespace net {
-class NetLogCaptureMode;
-
namespace test {
class SpdyHeaderBlockPeer;
class ValueProxyPeer;
@@ -256,11 +249,6 @@ SPDY_EXPORT_PRIVATE size_t Join(char* dst,
const std::vector<SpdyStringPiece>& fragments,
SpdyStringPiece separator);
-// Converts a SpdyHeaderBlock into NetLog event parameters.
-SPDY_EXPORT_PRIVATE std::unique_ptr<base::Value> SpdyHeaderBlockNetLogCallback(
- const SpdyHeaderBlock* headers,
- NetLogCaptureMode capture_mode);
-
} // namespace net
#endif // NET_SPDY_CORE_SPDY_HEADER_BLOCK_H_
diff --git a/chromium/net/spdy/core/spdy_header_block_test.cc b/chromium/net/spdy/core/spdy_header_block_test.cc
index da0eb7d6d6a..07d05234c3a 100644
--- a/chromium/net/spdy/core/spdy_header_block_test.cc
+++ b/chromium/net/spdy/core/spdy_header_block_test.cc
@@ -8,7 +8,6 @@
#include <utility>
#include "base/values.h"
-#include "net/log/net_log_capture_mode.h"
#include "net/spdy/core/spdy_test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/net/spdy/core/spdy_no_op_visitor.h b/chromium/net/spdy/core/spdy_no_op_visitor.h
index 6dabfcf1ef2..cacd527d172 100644
--- a/chromium/net/spdy/core/spdy_no_op_visitor.h
+++ b/chromium/net/spdy/core/spdy_no_op_visitor.h
@@ -39,7 +39,8 @@ class SpdyNoOpVisitor : public SpdyFramerVisitorInterface,
void OnStreamEnd(SpdyStreamId stream_id) override {}
void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {}
void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override {}
- void OnSetting(SpdyKnownSettingsId id, uint32_t value) override {}
+ void OnSettingOld(SpdyKnownSettingsId id, uint32_t value) override {}
+ void OnSetting(SpdySettingsId id, uint32_t value) override {}
void OnPing(SpdyPingId unique_id, bool is_ack) override {}
void OnSettingsEnd() override {}
void OnSettingsAck() override {}
diff --git a/chromium/net/spdy/core/spdy_protocol.cc b/chromium/net/spdy/core/spdy_protocol.cc
index e67fbd4870c..53d34fe7640 100644
--- a/chromium/net/spdy/core/spdy_protocol.cc
+++ b/chromium/net/spdy/core/spdy_protocol.cc
@@ -7,7 +7,6 @@
#include <ostream>
#include "net/spdy/core/spdy_bug_tracker.h"
-#include "net/spdy/platform/api/spdy_flags.h"
#include "net/spdy/platform/api/spdy_ptr_util.h"
#include "net/spdy/platform/api/spdy_string_utils.h"
@@ -140,26 +139,22 @@ bool ParseSettingsId(SpdySettingsId wire_setting_id,
}
*setting_id = static_cast<SpdyKnownSettingsId>(wire_setting_id);
- if (GetSpdyReloadableFlag(http2_check_settings_id_007)) {
- // This switch ensures that the casted value is valid. The default case is
- // explicitly omitted to have compile-time guarantees that new additions to
- // |SpdyKnownSettingsId| must also be handled here.
- switch (*setting_id) {
- case SETTINGS_HEADER_TABLE_SIZE:
- case SETTINGS_ENABLE_PUSH:
- case SETTINGS_MAX_CONCURRENT_STREAMS:
- case SETTINGS_INITIAL_WINDOW_SIZE:
- case SETTINGS_MAX_FRAME_SIZE:
- case SETTINGS_MAX_HEADER_LIST_SIZE:
- case SETTINGS_ENABLE_CONNECT_PROTOCOL:
- case SETTINGS_EXPERIMENT_SCHEDULER:
- // FALLTHROUGH_INTENDED
- return true;
- }
- return false;
- } else {
- return true;
+ // This switch ensures that the casted value is valid. The default case is
+ // explicitly omitted to have compile-time guarantees that new additions to
+ // |SpdyKnownSettingsId| must also be handled here.
+ switch (*setting_id) {
+ case SETTINGS_HEADER_TABLE_SIZE:
+ case SETTINGS_ENABLE_PUSH:
+ case SETTINGS_MAX_CONCURRENT_STREAMS:
+ case SETTINGS_INITIAL_WINDOW_SIZE:
+ case SETTINGS_MAX_FRAME_SIZE:
+ case SETTINGS_MAX_HEADER_LIST_SIZE:
+ case SETTINGS_ENABLE_CONNECT_PROTOCOL:
+ case SETTINGS_EXPERIMENT_SCHEDULER:
+ // FALLTHROUGH_INTENDED
+ return true;
}
+ return false;
}
SpdyString SettingsIdToString(SpdySettingsId id) {
diff --git a/chromium/net/spdy/core/spdy_protocol.h b/chromium/net/spdy/core/spdy_protocol.h
index 347090b8fb6..7e7d50d2e8d 100644
--- a/chromium/net/spdy/core/spdy_protocol.h
+++ b/chromium/net/spdy/core/spdy_protocol.h
@@ -176,7 +176,7 @@ SPDY_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
SPDY_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
SpdyFrameType frame_type);
-using SettingsMap = std::map<SpdyKnownSettingsId, uint32_t>;
+using SettingsMap = std::map<SpdySettingsId, uint32_t>;
// HTTP/2 error codes, RFC 7540 Section 7.
enum SpdyErrorCode : uint32_t {
@@ -603,9 +603,7 @@ class SPDY_EXPORT_PRIVATE SpdySettingsIR : public SpdyFrameIR {
// Overwrites as appropriate.
const SettingsMap& values() const { return values_; }
- void AddSetting(SpdyKnownSettingsId id, int32_t value) {
- values_[id] = value;
- }
+ void AddSetting(SpdySettingsId id, int32_t value) { values_[id] = value; }
bool is_ack() const { return is_ack_; }
void set_is_ack(bool is_ack) { is_ack_ = is_ack; }
diff --git a/chromium/net/spdy/core/spdy_protocol_test.cc b/chromium/net/spdy/core/spdy_protocol_test.cc
index af4b1b9c5ee..47c2a57bb79 100644
--- a/chromium/net/spdy/core/spdy_protocol_test.cc
+++ b/chromium/net/spdy/core/spdy_protocol_test.cc
@@ -10,7 +10,6 @@
#include "net/spdy/core/spdy_bitmasks.h"
#include "net/spdy/core/spdy_test_utils.h"
-#include "net/spdy/platform/api/spdy_flags.h"
#include "net/test/gtest_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -119,12 +118,7 @@ TEST(SpdyProtocolTest, ParseSettingsId) {
EXPECT_EQ(SETTINGS_MAX_FRAME_SIZE, setting_id);
EXPECT_TRUE(ParseSettingsId(6, &setting_id));
EXPECT_EQ(SETTINGS_MAX_HEADER_LIST_SIZE, setting_id);
- if (GetSpdyReloadableFlag(http2_check_settings_id_007)) {
- EXPECT_FALSE(ParseSettingsId(7, &setting_id));
- } else {
- EXPECT_TRUE(ParseSettingsId(7, &setting_id));
- EXPECT_EQ(0x07, setting_id);
- }
+ EXPECT_FALSE(ParseSettingsId(7, &setting_id));
EXPECT_TRUE(ParseSettingsId(8, &setting_id));
EXPECT_EQ(SETTINGS_ENABLE_CONNECT_PROTOCOL, setting_id);
EXPECT_FALSE(ParseSettingsId(9, &setting_id));
diff --git a/chromium/net/spdy/core/spdy_test_utils.cc b/chromium/net/spdy/core/spdy_test_utils.cc
index e8e29f7b7b8..050eaf2cbf6 100644
--- a/chromium/net/spdy/core/spdy_test_utils.cc
+++ b/chromium/net/spdy/core/spdy_test_utils.cc
@@ -11,11 +11,8 @@
#include <utility>
#include <vector>
-#include "base/base64.h"
#include "base/logging.h"
#include "base/sys_byteorder.h"
-#include "net/http/transport_security_state.h"
-#include "net/ssl/ssl_info.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -103,37 +100,6 @@ void SetFrameLength(SpdySerializedFrame* frame, size_t length) {
}
}
-HashValue GetTestHashValue(uint8_t label) {
- HashValue hash_value(HASH_VALUE_SHA256);
- memset(hash_value.data(), label, hash_value.size());
- return hash_value;
-}
-
-SpdyString GetTestPin(uint8_t label) {
- HashValue hash_value = GetTestHashValue(label);
- SpdyString base64;
- base::Base64Encode(SpdyStringPiece(reinterpret_cast<char*>(hash_value.data()),
- hash_value.size()),
- &base64);
-
- return SpdyString("pin-sha256=\"") + base64 + "\"";
-}
-
-void AddPin(TransportSecurityState* state,
- const SpdyString& host,
- uint8_t primary_label,
- uint8_t backup_label) {
- SpdyString primary_pin = GetTestPin(primary_label);
- SpdyString backup_pin = GetTestPin(backup_label);
- SpdyString header = "max-age = 10000; " + primary_pin + "; " + backup_pin;
-
- // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
- SSLInfo ssl_info;
- ssl_info.is_issued_by_known_root = true;
- ssl_info.public_key_hashes.push_back(GetTestHashValue(primary_label));
- EXPECT_TRUE(state->AddHPKPHeader(host, header, ssl_info));
-}
-
void TestHeadersHandler::OnHeaderBlockStart() {
block_.clear();
}
@@ -149,23 +115,5 @@ void TestHeadersHandler::OnHeaderBlockEnd(
compressed_header_bytes_parsed_ = compressed_header_bytes_parsed;
}
-TestServerPushDelegate::TestServerPushDelegate() = default;
-
-TestServerPushDelegate::~TestServerPushDelegate() = default;
-
-void TestServerPushDelegate::OnPush(
- std::unique_ptr<ServerPushHelper> push_helper,
- const NetLogWithSource& session_net_log) {
- push_helpers[push_helper->GetURL()] = std::move(push_helper);
-}
-
-bool TestServerPushDelegate::CancelPush(GURL url) {
- auto itr = push_helpers.find(url);
- DCHECK(itr != push_helpers.end());
- itr->second->Cancel();
- push_helpers.erase(itr);
- return true;
-}
-
} // namespace test
} // namespace net
diff --git a/chromium/net/spdy/core/spdy_test_utils.h b/chromium/net/spdy/core/spdy_test_utils.h
index 6e6c2e037f1..7afd261e524 100644
--- a/chromium/net/spdy/core/spdy_test_utils.h
+++ b/chromium/net/spdy/core/spdy_test_utils.h
@@ -24,9 +24,6 @@
namespace net {
-class HashValue;
-class TransportSecurityState;
-
inline bool operator==(SpdyStringPiece x,
const SpdyHeaderBlock::ValueProxy& y) {
return x == y.as_string();
@@ -49,19 +46,6 @@ void SetFrameFlags(SpdySerializedFrame* frame, uint8_t flags);
void SetFrameLength(SpdySerializedFrame* frame, size_t length);
-// Returns a SHA1 HashValue in which each byte has the value |label|.
-HashValue GetTestHashValue(uint8_t label);
-
-// Returns SHA1 pinning header for the of the base64 encoding of
-// GetTestHashValue(|label|).
-SpdyString GetTestPin(uint8_t label);
-
-// Adds a pin for |host| to |state|.
-void AddPin(TransportSecurityState* state,
- const SpdyString& host,
- uint8_t primary_label,
- uint8_t backup_label);
-
// A test implementation of SpdyHeadersHandlerInterface that correctly
// reconstructs multiple header values for the same name.
class TestHeadersHandler : public SpdyHeadersHandlerInterface {
@@ -89,22 +73,6 @@ class TestHeadersHandler : public SpdyHeadersHandlerInterface {
DISALLOW_COPY_AND_ASSIGN(TestHeadersHandler);
};
-// A test implementation of ServerPushDelegate that caches all the pushed
-// request and provides a interface to cancel the push given url.
-class TestServerPushDelegate : public ServerPushDelegate {
- public:
- TestServerPushDelegate();
- ~TestServerPushDelegate() override;
-
- void OnPush(std::unique_ptr<ServerPushHelper> push_helper,
- const NetLogWithSource& session_net_log) override;
-
- bool CancelPush(GURL url);
-
- private:
- std::map<GURL, std::unique_ptr<ServerPushHelper>> push_helpers;
-};
-
} // namespace test
} // namespace net
diff --git a/chromium/net/spdy/platform/api/spdy_flags.h b/chromium/net/spdy/platform/api/spdy_flags.h
index 2a81172d479..0f4f34042b6 100644
--- a/chromium/net/spdy/platform/api/spdy_flags.h
+++ b/chromium/net/spdy/platform/api/spdy_flags.h
@@ -8,5 +8,6 @@
#include "net/spdy/platform/impl/spdy_flags_impl.h"
#define GetSpdyReloadableFlag(flag) GetSpdyReloadableFlagImpl(flag)
+#define GetSpdyRestartFlag(flag) GetSpdyRestartFlagImpl(flag)
#endif // NET_SPDY_PLATFORM_API_SPDY_FLAGS_H_
diff --git a/chromium/net/spdy/platform/impl/spdy_flags_impl.cc b/chromium/net/spdy/platform/impl/spdy_flags_impl.cc
index bcec96c5d25..61153077e60 100644
--- a/chromium/net/spdy/platform/impl/spdy_flags_impl.cc
+++ b/chromium/net/spdy/platform/impl/spdy_flags_impl.cc
@@ -6,7 +6,9 @@
namespace net {
-// Consider SETTINGS identifier 0x07 as invalid.
-bool http2_check_settings_id_007 = true;
+// If true, Http2FrameDecoderAdapter will pass decoded HTTP/2 SETTINGS through
+// the SpdyFramerVisitorInterface callback OnSetting(), which will also accept
+// unknown SETTINGS IDs.
+bool http2_propagate_unknown_settings = true;
} // namespace net
diff --git a/chromium/net/spdy/platform/impl/spdy_flags_impl.h b/chromium/net/spdy/platform/impl/spdy_flags_impl.h
index 95e26b72da0..434e59d382a 100644
--- a/chromium/net/spdy/platform/impl/spdy_flags_impl.h
+++ b/chromium/net/spdy/platform/impl/spdy_flags_impl.h
@@ -9,12 +9,16 @@
namespace net {
-NET_EXPORT_PRIVATE extern bool http2_check_settings_id_007;
+NET_EXPORT_PRIVATE extern bool http2_propagate_unknown_settings;
inline bool GetSpdyReloadableFlagImpl(bool flag) {
return flag;
}
+inline bool GetSpdyRestartFlagImpl(bool flag) {
+ return flag;
+}
+
} // namespace net
#endif // NET_SPDY_PLATFORM_IMPL_SPDY_FLAGS_IMPL_H_
diff --git a/chromium/net/ssl/client_cert_identity_unittest.cc b/chromium/net/ssl/client_cert_identity_unittest.cc
index fbd60d6b0f2..36a55836949 100644
--- a/chromium/net/ssl/client_cert_identity_unittest.cc
+++ b/chromium/net/ssl/client_cert_identity_unittest.cc
@@ -25,7 +25,7 @@ TEST(ClientCertIdentitySorter, SortClientCertificates) {
std::string der_cert;
ASSERT_TRUE(x509_util::CreateSelfSignedCert(
- key.get(), x509_util::DIGEST_SHA256, "CN=expired", 1,
+ key->key(), x509_util::DIGEST_SHA256, "CN=expired", 1,
base::Time::UnixEpoch(), base::Time::UnixEpoch(), &der_cert));
cert = X509Certificate::CreateFromBytes(der_cert.data(), der_cert.size());
ASSERT_TRUE(cert);
@@ -34,7 +34,7 @@ TEST(ClientCertIdentitySorter, SortClientCertificates) {
const base::Time now = base::Time::Now();
ASSERT_TRUE(x509_util::CreateSelfSignedCert(
- key.get(), x509_util::DIGEST_SHA256, "CN=not yet valid", 2,
+ key->key(), x509_util::DIGEST_SHA256, "CN=not yet valid", 2,
now + base::TimeDelta::FromDays(10), now + base::TimeDelta::FromDays(15),
&der_cert));
cert = X509Certificate::CreateFromBytes(der_cert.data(), der_cert.size());
@@ -42,7 +42,7 @@ TEST(ClientCertIdentitySorter, SortClientCertificates) {
certs.push_back(std::make_unique<FakeClientCertIdentity>(cert, nullptr));
ASSERT_TRUE(x509_util::CreateSelfSignedCert(
- key.get(), x509_util::DIGEST_SHA256, "CN=older cert", 3,
+ key->key(), x509_util::DIGEST_SHA256, "CN=older cert", 3,
now - base::TimeDelta::FromDays(5), now + base::TimeDelta::FromDays(5),
&der_cert));
cert = X509Certificate::CreateFromBytes(der_cert.data(), der_cert.size());
@@ -50,7 +50,7 @@ TEST(ClientCertIdentitySorter, SortClientCertificates) {
certs.push_back(std::make_unique<FakeClientCertIdentity>(cert, nullptr));
ASSERT_TRUE(x509_util::CreateSelfSignedCert(
- key.get(), x509_util::DIGEST_SHA256, "CN=newer cert", 2,
+ key->key(), x509_util::DIGEST_SHA256, "CN=newer cert", 2,
now - base::TimeDelta::FromDays(3), now + base::TimeDelta::FromDays(5),
&der_cert));
cert = X509Certificate::CreateFromBytes(der_cert.data(), der_cert.size());
diff --git a/chromium/net/ssl/client_cert_store_nss.cc b/chromium/net/ssl/client_cert_store_nss.cc
index 7c773ee51d1..3a248f3ba23 100644
--- a/chromium/net/ssl/client_cert_store_nss.cc
+++ b/chromium/net/ssl/client_cert_store_nss.cc
@@ -20,6 +20,7 @@
#include "base/task_scheduler/post_task.h"
#include "base/threading/scoped_blocking_call.h"
#include "crypto/nss_crypto_module_delegate.h"
+#include "crypto/nss_util.h"
#include "net/cert/scoped_nss_types.h"
#include "net/cert/x509_util_nss.h"
#include "net/ssl/ssl_cert_request_info.h"
@@ -166,6 +167,8 @@ void ClientCertStoreNSS::GetPlatformCertsOnWorkerThread(
password_delegate,
const CertFilter& cert_filter,
ClientCertIdentityList* identities) {
+ crypto::EnsureNSSInit();
+
CERTCertList* found_certs =
CERT_FindUserCertsByUsage(CERT_GetDefaultCertDB(), certUsageSSLClient,
PR_FALSE, PR_FALSE, password_delegate.get());
diff --git a/chromium/net/ssl/ssl_client_session_cache_unittest.cc b/chromium/net/ssl/ssl_client_session_cache_unittest.cc
index 461fb189561..174c5744caf 100644
--- a/chromium/net/ssl/ssl_client_session_cache_unittest.cc
+++ b/chromium/net/ssl/ssl_client_session_cache_unittest.cc
@@ -4,7 +4,6 @@
#include "net/ssl/ssl_client_session_cache.h"
-#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/simple_test_clock.h"
diff --git a/chromium/net/ssl/ssl_config.cc b/chromium/net/ssl/ssl_config.cc
index 883c7f8d32a..d74880518d8 100644
--- a/chromium/net/ssl/ssl_config.cc
+++ b/chromium/net/ssl/ssl_config.cc
@@ -24,7 +24,7 @@ SSLConfig::CertAndStatus::~CertAndStatus() = default;
SSLConfig::SSLConfig()
: rev_checking_enabled(false),
rev_checking_required_local_anchors(false),
- sha1_local_anchors_enabled(true),
+ sha1_local_anchors_enabled(false),
symantec_enforcement_disabled(false),
version_min(kDefaultSSLVersionMin),
version_max(kDefaultSSLVersionMax),
@@ -32,11 +32,8 @@ SSLConfig::SSLConfig()
version_interference_probe(false),
channel_id_enabled(true),
false_start_enabled(true),
- signed_cert_timestamps_enabled(true),
require_ecdhe(false),
send_client_cert(false),
- verify_ev_cert(false),
- cert_io_enabled(true),
renego_allowed_default(false) {}
SSLConfig::SSLConfig(const SSLConfig& other) = default;
@@ -59,10 +56,6 @@ int SSLConfig::GetCertVerifyFlags() const {
int flags = 0;
if (rev_checking_enabled)
flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED;
- if (verify_ev_cert)
- flags |= CertVerifier::VERIFY_EV_CERT;
- if (cert_io_enabled)
- flags |= CertVerifier::VERIFY_CERT_IO_ENABLED;
if (rev_checking_required_local_anchors)
flags |= CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS;
if (sha1_local_anchors_enabled)
diff --git a/chromium/net/ssl/ssl_config.h b/chromium/net/ssl/ssl_config.h
index da55dade74d..122e2105391 100644
--- a/chromium/net/ssl/ssl_config.h
+++ b/chromium/net/ssl/ssl_config.h
@@ -124,9 +124,6 @@ struct NET_EXPORT SSLConfig {
std::vector<TokenBindingParam> token_binding_params;
bool false_start_enabled; // True if we'll use TLS False Start.
- // True if the Certificate Transparency signed_certificate_timestamp
- // TLS extension is enabled.
- bool signed_cert_timestamps_enabled;
// If true, causes only ECDHE cipher suites to be enabled.
bool require_ecdhe;
@@ -153,15 +150,6 @@ struct NET_EXPORT SSLConfig {
// True if we should send client_cert to the server.
bool send_client_cert;
- bool verify_ev_cert; // True if we should verify the certificate for EV.
-
- // If cert_io_enabled is false, then certificate verification will not
- // result in additional HTTP requests. (For example: to fetch missing
- // intermediates or to perform OCSP/CRL fetches.) It also implies that online
- // revocation checking is disabled.
- // NOTE: Only used by NSS.
- bool cert_io_enabled;
-
// The list of application level protocols supported with ALPN (Application
// Layer Protocol Negotation), in decreasing order of preference. Protocols
// will be advertised in this order during TLS handshake.
diff --git a/chromium/net/ssl/ssl_config_unittest.cc b/chromium/net/ssl/ssl_config_unittest.cc
index e3fca97dec2..11001b49439 100644
--- a/chromium/net/ssl/ssl_config_unittest.cc
+++ b/chromium/net/ssl/ssl_config_unittest.cc
@@ -13,13 +13,9 @@ namespace {
void CheckCertVerifyFlags(SSLConfig* ssl_config,
bool rev_checking_enabled,
- bool verify_ev_cert,
- bool cert_io_enabled,
bool rev_checking_required_local_anchors,
bool symantec_enforcement_disabled) {
ssl_config->rev_checking_enabled = rev_checking_enabled;
- ssl_config->verify_ev_cert = verify_ev_cert;
- ssl_config->cert_io_enabled = cert_io_enabled;
ssl_config->rev_checking_required_local_anchors =
rev_checking_required_local_anchors;
ssl_config->symantec_enforcement_disabled = symantec_enforcement_disabled;
@@ -27,8 +23,6 @@ void CheckCertVerifyFlags(SSLConfig* ssl_config,
int flags = ssl_config->GetCertVerifyFlags();
EXPECT_EQ(rev_checking_enabled,
!!(flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED));
- EXPECT_EQ(verify_ev_cert, !!(flags & CertVerifier::VERIFY_EV_CERT));
- EXPECT_EQ(cert_io_enabled, !!(flags & CertVerifier::VERIFY_CERT_IO_ENABLED));
EXPECT_EQ(
rev_checking_required_local_anchors,
!!(flags & CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS));
@@ -42,52 +36,28 @@ TEST(SSLConfigTest, GetCertVerifyFlags) {
SSLConfig ssl_config;
CheckCertVerifyFlags(&ssl_config,
/*rev_checking_enabled=*/true,
- /*verify_ev_cert=*/true,
- /*cert_io_enabled=*/true,
/*rev_checking_required_local_anchors=*/true,
/*symantec_enforcement_disabled=*/true);
CheckCertVerifyFlags(&ssl_config,
- /*rev_checking_enabled=*/false,
- /*verify_ev_cert=*/false,
- /*cert_io_enabled=*/false,
- /*rev_checking_required_local_anchors=*/false,
- /*symantec_enforcement_disabled=*/false);
-
- CheckCertVerifyFlags(&ssl_config,
/*rev_checking_enabled=*/true,
- /*verify_ev_cert=*/false,
- /*cert_io_enabled=*/false,
/*rev_checking_required_local_anchors=*/false,
/*symantec_enforcement_disabled=*/false);
CheckCertVerifyFlags(&ssl_config,
/*rev_checking_enabled=*/false,
- /*verify_ev_cert=*/true,
- /*cert_io_enabled=*/false,
- /*rev_checking_required_local_anchors=*/false,
+ /*rev_checking_required_local_anchors=*/true,
/*symantec_enforcement_disabled=*/false);
CheckCertVerifyFlags(&ssl_config,
/*rev_checking_enabled=*/false,
- /*verify_ev_cert=*/false,
- /*cert_io_enabled=*/true,
/*rev_checking_required_local_anchors=*/false,
- /*symantec_enforcement_disabled=*/false);
-
- CheckCertVerifyFlags(&ssl_config,
- /*rev_checking_enabled=*/false,
- /*verify_ev_cert=*/false,
- /*cert_io_enabled=*/false,
- /*rev_checking_required_local_anchors=*/true,
- /*symantec_enforcement_disabled=*/false);
+ /*symantec_enforcement_disabled=*/true);
CheckCertVerifyFlags(&ssl_config,
/*rev_checking_enabled=*/false,
- /*verify_ev_cert=*/false,
- /*cert_io_enabled=*/true,
/*rev_checking_required_local_anchors=*/false,
- /*symantec_enforcement_disabled=*/true);
+ /*symantec_enforcement_disabled=*/false);
}
} // namespace net
diff --git a/chromium/net/ssl/ssl_info.cc b/chromium/net/ssl/ssl_info.cc
index f80610f22ee..4c074fb4b13 100644
--- a/chromium/net/ssl/ssl_info.cc
+++ b/chromium/net/ssl/ssl_info.cc
@@ -4,51 +4,20 @@
#include "net/ssl/ssl_info.h"
-#include "base/pickle.h"
-#include "base/stl_util.h"
-#include "net/cert/cert_status_flags.h"
-#include "net/cert/ct_policy_status.h"
-#include "net/cert/signed_certificate_timestamp.h"
#include "net/cert/x509_certificate.h"
-#include "net/ssl/ssl_connection_status_flags.h"
-#include "third_party/boringssl/src/include/openssl/ssl.h"
namespace net {
-SSLInfo::SSLInfo() {
- Reset();
-}
+SSLInfo::SSLInfo() = default;
-SSLInfo::SSLInfo(const SSLInfo& info) {
- *this = info;
-}
+SSLInfo::SSLInfo(const SSLInfo& info) = default;
SSLInfo::~SSLInfo() = default;
SSLInfo& SSLInfo::operator=(const SSLInfo& info) = default;
void SSLInfo::Reset() {
- cert = NULL;
- unverified_cert = NULL;
- cert_status = 0;
- security_bits = -1;
- key_exchange_group = 0;
- connection_status = 0;
- is_issued_by_known_root = false;
- pkp_bypassed = false;
- client_cert_sent = false;
- channel_id_sent = false;
- token_binding_negotiated = false;
- token_binding_key_param = TB_PARAM_ECDSAP256;
- handshake_type = HANDSHAKE_UNKNOWN;
- base::STLClearObject(&public_key_hashes);
- base::STLClearObject(&pinning_failure_log);
- base::STLClearObject(&signed_certificate_timestamps);
- ct_policy_compliance =
- ct::CTPolicyCompliance::CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE;
- ct_policy_compliance_required = false;
- ocsp_result = OCSPVerifyResult();
- is_fatal_cert_error = false;
+ *this = SSLInfo();
}
void SSLInfo::SetCertError(int error) {
diff --git a/chromium/net/ssl/ssl_info.h b/chromium/net/ssl/ssl_info.h
index 2d903cf26df..89cf83f7760 100644
--- a/chromium/net/ssl/ssl_info.h
+++ b/chromium/net/ssl/ssl_info.h
@@ -12,6 +12,7 @@
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
#include "net/cert/cert_status_flags.h"
+#include "net/cert/ct_policy_status.h"
#include "net/cert/ct_verify_result.h"
#include "net/cert/ocsp_verify_result.h"
#include "net/cert/sct_status_flags.h"
@@ -21,12 +22,6 @@
namespace net {
-namespace ct {
-
-enum class CTPolicyCompliance;
-
-} // namespace ct
-
class X509Certificate;
// SSL connection info.
@@ -74,46 +69,51 @@ class NET_EXPORT SSLInfo {
// Bitmask of status info of |cert|, representing, for example, known errors
// and extended validation (EV) status.
// See cert_status_flags.h for values.
- CertStatus cert_status;
+ CertStatus cert_status = 0;
// The security strength, in bits, of the SSL cipher suite.
// 0 means the connection is not encrypted.
// -1 means the security strength is unknown.
- int security_bits;
+ int security_bits = -1;
// The ID of the (EC)DH group used by the key exchange or zero if unknown
// (older cache entries may not store the value) or not applicable.
- uint16_t key_exchange_group;
+ uint16_t key_exchange_group = 0;
// Information about the SSL connection itself. See
// ssl_connection_status_flags.h for values. The protocol version,
// ciphersuite, and compression in use are encoded within.
- int connection_status;
+ int connection_status = 0;
// If the certificate is valid, then this is true iff it was rooted at a
// standard CA root. (As opposed to a user-installed root.)
- bool is_issued_by_known_root;
+ bool is_issued_by_known_root = false;
// True if pinning was bypassed on this connection.
- bool pkp_bypassed;
+ bool pkp_bypassed = false;
// True if a client certificate was sent to the server. Note that sending
// a Certificate message with no client certificate in it does not count.
- bool client_cert_sent;
+ bool client_cert_sent = false;
// True if a channel ID was sent to the server.
- bool channel_id_sent;
+ bool channel_id_sent = false;
// True if Token Binding was negotiated with the server and we agreed on a
// version and key params.
- bool token_binding_negotiated;
+ bool token_binding_negotiated = false;
// Only valid if |token_binding_negotiated| is true. Contains the key param
// negotiated by the client and server in the Token Binding Negotiation TLS
// extension.
- TokenBindingParam token_binding_key_param;
+ TokenBindingParam token_binding_key_param = TB_PARAM_ECDSAP256;
+
+ // True if the server echoed a dummy post-quantum padding extension. See
+ // https://crbug.com/801302.
+ // TODO(agl): remove by 2018-05-31.
+ bool dummy_pq_padding_received = false;
- HandshakeType handshake_type;
+ HandshakeType handshake_type = HANDSHAKE_UNKNOWN;
// The hashes, in several algorithms, of the SubjectPublicKeyInfos from
// each certificate in the chain.
@@ -130,19 +130,20 @@ class NET_EXPORT SSLInfo {
// Whether the connection complied with the CT cert policy, and if
// not, why not.
- ct::CTPolicyCompliance ct_policy_compliance;
+ ct::CTPolicyCompliance ct_policy_compliance =
+ ct::CTPolicyCompliance::CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE;
// True if the connection was required to comply with the CT cert policy. Only
// meaningful if |ct_policy_compliance| is not
// COMPLIANCE_DETAILS_NOT_AVAILABLE.
- bool ct_policy_compliance_required;
+ bool ct_policy_compliance_required = false;
// OCSP stapling details.
OCSPVerifyResult ocsp_result;
// True if there was a certificate error which should be treated as fatal,
// and false otherwise.
- bool is_fatal_cert_error;
+ bool is_fatal_cert_error = false;
};
} // namespace net
diff --git a/chromium/net/ssl/ssl_platform_key_android.cc b/chromium/net/ssl/ssl_platform_key_android.cc
index 4cd9cc03fc6..650b34878dd 100644
--- a/chromium/net/ssl/ssl_platform_key_android.cc
+++ b/chromium/net/ssl/ssl_platform_key_android.cc
@@ -194,12 +194,12 @@ scoped_refptr<SSLPrivateKey> WrapJavaPrivateKey(
android::AndroidRSA* sys_rsa = nullptr;
if (type == EVP_PKEY_RSA) {
- const int kAndroid42ApiLevel = 17;
if (base::android::BuildInfo::GetInstance()->sdk_int() <
- kAndroid42ApiLevel) {
- // Route around platform limitations: if Android < 4.2, then
- // base::android::RawSignDigestWithPrivateKey() cannot work, so try to get
- // the system OpenSSL's EVP_PKEY backing this PrivateKey object.
+ base::android::SDK_VERSION_JELLY_BEAN_MR1) {
+ // Route around platform limitations: if Android < 4.2 (Jelly
+ // Bean MR1), then base::android::RawSignDigestWithPrivateKey()
+ // cannot work, so try to get the system OpenSSL's EVP_PKEY
+ // backing this PrivateKey object.
android::AndroidEVP_PKEY* sys_pkey =
android::GetOpenSSLSystemHandleForPrivateKey(key);
if (!sys_pkey)
diff --git a/chromium/net/test/embedded_test_server/controllable_http_response.cc b/chromium/net/test/embedded_test_server/controllable_http_response.cc
index 2d13d54527f..226b126d6f5 100644
--- a/chromium/net/test/embedded_test_server/controllable_http_response.cc
+++ b/chromium/net/test/embedded_test_server/controllable_http_response.cc
@@ -15,9 +15,11 @@ class ControllableHttpResponse::Interceptor : public HttpResponse {
public:
explicit Interceptor(
base::WeakPtr<ControllableHttpResponse> controller,
- scoped_refptr<base::SingleThreadTaskRunner> controller_task_runner)
+ scoped_refptr<base::SingleThreadTaskRunner> controller_task_runner,
+ const HttpRequest& http_request)
: controller_(controller),
- controller_task_runner_(controller_task_runner) {}
+ controller_task_runner_(controller_task_runner),
+ http_request_(std::make_unique<HttpRequest>(http_request)) {}
~Interceptor() override {}
private:
@@ -26,24 +28,28 @@ class ControllableHttpResponse::Interceptor : public HttpResponse {
controller_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&ControllableHttpResponse::OnRequest, controller_,
- base::ThreadTaskRunnerHandle::Get(), send, done));
+ base::ThreadTaskRunnerHandle::Get(), send, done,
+ std::move(http_request_)));
}
base::WeakPtr<ControllableHttpResponse> controller_;
scoped_refptr<base::SingleThreadTaskRunner> controller_task_runner_;
+ std::unique_ptr<HttpRequest> http_request_;
+
DISALLOW_COPY_AND_ASSIGN(Interceptor);
};
ControllableHttpResponse::ControllableHttpResponse(
EmbeddedTestServer* embedded_test_server,
- const std::string& relative_url)
+ const std::string& relative_url,
+ bool relative_url_is_prefix)
: weak_ptr_factory_(this) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- embedded_test_server->RegisterRequestHandler(
- base::BindRepeating(RequestHandler, weak_ptr_factory_.GetWeakPtr(),
- base::ThreadTaskRunnerHandle::Get(),
- base::Owned(new bool(true)), relative_url));
+ embedded_test_server->RegisterRequestHandler(base::BindRepeating(
+ RequestHandler, weak_ptr_factory_.GetWeakPtr(),
+ base::ThreadTaskRunnerHandle::Get(), base::Owned(new bool(true)),
+ relative_url, relative_url_is_prefix));
}
ControllableHttpResponse::~ControllableHttpResponse() {}
@@ -83,13 +89,15 @@ void ControllableHttpResponse::OnRequest(
scoped_refptr<base::SingleThreadTaskRunner>
embedded_test_server_task_runner,
const SendBytesCallback& send,
- const SendCompleteCallback& done) {
+ const SendCompleteCallback& done,
+ std::unique_ptr<HttpRequest> http_request) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!embedded_test_server_task_runner_)
<< "A ControllableHttpResponse can only handle one request at a time";
embedded_test_server_task_runner_ = embedded_test_server_task_runner;
send_ = send;
done_ = done;
+ http_request_ = std::move(http_request);
loop_.Quit();
}
@@ -100,12 +108,20 @@ std::unique_ptr<HttpResponse> ControllableHttpResponse::RequestHandler(
scoped_refptr<base::SingleThreadTaskRunner> controller_task_runner,
bool* available,
const std::string& relative_url,
+ bool relative_url_is_prefix,
const HttpRequest& request) {
- if (*available && request.relative_url == relative_url) {
+ if (!*available)
+ return nullptr;
+
+ if (request.relative_url == relative_url ||
+ (relative_url_is_prefix &&
+ base::StartsWith(request.relative_url, relative_url,
+ base::CompareCase::SENSITIVE))) {
*available = false;
return std::make_unique<ControllableHttpResponse::Interceptor>(
- controller, controller_task_runner);
+ controller, controller_task_runner, request);
}
+
return nullptr;
}
diff --git a/chromium/net/test/embedded_test_server/controllable_http_response.h b/chromium/net/test/embedded_test_server/controllable_http_response.h
index 74f7965926a..ffc72717e3f 100644
--- a/chromium/net/test/embedded_test_server/controllable_http_response.h
+++ b/chromium/net/test/embedded_test_server/controllable_http_response.h
@@ -27,10 +27,15 @@ namespace test_server {
// handle only **one** request with the matching |relative_url|. In the case of
// multiple ControllableHttpResponses for the same path, they're used in the
// order they were created.
+//
+// If |relative_url_is_prefix| is true, |relative_url| is only compared agaisnt
+// the start of the URL being requested, which allows matching against (possibly
+// variable) query strings, for instance.
class ControllableHttpResponse {
public:
ControllableHttpResponse(EmbeddedTestServer* embedded_test_server,
- const std::string& relative_path);
+ const std::string& relative_url,
+ bool relative_url_is_prefix = false);
~ControllableHttpResponse();
// These method are intented to be used in order.
@@ -44,6 +49,9 @@ class ControllableHttpResponse {
// 3) Notify there are no more data to be sent and close the socket.
void Done();
+ // Returns the HttpRequest after a call to WaitForRequest.
+ const HttpRequest* http_request() const { return http_request_.get(); }
+
private:
class Interceptor;
@@ -52,13 +60,15 @@ class ControllableHttpResponse {
void OnRequest(scoped_refptr<base::SingleThreadTaskRunner>
embedded_test_server_task_runner,
const SendBytesCallback& send,
- const SendCompleteCallback& done);
+ const SendCompleteCallback& done,
+ std::unique_ptr<HttpRequest> http_request);
static std::unique_ptr<HttpResponse> RequestHandler(
base::WeakPtr<ControllableHttpResponse> controller,
scoped_refptr<base::SingleThreadTaskRunner> controller_task_runner,
bool* available,
const std::string& relative_url,
+ bool relative_url_is_prefix,
const HttpRequest& request);
State state_ = State::WAITING_FOR_REQUEST;
@@ -66,6 +76,8 @@ class ControllableHttpResponse {
scoped_refptr<base::SingleThreadTaskRunner> embedded_test_server_task_runner_;
SendBytesCallback send_;
SendCompleteCallback done_;
+ std::unique_ptr<HttpRequest> http_request_;
+
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<ControllableHttpResponse> weak_ptr_factory_;
diff --git a/chromium/net/test/embedded_test_server/default_handlers.cc b/chromium/net/test/embedded_test_server/default_handlers.cc
index bc89ab822e2..6d7375dede2 100644
--- a/chromium/net/test/embedded_test_server/default_handlers.cc
+++ b/chromium/net/test/embedded_test_server/default_handlers.cc
@@ -232,7 +232,7 @@ std::unique_ptr<HttpResponse> HandleExpectAndSetCookie(
if (request.headers.find("Cookie") != request.headers.end()) {
received_cookies =
base::SplitString(request.headers.at("Cookie"), ";",
- base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
+ base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
}
bool got_all_expected = true;
diff --git a/chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc b/chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc
index 21c37e2205b..d6f74a11c10 100644
--- a/chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc
+++ b/chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc
@@ -4,6 +4,7 @@
#include "net/test/embedded_test_server/embedded_test_server.h"
+#include <tuple>
#include <utility>
#include "base/macros.h"
@@ -16,7 +17,6 @@
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "crypto/nss_util.h"
#include "net/base/test_completion_callback.h"
#include "net/http/http_response_headers.h"
#include "net/log/net_log_source.h"
@@ -36,10 +36,6 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#if defined(USE_NSS_CERTS)
-#include "net/cert_net/nss_ocsp.h"
-#endif
-
using net::test::IsOk;
namespace net {
@@ -130,15 +126,6 @@ class EmbeddedTestServerTest
}
void SetUp() override {
-#if defined(USE_NSS_CERTS)
- // This is needed so NSS's HTTP client functions are initialized on the
- // right thread. These tests create SSLClientSockets on a different thread.
- // TODO(davidben): Initialization can't be deferred to SSLClientSocket. See
- // https://crbug.com/539520.
- crypto::EnsureNSSInit();
- EnsureNSSHttpIOInit();
-#endif
-
base::Thread::Options thread_options;
thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
ASSERT_TRUE(io_thread_.StartWithOptions(thread_options));
@@ -153,9 +140,6 @@ class EmbeddedTestServerTest
void TearDown() override {
if (server_->Started())
ASSERT_TRUE(server_->ShutdownAndWaitUntilComplete());
-#if defined(USE_NSS_CERTS)
- ShutdownNSSHttpIO();
-#endif
}
// URLFetcherDelegate override.
@@ -512,28 +496,10 @@ INSTANTIATE_TEST_CASE_P(EmbeddedTestServerTestInstantiation,
// where there is no MessageLoop available on the thread at EmbeddedTestServer
// initialization and/or destruction.
-typedef std::tr1::tuple<bool, bool, EmbeddedTestServer::Type>
- ThreadingTestParams;
+typedef std::tuple<bool, bool, EmbeddedTestServer::Type> ThreadingTestParams;
class EmbeddedTestServerThreadingTest
- : public testing::TestWithParam<ThreadingTestParams> {
- void SetUp() override {
-#if defined(USE_NSS_CERTS)
- // This is needed so NSS's HTTP client functions are initialized on the
- // right thread. These tests create SSLClientSockets on a different thread.
- // TODO(davidben): Initialization can't be deferred to SSLClientSocket. See
- // https://crbug.com/539520.
- crypto::EnsureNSSInit();
- EnsureNSSHttpIOInit();
-#endif
- }
-
- void TearDown() override {
-#if defined(USE_NSS_CERTS)
- ShutdownNSSHttpIO();
-#endif
- }
-};
+ : public testing::TestWithParam<ThreadingTestParams> {};
class EmbeddedTestServerThreadingTestDelegate
: public base::PlatformThread::Delegate,
@@ -604,9 +570,9 @@ TEST_P(EmbeddedTestServerThreadingTest, RunTest) {
// of a MessageLoop - the test suite already sets up a MessageLoop for the
// main test thread.
base::PlatformThreadHandle thread_handle;
- EmbeddedTestServerThreadingTestDelegate delegate(
- std::tr1::get<0>(GetParam()), std::tr1::get<1>(GetParam()),
- std::tr1::get<2>(GetParam()));
+ EmbeddedTestServerThreadingTestDelegate delegate(std::get<0>(GetParam()),
+ std::get<1>(GetParam()),
+ std::get<2>(GetParam()));
ASSERT_TRUE(base::PlatformThread::Create(0, &delegate, &thread_handle));
base::PlatformThread::Join(thread_handle);
}
diff --git a/chromium/net/test/net_test_suite.cc b/chromium/net/test/net_test_suite.cc
index 792eeab126f..d26e50e4326 100644
--- a/chromium/net/test/net_test_suite.cc
+++ b/chromium/net/test/net_test_suite.cc
@@ -10,10 +10,6 @@
#include "net/spdy/chromium/spdy_session.h"
#include "testing/gtest/include/gtest/gtest.h"
-#if defined(USE_NSS_CERTS)
-#include "net/cert_net/nss_ocsp.h"
-#endif
-
namespace {
base::test::ScopedTaskEnvironment::MainThreadType kDefaultMainThreadType =
base::test::ScopedTaskEnvironment::MainThreadType::IO;
@@ -38,10 +34,6 @@ void NetTestSuite::Initialize() {
}
void NetTestSuite::Shutdown() {
-#if defined(USE_NSS_CERTS)
- net::ShutdownNSSHttpIO();
-#endif
-
// We want to destroy this here before the TestSuite continues to tear down
// the environment.
scoped_task_environment_.reset();
diff --git a/chromium/net/test/quic_simple_test_server.cc b/chromium/net/test/quic_simple_test_server.cc
new file mode 100644
index 00000000000..0f11650274e
--- /dev/null
+++ b/chromium/net/test/quic_simple_test_server.cc
@@ -0,0 +1,247 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/test/quic_simple_test_server.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/message_loop/message_loop.h"
+#include "base/path_service.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/thread.h"
+#include "net/base/ip_address.h"
+#include "net/base/ip_endpoint.h"
+#include "net/quic/chromium/crypto/proof_source_chromium.h"
+#include "net/spdy/core/spdy_header_block.h"
+#include "net/test/test_data_directory.h"
+#include "net/tools/quic/quic_dispatcher.h"
+#include "net/tools/quic/quic_http_response_cache.h"
+#include "net/tools/quic/quic_simple_server.h"
+
+namespace {
+
+const char kTestServerDomain[] = "example.com";
+// This must match the certificate used (quic-chain.pem and quic-leaf-cert.key).
+const char kTestServerHost[] = "test.example.com";
+
+const char kStatusHeader[] = ":status";
+
+const char kHelloPath[] = "/hello.txt";
+const char kHelloBodyValue[] = "Hello from QUIC Server";
+const char kHelloStatus[] = "200";
+
+const char kHelloHeaderName[] = "hello_header";
+const char kHelloHeaderValue[] = "hello header value";
+
+const char kHelloTrailerName[] = "hello_trailer";
+const char kHelloTrailerValue[] = "hello trailer value";
+
+const char kSimplePath[] = "/simple.txt";
+const char kSimpleBodyValue[] = "Simple Hello from QUIC Server";
+const char kSimpleStatus[] = "200";
+
+const char kSimpleHeaderName[] = "hello_header";
+const char kSimpleHeaderValue[] = "hello header value";
+
+base::Thread* g_quic_server_thread = nullptr;
+net::QuicHttpResponseCache* g_quic_response_cache = nullptr;
+net::QuicSimpleServer* g_quic_server = nullptr;
+int g_quic_server_port = 0;
+
+} // namespace
+
+namespace net {
+
+const std::string QuicSimpleTestServer::GetDomain() {
+ return kTestServerDomain;
+}
+
+const std::string QuicSimpleTestServer::GetHost() {
+ return kTestServerHost;
+}
+
+GURL QuicSimpleTestServer::GetFileURL(const std::string& file_path) {
+ return GURL("https://test.example.com:" + base::NumberToString(GetPort()))
+ .Resolve(file_path);
+}
+
+GURL QuicSimpleTestServer::GetHelloURL() {
+ // Don't include |port| into Hello URL as it is mapped differently.
+ return GURL("https://test.example.com").Resolve(kHelloPath);
+}
+
+const std::string QuicSimpleTestServer::GetStatusHeaderName() {
+ return kStatusHeader;
+}
+
+// Hello Url returns response with HTTP/2 headers and trailers.
+const std::string QuicSimpleTestServer::GetHelloPath() {
+ return kHelloPath;
+}
+
+const std::string QuicSimpleTestServer::GetHelloBodyValue() {
+ return kHelloBodyValue;
+}
+const std::string QuicSimpleTestServer::GetHelloStatus() {
+ return kHelloStatus;
+}
+
+const std::string QuicSimpleTestServer::GetHelloHeaderName() {
+ return kHelloHeaderName;
+}
+
+const std::string QuicSimpleTestServer::GetHelloHeaderValue() {
+ return kHelloHeaderValue;
+}
+
+const std::string QuicSimpleTestServer::GetHelloTrailerName() {
+ return kHelloTrailerName;
+}
+
+const std::string QuicSimpleTestServer::GetHelloTrailerValue() {
+ return kHelloTrailerValue;
+}
+
+// Simple Url returns response without HTTP/2 trailers.
+GURL QuicSimpleTestServer::GetSimpleURL() {
+ // Don't include |port| into Simple URL as it is mapped differently.
+ return GURL("https://test.example.com").Resolve(kSimplePath);
+}
+
+const std::string QuicSimpleTestServer::GetSimpleBodyValue() {
+ return kSimpleBodyValue;
+}
+
+const std::string QuicSimpleTestServer::GetSimpleStatus() {
+ return kSimpleStatus;
+}
+
+const std::string QuicSimpleTestServer::GetSimpleHeaderName() {
+ return kSimpleHeaderName;
+}
+
+const std::string QuicSimpleTestServer::GetSimpleHeaderValue() {
+ return kSimpleHeaderValue;
+}
+
+void SetupQuicHttpResponseCache() {
+ SpdyHeaderBlock headers;
+ headers[kHelloHeaderName] = kHelloHeaderValue;
+ headers[kStatusHeader] = kHelloStatus;
+ SpdyHeaderBlock trailers;
+ trailers[kHelloTrailerName] = kHelloTrailerValue;
+ g_quic_response_cache = new QuicHttpResponseCache();
+ g_quic_response_cache->AddResponse(base::StringPrintf("%s", kTestServerHost),
+ kHelloPath, std::move(headers),
+ kHelloBodyValue, std::move(trailers));
+ headers[kSimpleHeaderName] = kSimpleHeaderValue;
+ headers[kStatusHeader] = kSimpleStatus;
+ g_quic_response_cache->AddResponse(base::StringPrintf("%s", kTestServerHost),
+ kSimplePath, std::move(headers),
+ kSimpleBodyValue);
+}
+
+void StartQuicServerOnServerThread(const base::FilePath& test_files_root,
+ base::WaitableEvent* server_started_event) {
+ DCHECK(g_quic_server_thread->task_runner()->BelongsToCurrentThread());
+ DCHECK(!g_quic_server);
+
+ QuicConfig config;
+ // Set up server certs.
+ base::FilePath directory;
+ directory = test_files_root;
+ std::unique_ptr<ProofSourceChromium> proof_source(new ProofSourceChromium());
+ CHECK(proof_source->Initialize(directory.AppendASCII("quic-chain.pem"),
+ directory.AppendASCII("quic-leaf-cert.key"),
+ base::FilePath()));
+ SetupQuicHttpResponseCache();
+
+ g_quic_server = new QuicSimpleServer(
+ std::move(proof_source), config, QuicCryptoServerConfig::ConfigOptions(),
+ AllSupportedVersions(), g_quic_response_cache);
+
+ // Start listening on an unbound port.
+ int rv = g_quic_server->Listen(IPEndPoint(IPAddress::IPv4AllZeros(), 0));
+ CHECK_GE(rv, 0) << "Quic server fails to start";
+ g_quic_server_port = g_quic_server->server_address().port();
+ server_started_event->Signal();
+}
+
+void ShutdownOnServerThread(base::WaitableEvent* server_stopped_event) {
+ DCHECK(g_quic_server_thread->task_runner()->BelongsToCurrentThread());
+ g_quic_server->Shutdown();
+ delete g_quic_server;
+ g_quic_server = nullptr;
+ delete g_quic_response_cache;
+ g_quic_response_cache = nullptr;
+ server_stopped_event->Signal();
+}
+
+void ShutdownDispatcherOnServerThread(
+ base::WaitableEvent* dispatcher_stopped_event) {
+ DCHECK(g_quic_server_thread->task_runner()->BelongsToCurrentThread());
+ g_quic_server->dispatcher()->Shutdown();
+ dispatcher_stopped_event->Signal();
+}
+
+bool QuicSimpleTestServer::Start() {
+ DVLOG(3) << g_quic_server_thread;
+ DCHECK(!g_quic_server_thread);
+ g_quic_server_thread = new base::Thread("quic server thread");
+ base::Thread::Options thread_options;
+ thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
+ bool started = g_quic_server_thread->StartWithOptions(thread_options);
+ DCHECK(started);
+ base::FilePath test_files_root = GetTestCertsDirectory();
+
+ base::WaitableEvent server_started_event(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
+ g_quic_server_thread->task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(&StartQuicServerOnServerThread, test_files_root,
+ &server_started_event));
+ server_started_event.Wait();
+ return true;
+}
+
+// Shut down the server dispatcher, and the stream should error out.
+void QuicSimpleTestServer::ShutdownDispatcherForTesting() {
+ if (!g_quic_server)
+ return;
+ DCHECK(!g_quic_server_thread->task_runner()->BelongsToCurrentThread());
+ base::WaitableEvent dispatcher_stopped_event(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
+ g_quic_server_thread->task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(&ShutdownDispatcherOnServerThread,
+ &dispatcher_stopped_event));
+ dispatcher_stopped_event.Wait();
+}
+
+void QuicSimpleTestServer::Shutdown() {
+ if (!g_quic_server)
+ return;
+ DCHECK(!g_quic_server_thread->task_runner()->BelongsToCurrentThread());
+ base::WaitableEvent server_stopped_event(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
+ g_quic_server_thread->task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&ShutdownOnServerThread, &server_stopped_event));
+ server_stopped_event.Wait();
+ delete g_quic_server_thread;
+ g_quic_server_thread = nullptr;
+}
+
+int QuicSimpleTestServer::GetPort() {
+ return g_quic_server_port;
+}
+
+} // namespace net
diff --git a/chromium/net/test/quic_simple_test_server.h b/chromium/net/test/quic_simple_test_server.h
new file mode 100644
index 00000000000..03ed5b72e67
--- /dev/null
+++ b/chromium/net/test/quic_simple_test_server.h
@@ -0,0 +1,60 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_TEST_QUIC_SIMPLE_TEST_SERVER_H_
+#define NET_TEST_QUIC_SIMPLE_TEST_SERVER_H_
+
+#include <string>
+
+#include "url/gurl.h"
+
+namespace net {
+
+class QuicSimpleTestServer {
+ public:
+ static bool Start();
+ static void Shutdown();
+
+ // Shuts down the server dispatcher, which results in sending ConnectionClose
+ // frames to all connected clients.
+ static void ShutdownDispatcherForTesting();
+
+ // Returns example.com
+ static const std::string GetDomain();
+ // Returns test.example.com
+ static const std::string GetHost();
+ // Returns port number of the server.
+ static int GetPort();
+ // Returns test.example.com:port
+ static const std::string GetHostPort();
+
+ // Returns URL with host, port and file path, for example
+ // https://test.example.com:12345/{file_path}
+ static GURL GetFileURL(const std::string& file_path);
+
+ static const std::string GetStatusHeaderName();
+
+ // Server returns response with HTTP/2 headers and trailers. Does not include
+ // |port| as it is resolved differently: https://test.example.com/hello.txt
+ static GURL GetHelloURL();
+ static const std::string GetHelloPath();
+ static const std::string GetHelloBodyValue();
+ static const std::string GetHelloStatus();
+ static const std::string GetHelloHeaderName();
+ static const std::string GetHelloHeaderValue();
+ static const std::string GetHelloTrailerName();
+ static const std::string GetHelloTrailerValue();
+
+ // Server returns response without HTTP/2 trailers.
+ // https://test.example.com/simple.txt
+ static GURL GetSimpleURL();
+ static const std::string GetSimpleBodyValue();
+ static const std::string GetSimpleStatus();
+ static const std::string GetSimpleHeaderName();
+ static const std::string GetSimpleHeaderValue();
+};
+
+} // namespace net
+
+#endif // NET_TEST_QUIC_SIMPLE_TEST_SERVER_H_
diff --git a/chromium/net/tools/cert_verify_tool/cert_verify_tool.cc b/chromium/net/tools/cert_verify_tool/cert_verify_tool.cc
index b8c9f8df9c9..5be75021a94 100644
--- a/chromium/net/tools/cert_verify_tool/cert_verify_tool.cc
+++ b/chromium/net/tools/cert_verify_tool/cert_verify_tool.cc
@@ -51,7 +51,8 @@ void SetUpOnNetworkThread(std::unique_ptr<net::URLRequestContext>* context,
//
// TODO(akalin): Remove this once http://crbug.com/146421 is fixed.
url_request_context_builder.set_proxy_config_service(
- std::make_unique<net::ProxyConfigServiceFixed>(net::ProxyConfig()));
+ std::make_unique<net::ProxyConfigServiceFixed>(
+ net::ProxyConfigWithAnnotation()));
#endif
*context = url_request_context_builder.Build();
diff --git a/chromium/net/tools/cert_verify_tool/verify_using_cert_verify_proc.cc b/chromium/net/tools/cert_verify_tool/verify_using_cert_verify_proc.cc
index 9e745317292..a8580919283 100644
--- a/chromium/net/tools/cert_verify_tool/verify_using_cert_verify_proc.cc
+++ b/chromium/net/tools/cert_verify_tool/verify_using_cert_verify_proc.cc
@@ -150,8 +150,7 @@ bool VerifyUsingCertVerifyProc(
}
// TODO(mattm): add command line flags to configure VerifyFlags.
- int flags = net::CertVerifier::VERIFY_EV_CERT |
- net::CertVerifier::VERIFY_CERT_IO_ENABLED;
+ int flags = 0;
if (!x509_additional_trust_anchors.empty() &&
!cert_verify_proc->SupportsAdditionalTrustAnchors()) {
diff --git a/chromium/net/tools/cert_verify_tool/verify_using_path_builder.cc b/chromium/net/tools/cert_verify_tool/verify_using_path_builder.cc
index 7a936025d90..8621c76f179 100644
--- a/chromium/net/tools/cert_verify_tool/verify_using_path_builder.cc
+++ b/chromium/net/tools/cert_verify_tool/verify_using_path_builder.cc
@@ -174,7 +174,6 @@ bool VerifyUsingPathBuilder(
// TODO(mattm): add command line flags to configure using
// CertIssuerSourceAia
- // (similar to VERIFY_CERT_IO_ENABLED flag for CertVerifyProc).
DCHECK(net::GetGlobalCertNetFetcher());
net::CertIssuerSourceAia aia_cert_issuer_source(
net::GetGlobalCertNetFetcher());
diff --git a/chromium/net/tools/ct_log_list/make_ct_known_logs_list.py b/chromium/net/tools/ct_log_list/make_ct_known_logs_list.py
index c3ce09580be..2de125e7324 100755
--- a/chromium/net/tools/ct_log_list/make_ct_known_logs_list.py
+++ b/chromium/net/tools/ct_log_list/make_ct_known_logs_list.py
@@ -25,9 +25,6 @@ def _write_log_info_struct_definition(f):
" // The user-friendly log name.\n"
" // Note: This will not be translated.\n"
" const char* log_name;\n"
- " // The HTTPS API endpoint for the log.\n"
- " // Note: Trailing slashes should be included.\n"
- " const char* log_url;\n"
" // The DNS API endpoint for the log.\n"
" // This is used as the parent domain for all queries about the "
"log.\n // If empty, CT DNS queries are not supported for the log. "
@@ -132,7 +129,6 @@ def _to_loginfo_struct(log):
s += "\n ".join(split_hex_key)
s += ',\n %d' % (len(log_key))
s += ',\n "%s"' % (_escape_c_string(log["description"]))
- s += ',\n "https://%s"' % (log["url"])
s += ',\n "%s"' % (log["dns_api_endpoint"])
s += '}'
return s
diff --git a/chromium/net/tools/ct_log_list/make_ct_known_logs_list_unittest.py b/chromium/net/tools/ct_log_list/make_ct_known_logs_list_unittest.py
index 804b3c20ede..b4862bffcdf 100755
--- a/chromium/net/tools/ct_log_list/make_ct_known_logs_list_unittest.py
+++ b/chromium/net/tools/ct_log_list/make_ct_known_logs_list_unittest.py
@@ -69,7 +69,7 @@ class FormattingTest(unittest.TestCase):
"dns_api_endpoint": "dns.ct.example.com"}
expected_loginfo = (
' {"\\x61\\x62\\x63",\n 3,\n "Test Description",\n'
- ' "https://ct.example.com",\n "dns.ct.example.com"}')
+ ' "dns.ct.example.com"}')
self.assertEqual(
make_ct_known_logs_list._to_loginfo_struct(log),
expected_loginfo)
@@ -128,7 +128,7 @@ class DisqualifiedLogsHandlingTest(unittest.TestCase):
'\\xde\\x5d\\xae\\x22\\x23\\xb0"\n "\\x03\\x61\\xa3\\x96\\x17'
'\\x7a\\x9c\\xb4\\x10\\xff\\x61\\xf2\\x00\\x15\\xad",\n {"\\x61'
'\\x62\\x63",\n 3,\n "Test Description",\n '
- '"https://ct.example.com",\n "dns.ct.example.com"},\n '
+ '"dns.ct.example.com"},\n '
'base::TimeDelta::FromSeconds(1464566400)}')
self.assertEqual(
diff --git a/chromium/net/tools/net_watcher/net_watcher.cc b/chromium/net/tools/net_watcher/net_watcher.cc
index 6819f564252..be417380cf7 100644
--- a/chromium/net/tools/net_watcher/net_watcher.cc
+++ b/chromium/net/tools/net_watcher/net_watcher.cc
@@ -28,7 +28,7 @@
#include "net/base/network_change_notifier.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
#include "net/base/network_change_notifier_linux.h"
@@ -130,11 +130,10 @@ class NetWatcher :
// net::ProxyConfigService::Observer implementation.
void OnProxyConfigChanged(
- const net::ProxyConfig& config,
+ const net::ProxyConfigWithAnnotation& config,
net::ProxyConfigService::ConfigAvailability availability) override {
- LOG(INFO) << "OnProxyConfigChanged("
- << ProxyConfigToString(config) << ", "
- << ConfigAvailabilityToString(availability) << ")";
+ LOG(INFO) << "OnProxyConfigChanged(" << ProxyConfigToString(config.value())
+ << ", " << ConfigAvailabilityToString(availability) << ")";
}
private:
@@ -196,12 +195,11 @@ int main(int argc, char* argv[]) {
net::NetworkChangeNotifier::GetConnectionType());
{
- net::ProxyConfig config;
+ net::ProxyConfigWithAnnotation config;
const net::ProxyConfigService::ConfigAvailability availability =
proxy_config_service->GetLatestProxyConfig(&config);
- LOG(INFO) << "Initial proxy config: "
- << ProxyConfigToString(config) << ", "
- << ConfigAvailabilityToString(availability);
+ LOG(INFO) << "Initial proxy config: " << ProxyConfigToString(config.value())
+ << ", " << ConfigAvailabilityToString(availability);
}
LOG(INFO) << "Watching for network events...";
diff --git a/chromium/net/tools/quic/chlo_extractor.cc b/chromium/net/tools/quic/chlo_extractor.cc
index 2fadb6d1445..7ef853a939c 100644
--- a/chromium/net/tools/quic/chlo_extractor.cc
+++ b/chromium/net/tools/quic/chlo_extractor.cc
@@ -53,6 +53,9 @@ class ChloFramerVisitor : public QuicFramerVisitorInterface,
bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
void OnPacketComplete() override {}
+ bool IsValidStatelessResetToken(uint128 token) const override;
+ void OnAuthenticatedIetfStatelessResetPacket(
+ const QuicIetfStatelessResetPacket& packet) override {}
// CryptoFramerVisitorInterface implementation.
void OnError(CryptoFramer* framer) override;
@@ -110,23 +113,21 @@ bool ChloFramerVisitor::OnStreamFrame(const QuicStreamFrame& frame) {
if (!crypto_framer.ProcessInput(data, Perspective::IS_SERVER)) {
return false;
}
- if (FLAGS_quic_reloadable_flag_quic_inspect_chlo_tags) {
- // Interrogate the crypto framer and see if there are any
- // intersecting tags between what we saw in the maybe-CHLO and the
- // indicator set.
- for (const QuicTag tag : create_session_tag_indicators_) {
- if (crypto_framer.HasTag(tag)) {
- chlo_contains_tags_ = true;
- }
- }
- if (chlo_contains_tags_ && delegate_) {
- // Unfortunately, because this is a partial CHLO,
- // OnHandshakeMessage was never called, so the ALPN was never
- // extracted. Fake it up a bit and send it to the delegate so that
- // the correct dispatch can happen.
- crypto_framer.ForceHandshake();
+ // Interrogate the crypto framer and see if there are any
+ // intersecting tags between what we saw in the maybe-CHLO and the
+ // indicator set.
+ for (const QuicTag tag : create_session_tag_indicators_) {
+ if (crypto_framer.HasTag(tag)) {
+ chlo_contains_tags_ = true;
}
}
+ if (chlo_contains_tags_ && delegate_) {
+ // Unfortunately, because this is a partial CHLO,
+ // OnHandshakeMessage was never called, so the ALPN was never
+ // extracted. Fake it up a bit and send it to the delegate so that
+ // the correct dispatch can happen.
+ crypto_framer.ForceHandshake();
+ }
}
return true;
@@ -181,6 +182,10 @@ bool ChloFramerVisitor::OnPaddingFrame(const QuicPaddingFrame& frame) {
return true;
}
+bool ChloFramerVisitor::IsValidStatelessResetToken(uint128 token) const {
+ return false;
+}
+
void ChloFramerVisitor::OnError(CryptoFramer* framer) {}
void ChloFramerVisitor::OnHandshakeMessage(
diff --git a/chromium/net/tools/quic/chlo_extractor_test.cc b/chromium/net/tools/quic/chlo_extractor_test.cc
index 72c68b51f91..f02b5d1bb30 100644
--- a/chromium/net/tools/quic/chlo_extractor_test.cc
+++ b/chromium/net/tools/quic/chlo_extractor_test.cc
@@ -4,14 +4,17 @@
#include "net/tools/quic/chlo_extractor.h"
+#include <memory>
+
#include "net/quic/core/quic_framer.h"
+#include "net/quic/platform/api/quic_arraysize.h"
#include "net/quic/platform/api/quic_ptr_util.h"
#include "net/quic/platform/api/quic_string.h"
#include "net/quic/platform/api/quic_test.h"
#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
-using testing::_;
+using std::string;
namespace net {
namespace test {
@@ -49,7 +52,7 @@ class ChloExtractorTest : public QuicTest {
header_.version_flag = true;
header_.version = AllSupportedVersions().front();
header_.reset_flag = false;
- header_.packet_number_length = PACKET_6BYTE_PACKET_NUMBER;
+ header_.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
header_.packet_number = 1;
}
@@ -64,7 +67,7 @@ class ChloExtractorTest : public QuicTest {
EXPECT_TRUE(packet != nullptr);
size_t encrypted_length =
framer.EncryptPayload(ENCRYPTION_NONE, header_.packet_number, *packet,
- buffer_, arraysize(buffer_));
+ buffer_, QUIC_ARRAYSIZE(buffer_));
ASSERT_NE(0u, encrypted_length);
packet_ = QuicMakeUnique<QuicEncryptedPacket>(buffer_, encrypted_length);
EXPECT_TRUE(packet_ != nullptr);
@@ -82,9 +85,8 @@ TEST_F(ChloExtractorTest, FindsValidChlo) {
CryptoHandshakeMessage client_hello;
client_hello.set_tag(kCHLO);
- QuicString client_hello_str(client_hello.GetSerialized(Perspective::IS_CLIENT)
- .AsStringPiece()
- .as_string());
+ string client_hello_str((string(
+ client_hello.GetSerialized(Perspective::IS_CLIENT).AsStringPiece())));
// Construct a CHLO with each supported version
for (ParsedQuicVersion version : AllSupportedVersions()) {
ParsedQuicVersionVector versions(SupportedVersions(version));
@@ -105,9 +107,8 @@ TEST_F(ChloExtractorTest, DoesNotFindValidChloOnWrongStream) {
CryptoHandshakeMessage client_hello;
client_hello.set_tag(kCHLO);
- QuicString client_hello_str(client_hello.GetSerialized(Perspective::IS_CLIENT)
- .AsStringPiece()
- .as_string());
+ string client_hello_str((string(
+ client_hello.GetSerialized(Perspective::IS_CLIENT).AsStringPiece())));
MakePacket(
new QuicStreamFrame(kCryptoStreamId + 1, false, 0, client_hello_str));
EXPECT_FALSE(
@@ -118,9 +119,8 @@ TEST_F(ChloExtractorTest, DoesNotFindValidChloOnWrongOffset) {
CryptoHandshakeMessage client_hello;
client_hello.set_tag(kCHLO);
- QuicString client_hello_str(client_hello.GetSerialized(Perspective::IS_CLIENT)
- .AsStringPiece()
- .as_string());
+ string client_hello_str((string(
+ client_hello.GetSerialized(Perspective::IS_CLIENT).AsStringPiece())));
MakePacket(new QuicStreamFrame(kCryptoStreamId, false, 1, client_hello_str));
EXPECT_FALSE(
ChloExtractor::Extract(*packet_, AllSupportedVersions(), {}, &delegate_));
diff --git a/chromium/net/tools/quic/crypto_message_printer_bin.cc b/chromium/net/tools/quic/crypto_message_printer_bin.cc
index b466a008ab3..260175441ef 100644
--- a/chromium/net/tools/quic/crypto_message_printer_bin.cc
+++ b/chromium/net/tools/quic/crypto_message_printer_bin.cc
@@ -68,6 +68,7 @@ int main(int argc, char* argv[]) {
net::CryptoMessagePrinter printer(perspective);
net::CryptoFramer framer;
framer.set_visitor(&printer);
+ framer.set_process_truncated_messages(true);
std::string input = net::QuicTextUtils::HexDecode(argv[1]);
if (!framer.ProcessInput(input, perspective)) {
return 1;
diff --git a/chromium/net/tools/quic/end_to_end_test.cc b/chromium/net/tools/quic/end_to_end_test.cc
index 2fdc7ba0dbd..d43f8c3ef02 100644
--- a/chromium/net/tools/quic/end_to_end_test.cc
+++ b/chromium/net/tools/quic/end_to_end_test.cc
@@ -576,23 +576,6 @@ class EndToEndTest : public QuicTestWithParam<TestParams> {
*client_->client()->client_session(), n);
}
- void WaitForDelayedAcks() {
- // kWaitDuration is a period of time that is long enough for all delayed
- // acks to be sent and received on the other end.
- const QuicTime::Delta kWaitDuration =
- 4 * QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
-
- const QuicClock* clock =
- client_->client()->client_session()->connection()->clock();
-
- QuicTime wait_until = clock->ApproximateNow() + kWaitDuration;
- while (clock->ApproximateNow() < wait_until) {
- QUIC_LOG_EVERY_N_SEC(INFO, 0.01) << "Waiting for delayed acks...";
- // This waits for up to 50 ms.
- client_->client()->WaitForEvents();
- }
- }
-
bool initialized_;
QuicSocketAddress server_address_;
QuicString server_hostname_;
@@ -617,6 +600,7 @@ class EndToEndTestWithTls : public EndToEndTest {
protected:
EndToEndTestWithTls() : EndToEndTest() {
FLAGS_quic_reloadable_flag_delay_quic_server_handshaker_construction = true;
+ SetQuicReloadableFlag(quic_server_early_version_negotiation, true);
}
};
@@ -1642,6 +1626,26 @@ TEST_P(EndToEndTest, ConnectionMigrationClientPortChanged) {
EXPECT_NE(old_address.port(), new_address.port());
}
+TEST_P(EndToEndTest, NegotiatedInitialCongestionWindow) {
+ SetQuicReloadableFlag(quic_unified_iw_options, true);
+ client_extra_copts_.push_back(kIW03);
+
+ ASSERT_TRUE(Initialize());
+
+ // Values are exchanged during crypto handshake, so wait for that to finish.
+ EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
+ server_thread_->WaitForCryptoHandshakeConfirmed();
+ server_thread_->Pause();
+
+ QuicDispatcher* dispatcher =
+ QuicServerPeer::GetDispatcher(server_thread_->server());
+ QuicSession* session = dispatcher->session_map().begin()->second.get();
+ QuicConnection* server_connection = session->connection();
+ QuicPacketCount cwnd =
+ server_connection->sent_packet_manager().initial_congestion_window();
+ EXPECT_EQ(3u, cwnd);
+}
+
TEST_P(EndToEndTest, DifferentFlowControlWindows) {
// Client and server can set different initial flow control receive windows.
// These are sent in CHLO/SHLO. Tests that these values are exchanged properly
@@ -2076,7 +2080,7 @@ TEST_P(EndToEndTestWithTls,
QuicConnectionId incorrect_connection_id =
client_->client()->client_session()->connection()->connection_id() + 1;
std::unique_ptr<QuicEncryptedPacket> packet(
- QuicFramer::BuildVersionNegotiationPacket(incorrect_connection_id,
+ QuicFramer::BuildVersionNegotiationPacket(incorrect_connection_id, false,
server_supported_versions_));
testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
client_->client()->client_session()->connection()->set_debug_visitor(
@@ -2194,7 +2198,7 @@ TEST_P(EndToEndTestWithTls, BadEncryptedData) {
std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
client_->client()->client_session()->connection()->connection_id(), false,
false, 1, "At least 20 characters.", PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER));
+ PACKET_4BYTE_PACKET_NUMBER));
// Damage the encrypted data.
QuicString damaged_packet(packet->data(), packet->length());
damaged_packet[30] ^= 0x01;
@@ -2956,17 +2960,22 @@ TEST_P(EndToEndTest, WayTooLongRequestHeaders) {
class WindowUpdateObserver : public QuicConnectionDebugVisitor {
public:
- WindowUpdateObserver() : num_window_update_frames_(0) {}
+ WindowUpdateObserver() : num_window_update_frames_(0), num_ping_frames_(0) {}
size_t num_window_update_frames() const { return num_window_update_frames_; }
+ size_t num_ping_frames() const { return num_ping_frames_; }
+
void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame,
const QuicTime& receive_time) override {
++num_window_update_frames_;
}
+ void OnPingFrame(const QuicPingFrame& frame) override { ++num_ping_frames_; }
+
private:
size_t num_window_update_frames_;
+ size_t num_ping_frames_;
};
TEST_P(EndToEndTest, WindowUpdateInAck) {
@@ -2990,6 +2999,13 @@ TEST_P(EndToEndTest, WindowUpdateInAck) {
client_->Disconnect();
if (version > QUIC_VERSION_38) {
EXPECT_LT(0u, observer.num_window_update_frames());
+ if (GetQuicReloadableFlag(quic_remove_redundant_ping)) {
+ EXPECT_EQ(0u, observer.num_ping_frames());
+ } else {
+ // A redundant PING frame is bundled with each WINDOW_UPDATE frame.
+ EXPECT_EQ(observer.num_window_update_frames(),
+ observer.num_ping_frames());
+ }
} else {
EXPECT_EQ(0u, observer.num_window_update_frames());
}
@@ -3033,7 +3049,7 @@ TEST_P(EndToEndTest, LastPacketSentIsConnectivityProbing) {
EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
// Wait for the client's ACK (of the response) to be received by the server.
- WaitForDelayedAcks();
+ client_->WaitForDelayedAcks();
// We are sending a connectivity probing packet from an unchanged client
// address, so the server will not respond to us with a connectivity probing
@@ -3041,7 +3057,7 @@ TEST_P(EndToEndTest, LastPacketSentIsConnectivityProbing) {
client_->SendConnectivityProbing();
// Wait for the server's last ACK to be received by the client.
- WaitForDelayedAcks();
+ client_->WaitForDelayedAcks();
}
class EndToEndBufferedPacketsTest : public EndToEndTest {
diff --git a/chromium/net/tools/quic/quic_client_base.cc b/chromium/net/tools/quic/quic_client_base.cc
index 310a5c01b9d..c8fa05f4d48 100644
--- a/chromium/net/tools/quic/quic_client_base.cc
+++ b/chromium/net/tools/quic/quic_client_base.cc
@@ -141,6 +141,7 @@ void QuicClientBase::InitializeSession() {
void QuicClientBase::Disconnect() {
DCHECK(initialized_);
+ initialized_ = false;
if (connected()) {
session()->connection()->CloseConnection(
QUIC_PEER_GOING_AWAY, "Client disconnecting",
@@ -150,8 +151,6 @@ void QuicClientBase::Disconnect() {
ClearDataToResend();
network_helper_->CleanUpAllUDPSockets();
-
- initialized_ = false;
}
ProofVerifier* QuicClientBase::proof_verifier() const {
diff --git a/chromium/net/tools/quic/quic_client_base.h b/chromium/net/tools/quic/quic_client_base.h
index cb26051945c..f3d1d5aeee2 100644
--- a/chromium/net/tools/quic/quic_client_base.h
+++ b/chromium/net/tools/quic/quic_client_base.h
@@ -229,6 +229,8 @@ class QuicClientBase {
NetworkHelper* network_helper();
const NetworkHelper* network_helper() const;
+ bool initialized() const { return initialized_; }
+
protected:
// TODO(rch): Move GetNumSentClientHellosFromSession and
// GetNumReceivedServerConfigUpdatesFromSession into a new/better
diff --git a/chromium/net/tools/quic/quic_client_epoll_network_helper.h b/chromium/net/tools/quic/quic_client_epoll_network_helper.h
index 61fbaf022a1..a5117fd6a20 100644
--- a/chromium/net/tools/quic/quic_client_epoll_network_helper.h
+++ b/chromium/net/tools/quic/quic_client_epoll_network_helper.h
@@ -92,6 +92,9 @@ class QuicClientEpollNetworkHelper : public QuicClientBase::NetworkHelper,
void set_max_reads_per_epoll_loop(int num_reads) {
max_reads_per_epoll_loop_ = num_reads;
}
+ // If |fd| is an open UDP socket, unregister and close it. Otherwise, do
+ // nothing.
+ void CleanUpUDPSocket(int fd);
private:
friend class test::QuicClientPeer;
@@ -99,10 +102,6 @@ class QuicClientEpollNetworkHelper : public QuicClientBase::NetworkHelper,
// Used for testing.
void SetClientPort(int port);
- // If |fd| is an open UDP socket, unregister and close it. Otherwise, do
- // nothing.
- void CleanUpUDPSocket(int fd);
-
// Actually clean up |fd|.
void CleanUpUDPSocketImpl(int fd);
diff --git a/chromium/net/tools/quic/quic_client_message_loop_network_helper.cc b/chromium/net/tools/quic/quic_client_message_loop_network_helper.cc
index 6c524fae2e2..b60ba04d575 100644
--- a/chromium/net/tools/quic/quic_client_message_loop_network_helper.cc
+++ b/chromium/net/tools/quic/quic_client_message_loop_network_helper.cc
@@ -45,9 +45,8 @@ bool QuicClientMessageLooplNetworkHelper::CreateUDPSocketAndBind(
QuicSocketAddress server_address,
QuicIpAddress bind_to_address,
int bind_to_port) {
- std::unique_ptr<UDPClientSocket> socket(
- new UDPClientSocket(DatagramSocket::DEFAULT_BIND, RandIntCallback(),
- &net_log_, NetLogSource()));
+ auto socket = std::make_unique<UDPClientSocket>(DatagramSocket::DEFAULT_BIND,
+ &net_log_, NetLogSource());
if (bind_to_address.IsInitialized()) {
client_address_ = QuicSocketAddress(bind_to_address, client_->local_port());
diff --git a/chromium/net/tools/quic/quic_dispatcher.cc b/chromium/net/tools/quic/quic_dispatcher.cc
index 8ed5d9e6bd1..591c45869a7 100644
--- a/chromium/net/tools/quic/quic_dispatcher.cc
+++ b/chromium/net/tools/quic/quic_dispatcher.cc
@@ -60,9 +60,9 @@ class PacketCollector : public QuicPacketCreator::DelegateInterface,
// QuicPacketCreator::DelegateInterface methods:
void OnSerializedPacket(SerializedPacket* serialized_packet) override {
// Make a copy of the serialized packet to send later.
- packets_.push_back(std::unique_ptr<QuicEncryptedPacket>(
+ packets_.emplace_back(
new QuicEncryptedPacket(CopyBuffer(*serialized_packet),
- serialized_packet->encrypted_length, true)));
+ serialized_packet->encrypted_length, true));
serialized_packet->encrypted_buffer = nullptr;
DeleteFrames(&(serialized_packet->retransmittable_frames));
serialized_packet->retransmittable_frames.clear();
@@ -136,7 +136,7 @@ class StatelessConnectionTerminator {
creator_.Flush();
DCHECK_EQ(1u, collector_.packets()->size());
time_wait_list_manager_->AddConnectionIdToTimeWait(
- connection_id_, framer_->version(),
+ connection_id_, framer_->version(), framer_->last_packet_is_ietf_quic(),
/*connection_rejected_statelessly=*/false, collector_.packets());
}
@@ -162,7 +162,7 @@ class StatelessConnectionTerminator {
creator_.Flush();
}
time_wait_list_manager_->AddConnectionIdToTimeWait(
- connection_id_, framer_->version(),
+ connection_id_, framer_->version(), framer_->last_packet_is_ietf_quic(),
/*connection_rejected_statelessly=*/true, collector_.packets());
DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id_));
}
@@ -279,6 +279,8 @@ void QuicDispatcher::ProcessPacket(const QuicSocketAddress& self_address,
const QuicReceivedPacket& packet) {
current_self_address_ = self_address;
current_peer_address_ = peer_address;
+ // GetClientAddress must be called after current_peer_address_ is set.
+ current_client_address_ = GetClientAddress();
current_packet_ = &packet;
// ProcessPacket will cause the packet to be dispatched in
// OnUnauthenticatedPublicHeader, or sent to the time wait list manager
@@ -286,6 +288,8 @@ void QuicDispatcher::ProcessPacket(const QuicSocketAddress& self_address,
framer_.ProcessPacket(packet);
// TODO(rjshade): Return a status describing if/why a packet was dropped,
// and log somehow. Maybe expose as a varz.
+ // TODO(wub): Consider invalidate the current_* variables so processing of the
+ // next packet does not use them incorrectly.
}
bool QuicDispatcher::OnUnauthenticatedPublicHeader(
@@ -319,7 +323,7 @@ bool QuicDispatcher::OnUnauthenticatedPublicHeader(
}
if (buffered_packets_.HasChloForConnection(connection_id)) {
- BufferEarlyPacket(connection_id);
+ BufferEarlyPacket(connection_id, framer_.last_packet_is_ietf_quic());
return false;
}
@@ -328,7 +332,7 @@ bool QuicDispatcher::OnUnauthenticatedPublicHeader(
temporarily_buffered_connections_.end()) {
// This packet was received while the a CHLO for the same connection ID was
// being processed. Buffer it.
- BufferEarlyPacket(connection_id);
+ BufferEarlyPacket(connection_id, framer_.last_packet_is_ietf_quic());
return false;
}
@@ -366,8 +370,8 @@ bool QuicDispatcher::OnUnauthenticatedPublicHeader(
// Since the version is not supported, send a version negotiation
// packet and stop processing the current packet.
time_wait_list_manager()->SendVersionNegotiationPacket(
- connection_id, GetSupportedVersions(), current_self_address_,
- current_peer_address_);
+ connection_id, framer_.last_packet_is_ietf_quic(),
+ GetSupportedVersions(), current_self_address_, current_peer_address_);
return false;
}
version = packet_version;
@@ -421,6 +425,7 @@ void QuicDispatcher::ProcessUnauthenticatedHeaderFate(
<< "to time-wait list.";
time_wait_list_manager_->AddConnectionIdToTimeWait(
connection_id, framer_.version(),
+ framer_.last_packet_is_ietf_quic(),
/*connection_rejected_statelessly=*/false, nullptr);
}
DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
@@ -437,7 +442,7 @@ void QuicDispatcher::ProcessUnauthenticatedHeaderFate(
// This packet is a non-CHLO packet which has arrived before the
// corresponding CHLO, *or* this packet was received while the
// corresponding CHLO was being processed. Buffer it.
- BufferEarlyPacket(connection_id);
+ BufferEarlyPacket(connection_id, framer_.last_packet_is_ietf_quic());
break;
case kFateDrop:
// Do nothing with the packet.
@@ -505,7 +510,7 @@ void QuicDispatcher::CleanUpSession(SessionMap::iterator it,
!connection->termination_packets()->empty());
}
time_wait_list_manager_->AddConnectionIdToTimeWait(
- it->first, connection->version(), should_close_statelessly,
+ it->first, connection->version(), false, should_close_statelessly,
connection->termination_packets());
session_map_.erase(it);
}
@@ -720,11 +725,22 @@ void QuicDispatcher::OnPacketComplete() {
DCHECK(false);
}
+bool QuicDispatcher::IsValidStatelessResetToken(uint128 token) const {
+ DCHECK(false);
+ return false;
+}
+
+void QuicDispatcher::OnAuthenticatedIetfStatelessResetPacket(
+ const QuicIetfStatelessResetPacket& packet) {
+ DCHECK(false);
+}
+
void QuicDispatcher::OnExpiredPackets(
QuicConnectionId connection_id,
BufferedPacketList early_arrived_packets) {
time_wait_list_manager_->AddConnectionIdToTimeWait(
- connection_id, framer_.version(), false, nullptr);
+ connection_id, framer_.version(), early_arrived_packets.ietf_quic, false,
+ nullptr);
}
void QuicDispatcher::ProcessBufferedChlos(size_t max_connections_to_create) {
@@ -781,14 +797,15 @@ QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() {
alarm_factory_.get());
}
-void QuicDispatcher::BufferEarlyPacket(QuicConnectionId connection_id) {
+void QuicDispatcher::BufferEarlyPacket(QuicConnectionId connection_id,
+ bool ietf_quic) {
bool is_new_connection = !buffered_packets_.HasBufferedPackets(connection_id);
if (is_new_connection &&
!ShouldCreateOrBufferPacketForConnection(connection_id)) {
return;
}
EnqueuePacketResult rs = buffered_packets_.EnqueuePacket(
- connection_id, *current_packet_, current_self_address_,
+ connection_id, ietf_quic, *current_packet_, current_self_address_,
current_peer_address_, /*is_chlo=*/false, /*alpn=*/"");
if (rs != EnqueuePacketResult::SUCCESS) {
OnBufferPacketFailure(rs, connection_id);
@@ -800,6 +817,7 @@ void QuicDispatcher::ProcessChlo() {
// Don't any create new connection.
time_wait_list_manager()->AddConnectionIdToTimeWait(
current_connection_id(), framer()->version(),
+ framer()->last_packet_is_ietf_quic(),
/*connection_rejected_statelessly=*/false,
/*termination_packets=*/nullptr);
// This will trigger sending Public Reset packet.
@@ -817,8 +835,9 @@ void QuicDispatcher::ProcessChlo() {
// Can't create new session any more. Wait till next event loop.
QUIC_BUG_IF(buffered_packets_.HasChloForConnection(current_connection_id_));
EnqueuePacketResult rs = buffered_packets_.EnqueuePacket(
- current_connection_id_, *current_packet_, current_self_address_,
- current_peer_address_, /*is_chlo=*/true, current_alpn_);
+ current_connection_id_, framer_.last_packet_is_ietf_quic(),
+ *current_packet_, current_self_address_, current_peer_address_,
+ /*is_chlo=*/true, current_alpn_);
if (rs != EnqueuePacketResult::SUCCESS) {
OnBufferPacketFailure(rs, current_connection_id_);
}
@@ -886,6 +905,7 @@ class StatelessRejectorProcessDoneCallback
StatelessRejectorProcessDoneCallback(QuicDispatcher* dispatcher,
ParsedQuicVersion first_version)
: dispatcher_(dispatcher),
+ current_client_address_(dispatcher->current_client_address_),
current_peer_address_(dispatcher->current_peer_address_),
current_self_address_(dispatcher->current_self_address_),
current_packet_(
@@ -894,12 +914,13 @@ class StatelessRejectorProcessDoneCallback
void Run(std::unique_ptr<StatelessRejector> rejector) override {
dispatcher_->OnStatelessRejectorProcessDone(
- std::move(rejector), current_peer_address_, current_self_address_,
- std::move(current_packet_), first_version_);
+ std::move(rejector), current_client_address_, current_peer_address_,
+ current_self_address_, std::move(current_packet_), first_version_);
}
private:
QuicDispatcher* dispatcher_;
+ QuicSocketAddress current_client_address_;
QuicSocketAddress current_peer_address_;
QuicSocketAddress current_self_address_;
std::unique_ptr<QuicReceivedPacket> current_packet_;
@@ -937,7 +958,7 @@ void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id,
version.transport_version, GetSupportedTransportVersions(),
crypto_config_, &compressed_certs_cache_, helper()->GetClock(),
helper()->GetRandomGenerator(), current_packet_->length(),
- GetClientAddress(), current_self_address_));
+ current_client_address_, current_self_address_));
ChloValidator validator(session_helper_.get(), current_self_address_,
rejector.get());
if (!ChloExtractor::Extract(*current_packet_, GetSupportedVersions(),
@@ -982,6 +1003,7 @@ void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id,
void QuicDispatcher::OnStatelessRejectorProcessDone(
std::unique_ptr<StatelessRejector> rejector,
+ const QuicSocketAddress& current_client_address,
const QuicSocketAddress& current_peer_address,
const QuicSocketAddress& current_self_address,
std::unique_ptr<QuicReceivedPacket> current_packet,
@@ -1004,6 +1026,7 @@ void QuicDispatcher::OnStatelessRejectorProcessDone(
// Reset current_* to correspond to the packet which initiated the stateless
// reject logic.
+ current_client_address_ = current_client_address;
current_peer_address_ = current_peer_address;
current_self_address_ = current_self_address;
current_packet_ = current_packet.get();
diff --git a/chromium/net/tools/quic/quic_dispatcher.h b/chromium/net/tools/quic/quic_dispatcher.h
index 8339e82a24b..27c7c8cad6e 100644
--- a/chromium/net/tools/quic/quic_dispatcher.h
+++ b/chromium/net/tools/quic/quic_dispatcher.h
@@ -150,6 +150,9 @@ class QuicDispatcher : public QuicTimeWaitListManager::Visitor,
bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
void OnPacketComplete() override;
+ bool IsValidStatelessResetToken(uint128 token) const override;
+ void OnAuthenticatedIetfStatelessResetPacket(
+ const QuicIetfStatelessResetPacket& packet) override;
// QuicBufferedPacketStore::VisitorInterface implementation.
void OnExpiredPackets(QuicConnectionId connection_id,
@@ -203,14 +206,19 @@ class QuicDispatcher : public QuicTimeWaitListManager::Visitor,
// Called when |connection_id| doesn't have an open connection yet, to buffer
// |current_packet_| until it can be delivered to the connection.
- void BufferEarlyPacket(QuicConnectionId connection_id);
+ void BufferEarlyPacket(QuicConnectionId connection_id, bool ietf_quic);
// Called when |current_packet_| is a CHLO packet. Creates a new connection
// and delivers any buffered packets for that connection id.
void ProcessChlo();
- // Returns client address used for stateless rejector to generate and validate
- // source address token.
+ // Returns the actual client address of the current packet.
+ // This function should only be called once per packet at the very beginning
+ // of ProcessPacket(), its result is saved to |current_client_address_|, which
+ // is guaranteed to be valid even in the stateless rejector's callback(i.e.
+ // OnStatelessRejectorProcessDone).
+ // By default, this function returns |current_peer_address_|, subclasses have
+ // the option to override this function to return a different address.
virtual const QuicSocketAddress GetClientAddress() const;
// Return true if dispatcher wants to destroy session outside of
@@ -225,14 +233,19 @@ class QuicDispatcher : public QuicTimeWaitListManager::Visitor,
const ParsedQuicVersionVector& GetSupportedVersions();
- QuicConnectionId current_connection_id() { return current_connection_id_; }
- const QuicSocketAddress& current_self_address() {
+ QuicConnectionId current_connection_id() const {
+ return current_connection_id_;
+ }
+ const QuicSocketAddress& current_self_address() const {
return current_self_address_;
}
- const QuicSocketAddress& current_peer_address() {
+ const QuicSocketAddress& current_peer_address() const {
return current_peer_address_;
}
- const QuicReceivedPacket& current_packet() { return *current_packet_; }
+ const QuicSocketAddress& current_client_address() const {
+ return current_client_address_;
+ }
+ const QuicReceivedPacket& current_packet() const { return *current_packet_; }
const QuicConfig& config() const { return config_; }
@@ -327,8 +340,11 @@ class QuicDispatcher : public QuicTimeWaitListManager::Visitor,
// Invoked when StatelessRejector::Process completes. |first_version| is the
// version of the packet which initiated the stateless reject.
+ // WARNING: This function can be called when a async proof returns, i.e. not
+ // from a stack traceable to ProcessPacket().
void OnStatelessRejectorProcessDone(
std::unique_ptr<StatelessRejector> rejector,
+ const QuicSocketAddress& current_client_address,
const QuicSocketAddress& current_peer_address,
const QuicSocketAddress& current_self_address,
std::unique_ptr<QuicReceivedPacket> current_packet,
@@ -388,6 +404,9 @@ class QuicDispatcher : public QuicTimeWaitListManager::Visitor,
QuicConnectionIdSet temporarily_buffered_connections_;
// Information about the packet currently being handled.
+
+ // Used for stateless rejector to generate and validate source address token.
+ QuicSocketAddress current_client_address_;
QuicSocketAddress current_peer_address_;
QuicSocketAddress current_self_address_;
const QuicReceivedPacket* current_packet_;
diff --git a/chromium/net/tools/quic/quic_dispatcher_test.cc b/chromium/net/tools/quic/quic_dispatcher_test.cc
index eca86ff7d6c..1f118e14f62 100644
--- a/chromium/net/tools/quic/quic_dispatcher_test.cc
+++ b/chromium/net/tools/quic/quic_dispatcher_test.cc
@@ -43,6 +43,7 @@
#include "testing/gmock_mutant.h"
#include "testing/gtest/include/gtest/gtest.h"
+using std::string;
using testing::_;
using testing::InSequence;
using testing::Invoke;
@@ -139,6 +140,7 @@ class TestDispatcher : public QuicDispatcher {
MOCK_METHOD1(ShouldCreateOrBufferPacketForConnection,
bool(QuicConnectionId connection_id));
+ using QuicDispatcher::current_client_address;
using QuicDispatcher::current_peer_address;
using QuicDispatcher::current_self_address;
};
@@ -223,7 +225,7 @@ class QuicDispatcherTest : public QuicTest {
bool has_version_flag,
const QuicString& data) {
ProcessPacket(peer_address, connection_id, has_version_flag, data,
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER);
+ PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER);
}
// Process a packet with a default path id, and packet number 1,
@@ -322,9 +324,8 @@ class QuicDispatcherTest : public QuicTest {
CryptoHandshakeMessage client_hello;
client_hello.set_tag(kCHLO);
client_hello.SetStringPiece(kALPN, "hq");
- return client_hello.GetSerialized(Perspective::IS_CLIENT)
- .AsStringPiece()
- .as_string();
+ return string(
+ client_hello.GetSerialized(Perspective::IS_CLIENT).AsStringPiece());
}
QuicString SerializeTlsClientHello() { return ""; }
@@ -367,7 +368,7 @@ TEST_F(QuicDispatcherTest, TlsClientHelloCreatesSession) {
client_address, 1, true,
ParsedQuicVersion(PROTOCOL_TLS1_3,
CurrentSupportedVersions().front().transport_version),
- SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
+ SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
1);
EXPECT_EQ(client_address, dispatcher_->current_peer_address());
EXPECT_EQ(server_address_, dispatcher_->current_self_address());
@@ -427,7 +428,7 @@ TEST_F(QuicDispatcherTest, StatelessVersionNegotiation) {
static_cast<QuicTransportVersion>(QuicTransportVersionMin() - 1);
ParsedQuicVersion parsed_version(PROTOCOL_QUIC_CRYPTO, version);
ProcessPacket(client_address, 1, true, parsed_version, SerializeCHLO(),
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1);
+ PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER, 1);
}
TEST_F(QuicDispatcherTest, Shutdown) {
@@ -501,7 +502,8 @@ TEST_F(QuicDispatcherTest, TimeWaitListManager) {
// wait list manager.
EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, connection_id))
.Times(1);
- EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
+ EXPECT_CALL(*time_wait_list_manager_,
+ AddConnectionIdToTimeWait(_, _, _, _, _))
.Times(0);
ProcessPacket(client_address, connection_id, true, "data");
}
@@ -517,7 +519,8 @@ TEST_F(QuicDispatcherTest, NoVersionPacketToTimeWaitListManager) {
.Times(0);
EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, connection_id))
.Times(1);
- EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
+ EXPECT_CALL(*time_wait_list_manager_,
+ AddConnectionIdToTimeWait(_, _, _, _, _))
.Times(1);
ProcessPacket(client_address, connection_id, false, SerializeCHLO());
}
@@ -533,7 +536,8 @@ TEST_F(QuicDispatcherTest, ProcessPacketWithZeroPort) {
CreateQuicSession(1, client_address, QuicStringPiece("hq")))
.Times(0);
EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _)).Times(0);
- EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
+ EXPECT_CALL(*time_wait_list_manager_,
+ AddConnectionIdToTimeWait(_, _, _, _, _))
.Times(0);
ProcessPacket(client_address, 1, true, SerializeCHLO());
}
@@ -560,7 +564,7 @@ TEST_F(QuicDispatcherTest, OKSeqNoPacketProcessed) {
EXPECT_CALL(*dispatcher_,
ShouldCreateOrBufferPacketForConnection(connection_id));
ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
+ PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
QuicDispatcher::kMaxReasonableInitialPacketNumber);
EXPECT_EQ(client_address, dispatcher_->current_peer_address());
EXPECT_EQ(server_address_, dispatcher_->current_self_address());
@@ -578,17 +582,18 @@ TEST_F(QuicDispatcherTest, TooBigSeqNoPacketToTimeWaitListManager) {
.Times(0);
EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, 1)).Times(1);
EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, 2)).Times(1);
- EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
+ EXPECT_CALL(*time_wait_list_manager_,
+ AddConnectionIdToTimeWait(_, _, _, _, _))
.Times(2);
// A packet whose packet number is one to large to be allowed to start a
// connection.
ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
+ PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
QuicDispatcher::kMaxReasonableInitialPacketNumber + 1);
connection_id = 2;
SetQuicRestartFlag(quic_enable_accept_random_ipn, true);
ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
+ PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
kMaxRandomInitialPacketNumber +
QuicDispatcher::kMaxReasonableInitialPacketNumber + 1);
}
@@ -613,7 +618,7 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
PROTOCOL_QUIC_CRYPTO,
static_cast<QuicTransportVersion>(QuicTransportVersionMin() - 1));
ProcessPacket(client_address, connection_id, true, version, SerializeCHLO(),
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, 1);
+ PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER, 1);
++connection_id;
EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
QuicStringPiece("hq")))
@@ -633,7 +638,7 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO,
QuicVersionMin().transport_version),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
+ PACKET_4BYTE_PACKET_NUMBER, 1);
++connection_id;
EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address,
QuicStringPiece("hq")))
@@ -651,7 +656,7 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
ShouldCreateOrBufferPacketForConnection(connection_id));
ProcessPacket(client_address, connection_id, true, QuicVersionMax(),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
+ PACKET_4BYTE_PACKET_NUMBER, 1);
// Turn off version 43.
SetQuicReloadableFlag(quic_enable_version_43, false);
@@ -662,7 +667,7 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
ProcessPacket(client_address, connection_id, true,
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
+ PACKET_4BYTE_PACKET_NUMBER, 1);
// Turn on version 43.
SetQuicReloadableFlag(quic_enable_version_43, true);
@@ -684,7 +689,7 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
ProcessPacket(client_address, connection_id, true,
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
+ PACKET_4BYTE_PACKET_NUMBER, 1);
// Turn off version 42.
SetQuicReloadableFlag(quic_enable_version_42_2, false);
@@ -695,7 +700,7 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
ProcessPacket(client_address, connection_id, true,
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_42),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
+ PACKET_4BYTE_PACKET_NUMBER, 1);
// Turn on version 42.
SetQuicReloadableFlag(quic_enable_version_42_2, true);
@@ -717,7 +722,7 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
ProcessPacket(client_address, connection_id, true,
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_42),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
+ PACKET_4BYTE_PACKET_NUMBER, 1);
// Turn off version 41.
SetQuicReloadableFlag(quic_disable_version_41, true);
@@ -728,7 +733,7 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
ProcessPacket(client_address, connection_id, true,
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_41),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
+ PACKET_4BYTE_PACKET_NUMBER, 1);
// Turn on version 41.
SetQuicReloadableFlag(quic_disable_version_41, false);
@@ -750,7 +755,7 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
ProcessPacket(client_address, connection_id, true,
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_41),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
+ PACKET_4BYTE_PACKET_NUMBER, 1);
// Turn off version 38.
SetQuicReloadableFlag(quic_disable_version_38, true);
@@ -761,7 +766,7 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
ProcessPacket(client_address, connection_id, true,
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_38),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
+ PACKET_4BYTE_PACKET_NUMBER, 1);
// Turn on version 38.
SetQuicReloadableFlag(quic_disable_version_38, false);
@@ -783,7 +788,7 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
ProcessPacket(client_address, connection_id, true,
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_38),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
+ PACKET_4BYTE_PACKET_NUMBER, 1);
// Turn off version 37.
SetQuicReloadableFlag(quic_disable_version_37, true);
@@ -794,7 +799,7 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
ProcessPacket(client_address, connection_id, true,
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_37),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
+ PACKET_4BYTE_PACKET_NUMBER, 1);
// Turn on version 37.
SetQuicReloadableFlag(quic_disable_version_37, false);
@@ -816,7 +821,7 @@ TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
ProcessPacket(client_address, connection_id, true,
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_37),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
+ PACKET_4BYTE_PACKET_NUMBER, 1);
}
// Enables mocking of the handshake-confirmation for stateless rejects.
@@ -1041,10 +1046,10 @@ TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) {
ShouldCreateOrBufferPacketForConnection(connection_id))
.Times(1);
}
- ProcessPacket(client_address, connection_id, true,
- client_hello.GetSerialized(Perspective::IS_CLIENT)
- .AsStringPiece()
- .as_string());
+ ProcessPacket(
+ client_address, connection_id, true,
+ string(
+ client_hello.GetSerialized(Perspective::IS_CLIENT).AsStringPiece()));
if (GetParam().enable_stateless_rejects_via_flag) {
EXPECT_EQ(true,
@@ -1094,10 +1099,10 @@ TEST_P(QuicDispatcherStatelessRejectTest, BufferNonChlo) {
ValidatePacket(connection_id, packet);
})))
.RetiresOnSaturation();
- ProcessPacket(client_address, connection_id, true,
- client_hello.GetSerialized(Perspective::IS_CLIENT)
- .AsStringPiece()
- .as_string());
+ ProcessPacket(
+ client_address, connection_id, true,
+ string(
+ client_hello.GetSerialized(Perspective::IS_CLIENT).AsStringPiece()));
EXPECT_FALSE(
time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
}
@@ -1118,10 +1123,11 @@ TEST_F(QuicDispatcherTestStrayPacketConnectionId,
.Times(0);
EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, connection_id))
.Times(0);
- EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _, _))
+ EXPECT_CALL(*time_wait_list_manager_,
+ AddConnectionIdToTimeWait(_, _, _, _, _))
.Times(0);
ProcessPacket(client_address, connection_id, true, "data",
- PACKET_0BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER);
+ PACKET_0BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER);
}
class BlockingWriter : public QuicPacketWriterWrapper {
@@ -1404,9 +1410,8 @@ class BufferedPacketStoreTest
}
QuicString SerializeFullCHLO() {
- return full_chlo_.GetSerialized(Perspective::IS_CLIENT)
- .AsStringPiece()
- .as_string();
+ return string(
+ full_chlo_.GetSerialized(Perspective::IS_CLIENT).AsStringPiece());
}
protected:
@@ -1434,7 +1439,7 @@ TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) {
for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) {
ProcessPacket(client_address, conn_id, true,
QuicStrCat("data packet ", i + 1), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, /*packet_number=*/i + 1);
+ PACKET_4BYTE_PACKET_NUMBER, /*packet_number=*/i + 1);
}
EXPECT_EQ(0u, dispatcher_->session_map().size())
<< "No session should be created before CHLO arrives.";
@@ -1474,7 +1479,7 @@ TEST_P(BufferedPacketStoreTest,
EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id));
ProcessPacket(client_address, conn_id, true,
QuicStrCat("data packet on connection ", i),
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
+ PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
/*packet_number=*/2);
}
@@ -1537,7 +1542,7 @@ TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) {
server_address_ = QuicSocketAddress(QuicIpAddress::Any4(), 5);
QuicConnectionId conn_id = 1;
ProcessPacket(client_address, conn_id, true, QuicStrCat("data packet ", 2),
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
+ PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
/*packet_number=*/2);
// When CHLO arrives, a new session should be created, and all packets
@@ -1573,7 +1578,7 @@ TEST_P(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) {
server_address_ = QuicSocketAddress(QuicIpAddress::Any4(), 5);
QuicConnectionId conn_id = 1;
ProcessPacket(client_address, conn_id, true, QuicStrCat("data packet ", 2),
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
+ PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
/*packet_number=*/2);
mock_helper_.AdvanceTime(
@@ -1761,7 +1766,7 @@ TEST_P(BufferedPacketStoreTest, ReceiveCHLOForBufferedConnection) {
QuicConnectionId conn_id = 1;
ProcessPacket(client_addr_, conn_id, true, "data packet",
- PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
+ PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
/*packet_number=*/1);
// Fill packet buffer to full with CHLOs on other connections. Need to feed
// extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create
@@ -1801,6 +1806,7 @@ class AsyncGetProofTest : public QuicDispatcherTest {
: QuicDispatcherTest(
std::unique_ptr<FakeProofSource>(new FakeProofSource())),
client_addr_(QuicIpAddress::Loopback4(), 1234),
+ client_addr_2_(QuicIpAddress::Loopback4(), 1357),
crypto_config_peer_(&crypto_config_),
signed_config_(new QuicSignedServerConfig) {
SetQuicReloadableFlag(enable_quic_stateless_reject_support, true);
@@ -1822,6 +1828,11 @@ class AsyncGetProofTest : public QuicDispatcherTest {
signed_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
&full_chlo_);
+ crypto_test_utils::GenerateFullCHLO(
+ chlo_, &crypto_config_, server_addr_, client_addr_2_, version, clock_,
+ signed_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()),
+ &full_chlo_2_);
+
GetFakeProofSource()->Activate();
}
@@ -1830,26 +1841,29 @@ class AsyncGetProofTest : public QuicDispatcherTest {
}
QuicString SerializeFullCHLO() {
- return full_chlo_.GetSerialized(Perspective::IS_CLIENT)
- .AsStringPiece()
- .as_string();
+ return QuicString(
+ full_chlo_.GetSerialized(Perspective::IS_CLIENT).AsStringPiece());
+ }
+
+ QuicString SerializeFullCHLOForClient2() {
+ return QuicString(
+ full_chlo_2_.GetSerialized(Perspective::IS_CLIENT).AsStringPiece());
}
QuicString SerializeCHLO() {
- return chlo_.GetSerialized(Perspective::IS_CLIENT)
- .AsStringPiece()
- .as_string();
+ return string(chlo_.GetSerialized(Perspective::IS_CLIENT).AsStringPiece());
}
// Sets up a session, and crypto stream based on the test parameters.
- QuicServerSessionBase* GetSession(QuicConnectionId connection_id) {
+ QuicServerSessionBase* GetSession(QuicConnectionId connection_id,
+ QuicSocketAddress client_address) {
auto it = sessions_.find(connection_id);
if (it != sessions_.end()) {
return it->second.session;
}
TestQuicSpdyServerSession* session;
- CreateSession(dispatcher_.get(), config_, connection_id, client_addr_,
+ CreateSession(dispatcher_.get(), config_, connection_id, client_address,
&mock_helper_, &mock_alarm_factory_, &crypto_config_,
QuicDispatcherPeer::GetCache(dispatcher_.get()), &session);
@@ -1870,6 +1884,7 @@ class AsyncGetProofTest : public QuicDispatcherTest {
protected:
const QuicSocketAddress client_addr_;
+ const QuicSocketAddress client_addr_2_;
private:
QuicCryptoServerConfigPeer crypto_config_peer_;
@@ -1877,7 +1892,8 @@ class AsyncGetProofTest : public QuicDispatcherTest {
QuicReferenceCountedPointer<QuicSignedServerConfig> signed_config_;
const QuicClock* clock_;
CryptoHandshakeMessage chlo_;
- CryptoHandshakeMessage full_chlo_;
+ CryptoHandshakeMessage full_chlo_; // CHLO for client_addr_
+ CryptoHandshakeMessage full_chlo_2_; // CHLO for client_addr_2_
struct SessionInfo {
TestQuicSpdyServerSession* session;
@@ -1899,9 +1915,9 @@ TEST_F(AsyncGetProofTest, BasicAccept) {
EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id));
EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_,
QuicStringPiece("HTTP/1")))
- .WillOnce(testing::Return(GetSession(conn_id)));
+ .WillOnce(testing::Return(GetSession(conn_id, client_addr_)));
EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id)->connection()),
+ GetSession(conn_id, client_addr_)->connection()),
ProcessUdpPacket(_, _, _))
.WillOnce(WithArg<2>(
Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
@@ -1910,7 +1926,7 @@ TEST_F(AsyncGetProofTest, BasicAccept) {
EXPECT_CALL(check, Call(2));
EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id)->connection()),
+ GetSession(conn_id, client_addr_)->connection()),
ProcessUdpPacket(_, _, _))
.WillOnce(WithArg<2>(
Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
@@ -1933,6 +1949,83 @@ TEST_F(AsyncGetProofTest, BasicAccept) {
ProcessPacket(client_addr_, conn_id, true, "My name is Data");
}
+TEST_F(AsyncGetProofTest, RestorePacketContext) {
+ QuicConnectionId conn_id_1 = 1;
+ QuicConnectionId conn_id_2 = 2;
+
+ testing::MockFunction<void(int check_point)> check;
+ {
+ InSequence s;
+ EXPECT_CALL(check, Call(1));
+ EXPECT_CALL(*dispatcher_,
+ ShouldCreateOrBufferPacketForConnection(conn_id_1));
+
+ EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_1, client_addr_,
+ QuicStringPiece("HTTP/1")))
+ .WillOnce(testing::Return(GetSession(conn_id_1, client_addr_)));
+ EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
+ GetSession(conn_id_1, client_addr_)->connection()),
+ ProcessUdpPacket(_, _, _))
+ .WillRepeatedly(WithArg<2>(
+ Invoke([this, conn_id_1](const QuicEncryptedPacket& packet) {
+ ValidatePacket(conn_id_1, packet);
+ })));
+
+ EXPECT_CALL(check, Call(2));
+
+ EXPECT_CALL(*dispatcher_,
+ ShouldCreateOrBufferPacketForConnection(conn_id_2));
+ EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_2_,
+ QuicStringPiece("HTTP/1")))
+ .WillOnce(testing::Return(GetSession(conn_id_2, client_addr_2_)));
+ EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
+ GetSession(conn_id_2, client_addr_2_)->connection()),
+ ProcessUdpPacket(_, _, _))
+ .WillOnce(WithArg<2>(
+ Invoke([this, conn_id_2](const QuicEncryptedPacket& packet) {
+ ValidatePacket(conn_id_2, packet);
+ })));
+ }
+
+ // Send a CHLO that the StatelessRejector will accept.
+ ProcessPacket(client_addr_, conn_id_1, true, SerializeFullCHLO());
+ ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
+
+ // Send another CHLO that the StatelessRejector will accept.
+ ProcessPacket(client_addr_2_, conn_id_2, true, SerializeFullCHLOForClient2());
+ ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
+
+ // Complete the first ProofSource::GetProof call and verify that a session is
+ // created.
+ check.Call(1);
+
+ EXPECT_EQ(client_addr_2_, dispatcher_->current_client_address());
+ EXPECT_EQ(client_addr_2_, dispatcher_->current_peer_address());
+
+ // Runs the async proof callback for conn_id_1 from client_addr_.
+ GetFakeProofSource()->InvokePendingCallback(0);
+
+ EXPECT_EQ(client_addr_, dispatcher_->current_client_address());
+ EXPECT_EQ(client_addr_, dispatcher_->current_peer_address());
+
+ ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 1);
+
+ // Complete the second ProofSource::GetProof call and verify that a session is
+ // created.
+ check.Call(2);
+
+ EXPECT_EQ(client_addr_, dispatcher_->current_client_address());
+ EXPECT_EQ(client_addr_, dispatcher_->current_peer_address());
+
+ // Runs the async proof callback for conn_id_2 from client_addr_2_.
+ GetFakeProofSource()->InvokePendingCallback(0);
+
+ EXPECT_EQ(client_addr_2_, dispatcher_->current_client_address());
+ EXPECT_EQ(client_addr_2_, dispatcher_->current_peer_address());
+
+ ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 0);
+}
+
// Test a simple situation of connections which the StatelessRejector will
// reject.
TEST_F(AsyncGetProofTest, BasicReject) {
@@ -1945,7 +2038,7 @@ TEST_F(AsyncGetProofTest, BasicReject) {
InSequence s;
EXPECT_CALL(check, Call(1));
EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(conn_id, _, true, _));
+ AddConnectionIdToTimeWait(conn_id, _, _, true, _));
EXPECT_CALL(*time_wait_list_manager_,
ProcessPacket(_, client_addr_, conn_id));
@@ -1988,9 +2081,9 @@ TEST_F(AsyncGetProofTest, MultipleAccept) {
ShouldCreateOrBufferPacketForConnection(conn_id_2));
EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_,
QuicStringPiece("HTTP/1")))
- .WillOnce(testing::Return(GetSession(conn_id_2)));
+ .WillOnce(testing::Return(GetSession(conn_id_2, client_addr_)));
EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id_2)->connection()),
+ GetSession(conn_id_2, client_addr_)->connection()),
ProcessUdpPacket(_, _, _))
.WillOnce(WithArg<2>(
Invoke([this, conn_id_2](const QuicEncryptedPacket& packet) {
@@ -1999,7 +2092,7 @@ TEST_F(AsyncGetProofTest, MultipleAccept) {
EXPECT_CALL(check, Call(2));
EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id_2)->connection()),
+ GetSession(conn_id_2, client_addr_)->connection()),
ProcessUdpPacket(_, _, _))
.WillOnce(WithArg<2>(
Invoke([this, conn_id_2](const QuicEncryptedPacket& packet) {
@@ -2013,9 +2106,9 @@ TEST_F(AsyncGetProofTest, MultipleAccept) {
EXPECT_CALL(check, Call(4));
EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_1, client_addr_,
QuicStringPiece("HTTP/1")))
- .WillOnce(testing::Return(GetSession(conn_id_1)));
+ .WillOnce(testing::Return(GetSession(conn_id_1, client_addr_)));
EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id_1)->connection()),
+ GetSession(conn_id_1, client_addr_)->connection()),
ProcessUdpPacket(_, _, _))
.WillRepeatedly(WithArg<2>(
Invoke([this, conn_id_1](const QuicEncryptedPacket& packet) {
@@ -2073,7 +2166,7 @@ TEST_F(AsyncGetProofTest, MultipleReject) {
EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id_2, client_addr_, _))
.Times(0);
EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(conn_id_2, _, true, _));
+ AddConnectionIdToTimeWait(conn_id_2, _, _, true, _));
EXPECT_CALL(*time_wait_list_manager_,
ProcessPacket(_, client_addr_, conn_id_2));
@@ -2087,7 +2180,7 @@ TEST_F(AsyncGetProofTest, MultipleReject) {
EXPECT_CALL(check, Call(4));
EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(conn_id_1, _, true, _));
+ AddConnectionIdToTimeWait(conn_id_1, _, _, true, _));
EXPECT_CALL(*time_wait_list_manager_,
ProcessPacket(_, client_addr_, conn_id_1));
}
@@ -2147,7 +2240,7 @@ TEST_F(AsyncGetProofTest, MultipleIdenticalReject) {
CreateQuicSession(conn_id_1, client_addr_, QuicStringPiece()))
.Times(0);
EXPECT_CALL(*time_wait_list_manager_,
- AddConnectionIdToTimeWait(conn_id_1, _, true, _));
+ AddConnectionIdToTimeWait(conn_id_1, _, _, true, _));
EXPECT_CALL(*time_wait_list_manager_,
ProcessPacket(_, client_addr_, conn_id_1));
}
@@ -2245,9 +2338,9 @@ TEST_F(AsyncGetProofTest, TimeWaitTimeout) {
EXPECT_CALL(*dispatcher_, ShouldCreateOrBufferPacketForConnection(conn_id));
EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_addr_,
QuicStringPiece("HTTP/1")))
- .WillOnce(testing::Return(GetSession(conn_id)));
+ .WillOnce(testing::Return(GetSession(conn_id, client_addr_)));
EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(
- GetSession(conn_id)->connection()),
+ GetSession(conn_id, client_addr_)->connection()),
ProcessUdpPacket(_, _, _))
.WillOnce(WithArg<2>(
Invoke([this, conn_id](const QuicEncryptedPacket& packet) {
@@ -2308,13 +2401,13 @@ TEST_F(AsyncGetProofTest, DispatcherFailedToPickUpVersionForAsyncProof) {
ProcessPacket(client_addr_, 1, true,
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_39),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
+ PACKET_4BYTE_PACKET_NUMBER, 1);
// Send another CHLO with v35. Dispatcher framer's version is set to v35.
ProcessPacket(client_addr_, 2, true,
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_35),
SerializeCHLO(), PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, 1);
+ PACKET_4BYTE_PACKET_NUMBER, 1);
ASSERT_EQ(GetFakeProofSource()->NumPendingCallbacks(), 2);
// Complete the ProofSource::GetProof call for v39. This would cause the
diff --git a/chromium/net/tools/quic/quic_http_response_cache.cc b/chromium/net/tools/quic/quic_http_response_cache.cc
index c960fc4f02f..39ae552c513 100644
--- a/chromium/net/tools/quic/quic_http_response_cache.cc
+++ b/chromium/net/tools/quic/quic_http_response_cache.cc
@@ -277,7 +277,7 @@ void QuicHttpResponseCache::InitializeFromDirectory(
}
push_resources.push_back(ServerPushInfo(url, response->headers().Clone(),
kV3LowestPriority,
- response->body().as_string()));
+ (string(response->body()))));
}
MaybeAddServerPushResources(resource_file->host(), resource_file->path(),
push_resources);
@@ -330,11 +330,11 @@ void QuicHttpResponseCache::AddResponseImpl(QuicStringPiece host,
string QuicHttpResponseCache::GetKey(QuicStringPiece host,
QuicStringPiece path) const {
- string host_string = host.as_string();
+ string host_string = string(host);
size_t port = host_string.find(':');
if (port != string::npos)
host_string = string(host_string.c_str(), port);
- return host_string + path.as_string();
+ return host_string + string(path);
}
void QuicHttpResponseCache::MaybeAddServerPushResources(
@@ -359,7 +359,7 @@ void QuicHttpResponseCache::MaybeAddServerPushResources(
}
string host = push_resource.request_url.host();
if (host.empty()) {
- host = request_host.as_string();
+ host = string(request_host);
}
string path = push_resource.request_url.path();
bool found_existing_response = false;
diff --git a/chromium/net/tools/quic/quic_packet_printer_bin.cc b/chromium/net/tools/quic/quic_packet_printer_bin.cc
index 74ae2f0d83e..59750bbfaa7 100644
--- a/chromium/net/tools/quic/quic_packet_printer_bin.cc
+++ b/chromium/net/tools/quic/quic_packet_printer_bin.cc
@@ -154,6 +154,14 @@ class QuicPacketPrinter : public QuicFramerVisitorInterface {
return true;
}
void OnPacketComplete() override { std::cerr << "OnPacketComplete\n"; }
+ bool IsValidStatelessResetToken(uint128 token) const override {
+ std::cerr << "IsValidStatelessResetToken\n";
+ return false;
+ }
+ void OnAuthenticatedIetfStatelessResetPacket(
+ const QuicIetfStatelessResetPacket& packet) override {
+ std::cerr << "OnAuthenticatedIetfStatelessResetPacket\n";
+ }
private:
QuicFramer* framer_; // Unowned.
diff --git a/chromium/net/tools/quic/quic_server_bin.cc b/chromium/net/tools/quic/quic_server_bin.cc
index 2bb71ba21f9..c3d2291b9cb 100644
--- a/chromium/net/tools/quic/quic_server_bin.cc
+++ b/chromium/net/tools/quic/quic_server_bin.cc
@@ -33,13 +33,13 @@ std::unique_ptr<net::ProofSource> CreateProofSource(
}
int main(int argc, char* argv[]) {
- base::TaskScheduler::CreateAndStartWithDefaultParams("quic_server");
base::AtExitManager exit_manager;
- base::MessageLoopForIO message_loop;
-
base::CommandLine::Init(argc, argv);
base::CommandLine* line = base::CommandLine::ForCurrentProcess();
+ base::MessageLoopForIO message_loop;
+ base::TaskScheduler::CreateAndStartWithDefaultParams("quic_server");
+
logging::LoggingSettings settings;
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
CHECK(logging::InitLogging(settings));
diff --git a/chromium/net/tools/quic/quic_simple_client_bin.cc b/chromium/net/tools/quic/quic_simple_client_bin.cc
index af5e63e2616..f14f2aacf34 100644
--- a/chromium/net/tools/quic/quic_simple_client_bin.cc
+++ b/chromium/net/tools/quic/quic_simple_client_bin.cc
@@ -136,10 +136,10 @@ class FakeProofVerifier : public ProofVerifier {
};
int main(int argc, char* argv[]) {
- base::TaskScheduler::CreateAndStartWithDefaultParams("quic_client");
base::CommandLine::Init(argc, argv);
base::CommandLine* line = base::CommandLine::ForCurrentProcess();
const base::CommandLine::StringVector& urls = line->GetArgs();
+ base::TaskScheduler::CreateAndStartWithDefaultParams("quic_client");
logging::LoggingSettings settings;
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
diff --git a/chromium/net/tools/quic/quic_simple_server_session.cc b/chromium/net/tools/quic/quic_simple_server_session.cc
index e417746aa1a..bc9ae358280 100644
--- a/chromium/net/tools/quic/quic_simple_server_session.cc
+++ b/chromium/net/tools/quic/quic_simple_server_session.cc
@@ -141,13 +141,9 @@ void QuicSimpleServerSession::HandleRstOnValidNonexistentStream(
size_t index = (frame.stream_id - next_outgoing_stream_id()) / 2;
DCHECK(index <= promised_streams_.size());
promised_streams_[index].is_cancelled = true;
- if (use_control_frame_manager()) {
- control_frame_manager().WriteOrBufferRstStream(
- frame.stream_id, QUIC_RST_ACKNOWLEDGEMENT, 0);
- connection()->OnStreamReset(frame.stream_id, QUIC_RST_ACKNOWLEDGEMENT);
- } else {
- connection()->SendRstStream(frame.stream_id, QUIC_RST_ACKNOWLEDGEMENT, 0);
- }
+ control_frame_manager().WriteOrBufferRstStream(frame.stream_id,
+ QUIC_RST_ACKNOWLEDGEMENT, 0);
+ connection()->OnStreamReset(frame.stream_id, QUIC_RST_ACKNOWLEDGEMENT);
}
}
diff --git a/chromium/net/tools/quic/quic_simple_server_session_test.cc b/chromium/net/tools/quic/quic_simple_server_session_test.cc
index 6800e761600..124ff389a2b 100644
--- a/chromium/net/tools/quic/quic_simple_server_session_test.cc
+++ b/chromium/net/tools/quic/quic_simple_server_session_test.cc
@@ -254,14 +254,9 @@ TEST_P(QuicSimpleServerSessionTest, CloseStreamDueToReset) {
QuicRstStreamFrame rst1(kInvalidControlFrameId, GetNthClientInitiatedId(0),
QUIC_ERROR_PROCESSING_STREAM, 0);
EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0),
- QUIC_RST_ACKNOWLEDGEMENT));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(GetNthClientInitiatedId(0),
- QUIC_RST_ACKNOWLEDGEMENT, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0),
+ QUIC_RST_ACKNOWLEDGEMENT));
visitor_->OnRstStream(rst1);
EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
@@ -278,14 +273,9 @@ TEST_P(QuicSimpleServerSessionTest, NeverOpenStreamDueToReset) {
QuicRstStreamFrame rst1(kInvalidControlFrameId, GetNthClientInitiatedId(0),
QUIC_ERROR_PROCESSING_STREAM, 0);
EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0),
- QUIC_RST_ACKNOWLEDGEMENT));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(GetNthClientInitiatedId(0),
- QUIC_RST_ACKNOWLEDGEMENT, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0),
+ QUIC_RST_ACKNOWLEDGEMENT));
visitor_->OnRstStream(rst1);
EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
@@ -313,14 +303,9 @@ TEST_P(QuicSimpleServerSessionTest, AcceptClosedStream) {
QuicRstStreamFrame rst(kInvalidControlFrameId, GetNthClientInitiatedId(0),
QUIC_ERROR_PROCESSING_STREAM, 0);
EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0),
- QUIC_RST_ACKNOWLEDGEMENT));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(GetNthClientInitiatedId(0),
- QUIC_RST_ACKNOWLEDGEMENT, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(GetNthClientInitiatedId(0),
+ QUIC_RST_ACKNOWLEDGEMENT));
visitor_->OnRstStream(rst);
// If we were tracking, we'd probably want to reject this because it's data
@@ -399,12 +384,22 @@ TEST_P(QuicSimpleServerSessionTest, CreateOutgoingDynamicStreamUptoLimit) {
EXPECT_EQ(1u, session_->GetNumOpenIncomingStreams());
EXPECT_EQ(0u, session_->GetNumOpenOutgoingStreams());
+ if (GetQuicReloadableFlag(quic_register_streams_early2) &&
+ GetQuicReloadableFlag(quic_register_static_streams)) {
+ session_->UnregisterStreamPriority(kHeadersStreamId, /*is_static=*/true);
+ }
// Assume encryption already established.
+ QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), nullptr);
MockQuicCryptoServerStream* crypto_stream =
new MockQuicCryptoServerStream(&crypto_config_, &compressed_certs_cache_,
session_.get(), &stream_helper_);
crypto_stream->set_encryption_established(true);
QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream);
+ if (GetQuicReloadableFlag(quic_register_streams_early2) &&
+ GetQuicReloadableFlag(quic_register_static_streams)) {
+ session_->RegisterStreamPriority(kHeadersStreamId, /*is_static=*/true,
+ QuicStream::kDefaultPriority);
+ }
// Create push streams till reaching the upper limit of allowed open streams.
for (size_t i = 0; i < kMaxStreamsForTest; ++i) {
@@ -487,6 +482,11 @@ class QuicSimpleServerSessionServerPushTest
visitor_ = QuicConnectionPeer::GetVisitor(connection_);
+ if (GetQuicReloadableFlag(quic_register_streams_early2) &&
+ GetQuicReloadableFlag(quic_register_static_streams)) {
+ session_->UnregisterStreamPriority(kHeadersStreamId, /*is_static=*/true);
+ }
+ QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), nullptr);
// Assume encryption already established.
MockQuicCryptoServerStream* crypto_stream = new MockQuicCryptoServerStream(
&crypto_config_, &compressed_certs_cache_, session_.get(),
@@ -494,6 +494,11 @@ class QuicSimpleServerSessionServerPushTest
crypto_stream->set_encryption_established(true);
QuicSimpleServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream);
+ if (GetQuicReloadableFlag(quic_register_streams_early2) &&
+ GetQuicReloadableFlag(quic_register_static_streams)) {
+ session_->RegisterStreamPriority(kHeadersStreamId, /*is_static=*/true,
+ QuicStream::kDefaultPriority);
+ }
}
// Given |num_resources|, create this number of fake push resources and push
@@ -522,24 +527,21 @@ class QuicSimpleServerSessionServerPushTest
string body(body_size, 'a');
response_cache_.AddSimpleResponse(resource_host, path, 200, body);
push_resources.push_back(QuicHttpResponseCache::ServerPushInfo(
- resource_url, SpdyHeaderBlock(), kDefaultPriority, body));
+ resource_url, SpdyHeaderBlock(), QuicStream::kDefaultPriority, body));
// PUSH_PROMISED are sent for all the resources.
EXPECT_CALL(*session_, WritePushPromiseMock(GetNthClientInitiatedId(0),
stream_id, _));
if (i <= kMaxStreamsForTest) {
// |kMaxStreamsForTest| promised responses should be sent.
EXPECT_CALL(*session_,
- WriteHeadersMock(stream_id, _, false, kDefaultPriority, _));
+ WriteHeadersMock(stream_id, _, false,
+ QuicStream::kDefaultPriority, _));
// Since flow control window is smaller than response body, not the
// whole body will be sent.
EXPECT_CALL(*connection_, SendStreamData(stream_id, _, 0, NO_FIN))
.WillOnce(
Return(QuicConsumedData(kStreamFlowControlWindowSize, false)));
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*session_, SendBlocked(stream_id));
- } else {
- EXPECT_CALL(*connection_, SendBlocked(stream_id));
- }
+ EXPECT_CALL(*session_, SendBlocked(stream_id));
}
}
session_->PromisePushResources(request_url, push_resources,
@@ -573,15 +575,11 @@ TEST_P(QuicSimpleServerSessionServerPushTest,
// After an open stream is marked draining, a new stream is expected to be
// created and a response sent on the stream.
EXPECT_CALL(*session_, WriteHeadersMock(next_out_going_stream_id, _, false,
- kDefaultPriority, _));
+ QuicStream::kDefaultPriority, _));
EXPECT_CALL(*connection_,
SendStreamData(next_out_going_stream_id, _, 0, NO_FIN))
.WillOnce(Return(QuicConsumedData(kStreamFlowControlWindowSize, false)));
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*session_, SendBlocked(next_out_going_stream_id));
- } else {
- EXPECT_CALL(*connection_, SendBlocked(next_out_going_stream_id));
- }
+ EXPECT_CALL(*session_, SendBlocked(next_out_going_stream_id));
session_->StreamDraining(2);
// Number of open outgoing streams should still be the same, because a new
// stream is opened. And the queue should be empty.
@@ -604,16 +602,11 @@ TEST_P(QuicSimpleServerSessionServerPushTest,
QuicRstStreamFrame rst(kInvalidControlFrameId, stream_got_reset,
QUIC_STREAM_CANCELLED, 0);
EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .WillOnce(Invoke(
- this, &QuicSimpleServerSessionServerPushTest::ClearControlFrame));
- EXPECT_CALL(*connection_,
- OnStreamReset(stream_got_reset, QUIC_RST_ACKNOWLEDGEMENT));
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(stream_got_reset, QUIC_RST_ACKNOWLEDGEMENT, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_))
+ .WillOnce(Invoke(
+ this, &QuicSimpleServerSessionServerPushTest::ClearControlFrame));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(stream_got_reset, QUIC_RST_ACKNOWLEDGEMENT));
visitor_->OnRstStream(rst);
// When the first 2 streams becomes draining, the two queued up stream could
@@ -622,16 +615,12 @@ TEST_P(QuicSimpleServerSessionServerPushTest,
QuicStreamId stream_not_reset = GetNthServerInitiatedId(kMaxStreamsForTest);
InSequence s;
EXPECT_CALL(*session_, WriteHeadersMock(stream_not_reset, _, false,
- kDefaultPriority, _));
+ QuicStream::kDefaultPriority, _));
EXPECT_CALL(*connection_, SendStreamData(stream_not_reset, _, 0, NO_FIN))
.WillOnce(Return(QuicConsumedData(kStreamFlowControlWindowSize, false)));
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*session_, SendBlocked(stream_not_reset));
- } else {
- EXPECT_CALL(*connection_, SendBlocked(stream_not_reset));
- }
- EXPECT_CALL(*session_,
- WriteHeadersMock(stream_got_reset, _, false, kDefaultPriority, _))
+ EXPECT_CALL(*session_, SendBlocked(stream_not_reset));
+ EXPECT_CALL(*session_, WriteHeadersMock(stream_got_reset, _, false,
+ QuicStream::kDefaultPriority, _))
.Times(0);
session_->StreamDraining(GetNthServerInitiatedId(0));
@@ -649,24 +638,15 @@ TEST_P(QuicSimpleServerSessionServerPushTest,
// Resetting 1st open stream will close the stream and give space for extra
// stream to be opened.
QuicStreamId stream_got_reset = GetNthServerInitiatedId(0);
- if (session_->use_control_frame_manager()) {
EXPECT_CALL(*connection_, SendControlFrame(_));
EXPECT_CALL(*connection_,
OnStreamReset(stream_got_reset, QUIC_RST_ACKNOWLEDGEMENT));
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(stream_got_reset, QUIC_RST_ACKNOWLEDGEMENT, _));
- }
- EXPECT_CALL(*session_,
- WriteHeadersMock(stream_to_open, _, false, kDefaultPriority, _));
+ EXPECT_CALL(*session_, WriteHeadersMock(stream_to_open, _, false,
+ QuicStream::kDefaultPriority, _));
EXPECT_CALL(*connection_, SendStreamData(stream_to_open, _, 0, NO_FIN))
.WillOnce(Return(QuicConsumedData(kStreamFlowControlWindowSize, false)));
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*session_, SendBlocked(stream_to_open));
- } else {
- EXPECT_CALL(*connection_, SendBlocked(stream_to_open));
- }
+ EXPECT_CALL(*session_, SendBlocked(stream_to_open));
EXPECT_CALL(owner_, OnRstStreamReceived(_)).Times(1);
QuicRstStreamFrame rst(kInvalidControlFrameId, stream_got_reset,
QUIC_STREAM_CANCELLED, 0);
diff --git a/chromium/net/tools/quic/quic_simple_server_stream_test.cc b/chromium/net/tools/quic/quic_simple_server_stream_test.cc
index 1d119ac452f..5163c42f66c 100644
--- a/chromium/net/tools/quic/quic_simple_server_stream_test.cc
+++ b/chromium/net/tools/quic/quic_simple_server_stream_test.cc
@@ -26,12 +26,12 @@
#include "testing/gtest/include/gtest/gtest.h"
using std::string;
+using testing::_;
using testing::AnyNumber;
using testing::InSequence;
using testing::Invoke;
using testing::Return;
using testing::StrictMock;
-using testing::_;
namespace net {
namespace test {
@@ -423,7 +423,8 @@ TEST_P(QuicSimpleServerStreamTest, SendReponseWithPushResources) {
string request_path = "/foo";
string body = "Yummm";
QuicHttpResponseCache::ServerPushInfo push_info(
- QuicUrl(host, "/bar"), SpdyHeaderBlock(), kDefaultPriority, "Push body");
+ QuicUrl(host, "/bar"), SpdyHeaderBlock(), QuicStream::kDefaultPriority,
+ "Push body");
std::list<QuicHttpResponseCache::ServerPushInfo> push_resources;
push_resources.push_back(push_info);
response_cache_.AddSimpleResponseWithServerPushResources(
diff --git a/chromium/net/tools/quic/quic_spdy_client_base.cc b/chromium/net/tools/quic/quic_spdy_client_base.cc
index 6cad4ee3c35..b7bf7c3f053 100644
--- a/chromium/net/tools/quic/quic_spdy_client_base.cc
+++ b/chromium/net/tools/quic/quic_spdy_client_base.cc
@@ -153,7 +153,7 @@ QuicSpdyClientStream* QuicSpdyClientBase::CreateClientStream() {
auto* stream = static_cast<QuicSpdyClientStream*>(
client_session()->CreateOutgoingDynamicStream());
if (stream) {
- stream->SetPriority(kDefaultPriority);
+ stream->SetPriority(QuicStream::kDefaultPriority);
stream->set_visitor(this);
}
return stream;
diff --git a/chromium/net/tools/quic/quic_spdy_client_session_test.cc b/chromium/net/tools/quic/quic_spdy_client_session_test.cc
index afc3fec1038..b805d89e93f 100644
--- a/chromium/net/tools/quic/quic_spdy_client_session_test.cc
+++ b/chromium/net/tools/quic/quic_spdy_client_session_test.cc
@@ -177,12 +177,8 @@ TEST_P(QuicSpdyClientSessionTest, NoEncryptionAfterInitialEncryption) {
}
TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithNoFinOrRst) {
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AnyNumber());
- EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(AnyNumber());
- } else {
- EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(AnyNumber());
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AnyNumber());
+ EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(AnyNumber());
const uint32_t kServerMaxIncomingStreams = 1;
CompleteCryptoHandshake(kServerMaxIncomingStreams);
@@ -201,12 +197,8 @@ TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithNoFinOrRst) {
}
TEST_P(QuicSpdyClientSessionTest, MaxNumStreamsWithRst) {
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AnyNumber());
- EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(AnyNumber());
- } else {
- EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(AnyNumber());
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AnyNumber());
+ EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(AnyNumber());
const uint32_t kServerMaxIncomingStreams = 1;
CompleteCryptoHandshake(kServerMaxIncomingStreams);
@@ -238,12 +230,8 @@ TEST_P(QuicSpdyClientSessionTest, ResetAndTrailers) {
EXPECT_FALSE(session_->CreateOutgoingDynamicStream());
QuicStreamId stream_id = stream->id();
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
- EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
- } else {
- EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(1);
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+ EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
session_->SendRstStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY, 0);
// A new stream cannot be created as the reset stream still counts as an open
@@ -279,12 +267,8 @@ TEST_P(QuicSpdyClientSessionTest, ReceivedMalformedTrailersAfterSendingRst) {
// Send the RST, which results in the stream being closed locally (but some
// state remains while the client waits for a response from the server).
QuicStreamId stream_id = stream->id();
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
- EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
- } else {
- EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(1);
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+ EXPECT_CALL(*connection_, OnStreamReset(_, _)).Times(1);
session_->SendRstStream(stream_id, QUIC_STREAM_PEER_GOING_AWAY, 0);
// The stream receives trailers with final byte offset, but the header value
@@ -319,7 +303,7 @@ TEST_P(QuicSpdyClientSessionTest, InvalidPacketReceived) {
QuicSocketAddress client_address(TestPeerIPAddress(), kTestPort);
EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
- .WillRepeatedly(Invoke(implicit_cast<MockQuicConnection*>(connection_),
+ .WillRepeatedly(Invoke(static_cast<MockQuicConnection*>(connection_),
&MockQuicConnection::ReallyProcessUdpPacket));
EXPECT_CALL(*connection_, OnCanWrite()).Times(AnyNumber());
EXPECT_CALL(*connection_, OnError(_)).Times(1);
@@ -341,7 +325,7 @@ TEST_P(QuicSpdyClientSessionTest, InvalidPacketReceived) {
QuicConnectionId connection_id = session_->connection()->connection_id();
std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
connection_id, false, false, 100, "data", PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, nullptr, Perspective::IS_SERVER));
+ PACKET_4BYTE_PACKET_NUMBER, nullptr, Perspective::IS_SERVER));
std::unique_ptr<QuicReceivedPacket> received(
ConstructReceivedPacket(*packet, QuicTime::Zero()));
// Change the last byte of the encrypted data.
@@ -357,7 +341,7 @@ TEST_P(QuicSpdyClientSessionTest, InvalidFramedPacketReceived) {
QuicSocketAddress client_address(TestPeerIPAddress(), kTestPort);
EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
- .WillRepeatedly(Invoke(implicit_cast<MockQuicConnection*>(connection_),
+ .WillRepeatedly(Invoke(static_cast<MockQuicConnection*>(connection_),
&MockQuicConnection::ReallyProcessUdpPacket));
EXPECT_CALL(*connection_, OnError(_)).Times(1);
@@ -366,7 +350,7 @@ TEST_P(QuicSpdyClientSessionTest, InvalidFramedPacketReceived) {
ParsedQuicVersionVector versions = {GetParam()};
std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
connection_id, false, false, 100, "data", PACKET_8BYTE_CONNECTION_ID,
- PACKET_6BYTE_PACKET_NUMBER, &versions, Perspective::IS_SERVER));
+ PACKET_4BYTE_PACKET_NUMBER, &versions, Perspective::IS_SERVER));
std::unique_ptr<QuicReceivedPacket> received(
ConstructReceivedPacket(*packet, QuicTime::Zero()));
EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
@@ -391,14 +375,9 @@ TEST_P(QuicSpdyClientSessionTest, PushPromiseOnPromiseHeadersAlreadyClosed) {
session_->CreateOutgoingDynamicStream();
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(associated_stream_id_, QUIC_REFUSED_STREAM));
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(associated_stream_id_, QUIC_REFUSED_STREAM, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(associated_stream_id_, QUIC_REFUSED_STREAM));
session_->ResetPromised(associated_stream_id_, QUIC_REFUSED_STREAM);
session_->OnPromiseHeaderList(associated_stream_id_, promised_stream_id_, 0,
@@ -445,14 +424,9 @@ TEST_P(QuicSpdyClientSessionTest, PushPromiseAlreadyClosed) {
session_->CreateOutgoingDynamicStream();
session_->GetOrCreateStream(promised_stream_id_);
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(promised_stream_id_, QUIC_REFUSED_STREAM, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
SpdyHeaderBlock promise_headers;
@@ -477,14 +451,9 @@ TEST_P(QuicSpdyClientSessionTest, PushPromiseDuplicateUrl) {
EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
promised_stream_id_ += 2;
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_DUPLICATE_PROMISE_URL));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(promised_stream_id_,
- QUIC_DUPLICATE_PROMISE_URL, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(promised_stream_id_, QUIC_DUPLICATE_PROMISE_URL));
EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
promised_stream_id_, push_promise_));
@@ -513,12 +482,8 @@ TEST_P(QuicSpdyClientSessionTest, ReceivingPromiseEnhanceYourCalm) {
push_promise_[":path"] = QuicStringPrintf("/bar%d", i);
QuicStreamId id = promised_stream_id_ + i * 2;
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(id, QUIC_REFUSED_STREAM));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(id, QUIC_REFUSED_STREAM, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_, OnStreamReset(id, QUIC_REFUSED_STREAM));
EXPECT_FALSE(
session_->HandlePromised(associated_stream_id_, id, push_promise_));
@@ -533,14 +498,9 @@ TEST_P(QuicSpdyClientSessionTest, IsClosedTrueAfterResetPromisedAlreadyOpen) {
CompleteCryptoHandshake();
session_->GetOrCreateStream(promised_stream_id_);
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(promised_stream_id_, QUIC_REFUSED_STREAM, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
EXPECT_TRUE(session_->IsClosedStream(promised_stream_id_));
}
@@ -549,14 +509,9 @@ TEST_P(QuicSpdyClientSessionTest, IsClosedTrueAfterResetPromisedNonexistant) {
// Initialize crypto before the client session will create a stream.
CompleteCryptoHandshake();
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(promised_stream_id_, QUIC_REFUSED_STREAM, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(promised_stream_id_, QUIC_REFUSED_STREAM));
session_->ResetPromised(promised_stream_id_, QUIC_REFUSED_STREAM);
EXPECT_TRUE(session_->IsClosedStream(promised_stream_id_));
}
@@ -604,14 +559,9 @@ TEST_P(QuicSpdyClientSessionTest, ResetPromised) {
session_->GetOrCreateStream(promised_stream_id_);
EXPECT_TRUE(session_->HandlePromised(associated_stream_id_,
promised_stream_id_, push_promise_));
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(promised_stream_id_,
- QUIC_STREAM_PEER_GOING_AWAY));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(promised_stream_id_,
- QUIC_STREAM_PEER_GOING_AWAY, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY));
session_->SendRstStream(promised_stream_id_, QUIC_STREAM_PEER_GOING_AWAY, 0);
QuicClientPromisedInfo* promised =
session_->GetPromisedById(promised_stream_id_);
@@ -626,14 +576,9 @@ TEST_P(QuicSpdyClientSessionTest, PushPromiseInvalidMethod) {
session_->CreateOutgoingDynamicStream();
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_, OnStreamReset(promised_stream_id_,
- QUIC_INVALID_PROMISE_METHOD));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(promised_stream_id_,
- QUIC_INVALID_PROMISE_METHOD, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(promised_stream_id_, QUIC_INVALID_PROMISE_METHOD));
push_promise_[":method"] = "POST";
EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
@@ -649,14 +594,9 @@ TEST_P(QuicSpdyClientSessionTest, PushPromiseInvalidHost) {
session_->CreateOutgoingDynamicStream();
- if (session_->use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(promised_stream_id_, QUIC_INVALID_PROMISE_URL));
- } else {
- EXPECT_CALL(*connection_, SendRstStream(promised_stream_id_,
- QUIC_INVALID_PROMISE_URL, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(promised_stream_id_, QUIC_INVALID_PROMISE_URL));
push_promise_[":authority"] = "";
EXPECT_FALSE(session_->HandlePromised(associated_stream_id_,
diff --git a/chromium/net/tools/quic/quic_spdy_client_stream_test.cc b/chromium/net/tools/quic/quic_spdy_client_stream_test.cc
index d7cd4c313f4..46d060c7a82 100644
--- a/chromium/net/tools/quic/quic_spdy_client_stream_test.cc
+++ b/chromium/net/tools/quic/quic_spdy_client_stream_test.cc
@@ -96,14 +96,9 @@ class QuicSpdyClientStreamTest : public QuicTest {
TEST_F(QuicSpdyClientStreamTest, TestReceivingIllegalResponseStatusCode) {
headers_[":status"] = "200 ok";
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
auto headers = AsHeaderList(headers_);
stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
headers);
@@ -156,14 +151,9 @@ TEST_F(QuicSpdyClientStreamTest, DISABLED_TestFramingExtraData) {
EXPECT_EQ("200", stream_->response_headers().find(":status")->second);
EXPECT_EQ(200, stream_->response_code());
- if (session_.use_control_frame_manager()) {
- EXPECT_CALL(*connection_, SendControlFrame(_));
- EXPECT_CALL(*connection_,
- OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
- } else {
- EXPECT_CALL(*connection_,
- SendRstStream(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD, 0));
- }
+ EXPECT_CALL(*connection_, SendControlFrame(_));
+ EXPECT_CALL(*connection_,
+ OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
stream_->OnStreamFrame(
QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, large_body));
diff --git a/chromium/net/tools/quic/quic_time_wait_list_manager.cc b/chromium/net/tools/quic/quic_time_wait_list_manager.cc
index 31279b34c39..cdc8d632072 100644
--- a/chromium/net/tools/quic/quic_time_wait_list_manager.cc
+++ b/chromium/net/tools/quic/quic_time_wait_list_manager.cc
@@ -94,6 +94,7 @@ QuicTimeWaitListManager::~QuicTimeWaitListManager() {
void QuicTimeWaitListManager::AddConnectionIdToTimeWait(
QuicConnectionId connection_id,
ParsedQuicVersion version,
+ bool ietf_quic,
bool connection_rejected_statelessly,
std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets) {
if (connection_rejected_statelessly) {
@@ -111,7 +112,8 @@ void QuicTimeWaitListManager::AddConnectionIdToTimeWait(
TrimTimeWaitListIfNeeded();
DCHECK_LT(num_connections(),
static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections));
- ConnectionIdData data(num_packets, version, clock_->ApproximateNow(),
+ ConnectionIdData data(num_packets, version, ietf_quic,
+ clock_->ApproximateNow(),
connection_rejected_statelessly);
if (termination_packets != nullptr) {
data.termination_packets.swap(*termination_packets);
@@ -180,13 +182,14 @@ void QuicTimeWaitListManager::ProcessPacket(
void QuicTimeWaitListManager::SendVersionNegotiationPacket(
QuicConnectionId connection_id,
+ bool ietf_quic,
const ParsedQuicVersionVector& supported_versions,
const QuicSocketAddress& server_address,
const QuicSocketAddress& client_address) {
- SendOrQueuePacket(
- QuicMakeUnique<QueuedPacket>(server_address, client_address,
- QuicFramer::BuildVersionNegotiationPacket(
- connection_id, supported_versions)));
+ SendOrQueuePacket(QuicMakeUnique<QueuedPacket>(
+ server_address, client_address,
+ QuicFramer::BuildVersionNegotiationPacket(connection_id, ietf_quic,
+ supported_versions)));
}
// Returns true if the number of packets received for this connection_id is a
@@ -240,7 +243,7 @@ bool QuicTimeWaitListManager::WriteToWire(QueuedPacket* queued_packet) {
DCHECK(writer_->IsWriteBlocked());
visitor_->OnWriteBlocked(this);
return writer_->IsWriteBlockedDataBuffered();
- } else if (result.status == WRITE_STATUS_ERROR) {
+ } else if (IsWriteError(result.status)) {
QUIC_LOG_FIRST_N(WARNING, 1)
<< "Received unknown error while sending reset packet to "
<< queued_packet->client_address().ToString() << ": "
@@ -307,13 +310,15 @@ void QuicTimeWaitListManager::TrimTimeWaitListIfNeeded() {
}
QuicTimeWaitListManager::ConnectionIdData::ConnectionIdData(
- int num_packets_,
- ParsedQuicVersion version_,
- QuicTime time_added_,
+ int num_packets,
+ ParsedQuicVersion version,
+ bool ietf_quic,
+ QuicTime time_added,
bool connection_rejected_statelessly)
- : num_packets(num_packets_),
- version(version_),
- time_added(time_added_),
+ : num_packets(num_packets),
+ version(version),
+ ietf_quic(ietf_quic),
+ time_added(time_added),
connection_rejected_statelessly(connection_rejected_statelessly) {}
QuicTimeWaitListManager::ConnectionIdData::ConnectionIdData(
diff --git a/chromium/net/tools/quic/quic_time_wait_list_manager.h b/chromium/net/tools/quic/quic_time_wait_list_manager.h
index 0bd53b87c90..e5ab534b860 100644
--- a/chromium/net/tools/quic/quic_time_wait_list_manager.h
+++ b/chromium/net/tools/quic/quic_time_wait_list_manager.h
@@ -69,6 +69,7 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface {
virtual void AddConnectionIdToTimeWait(
QuicConnectionId connection_id,
ParsedQuicVersion version,
+ bool ietf_quic,
bool connection_rejected_statelessly,
std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets);
@@ -111,6 +112,7 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface {
// for |supported_versions| to |client_address| from |server_address|.
virtual void SendVersionNegotiationPacket(
QuicConnectionId connection_id,
+ bool ietf_quic,
const ParsedQuicVersionVector& supported_versions,
const QuicSocketAddress& server_address,
const QuicSocketAddress& client_address);
@@ -161,9 +163,10 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface {
// received after the termination of the connection bound to the
// connection_id.
struct ConnectionIdData {
- ConnectionIdData(int num_packets_,
- ParsedQuicVersion version_,
- QuicTime time_added_,
+ ConnectionIdData(int num_packets,
+ ParsedQuicVersion version,
+ bool ietf_quic,
+ QuicTime time_added,
bool connection_rejected_statelessly);
ConnectionIdData(const ConnectionIdData& other) = delete;
@@ -173,6 +176,7 @@ class QuicTimeWaitListManager : public QuicBlockedWriterInterface {
int num_packets;
ParsedQuicVersion version;
+ bool ietf_quic;
QuicTime time_added;
// These packets may contain CONNECTION_CLOSE frames, or SREJ messages.
std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
diff --git a/chromium/net/tools/quic/quic_time_wait_list_manager_test.cc b/chromium/net/tools/quic/quic_time_wait_list_manager_test.cc
index f9c22f16c96..225471f9115 100644
--- a/chromium/net/tools/quic/quic_time_wait_list_manager_test.cc
+++ b/chromium/net/tools/quic/quic_time_wait_list_manager_test.cc
@@ -93,7 +93,7 @@ class QuicTimeWaitListManagerTest : public QuicTest {
termination_packets.push_back(std::unique_ptr<QuicEncryptedPacket>(
new QuicEncryptedPacket(nullptr, 0, false)));
time_wait_list_manager_.AddConnectionIdToTimeWait(
- connection_id, QuicVersionMax(),
+ connection_id, QuicVersionMax(), false,
/*connection_rejected_statelessly=*/true, &termination_packets);
}
@@ -103,7 +103,8 @@ class QuicTimeWaitListManagerTest : public QuicTest {
bool connection_rejected_statelessly,
std::vector<std::unique_ptr<QuicEncryptedPacket>>* packets) {
time_wait_list_manager_.AddConnectionIdToTimeWait(
- connection_id, version, connection_rejected_statelessly, packets);
+ connection_id, version, false, connection_rejected_statelessly,
+ packets);
}
bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) {
@@ -176,14 +177,15 @@ TEST_F(QuicTimeWaitListManagerTest, CheckStatelessConnectionIdInTimeWait) {
TEST_F(QuicTimeWaitListManagerTest, SendVersionNegotiationPacket) {
std::unique_ptr<QuicEncryptedPacket> packet(
- QuicFramer::BuildVersionNegotiationPacket(connection_id_,
+ QuicFramer::BuildVersionNegotiationPacket(connection_id_, false,
AllSupportedVersions()));
EXPECT_CALL(writer_, WritePacket(_, packet->length(), server_address_.host(),
client_address_, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
time_wait_list_manager_.SendVersionNegotiationPacket(
- connection_id_, AllSupportedVersions(), server_address_, client_address_);
+ connection_id_, false, AllSupportedVersions(), server_address_,
+ client_address_);
EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
}
diff --git a/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc b/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc
index 339078394cc..451d7ac9450 100644
--- a/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc
+++ b/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.cc
@@ -18,9 +18,9 @@ MockTimeWaitListManager::MockTimeWaitListManager(
: QuicTimeWaitListManager(writer, visitor, helper, alarm_factory) {
// Though AddConnectionIdToTimeWait is mocked, we want to retain its
// functionality.
- EXPECT_CALL(*this, AddConnectionIdToTimeWait(_, _, _, _))
+ EXPECT_CALL(*this, AddConnectionIdToTimeWait(_, _, _, _, _))
.Times(testing::AnyNumber());
- ON_CALL(*this, AddConnectionIdToTimeWait(_, _, _, _))
+ ON_CALL(*this, AddConnectionIdToTimeWait(_, _, _, _, _))
.WillByDefault(
Invoke(this, &MockTimeWaitListManager::
QuicTimeWaitListManager_AddConnectionIdToTimeWait));
diff --git a/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h b/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h
index 547ed7cb8ee..e893b0f9736 100644
--- a/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h
+++ b/chromium/net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h
@@ -19,9 +19,10 @@ class MockTimeWaitListManager : public QuicTimeWaitListManager {
QuicAlarmFactory* alarm_factory);
~MockTimeWaitListManager() override;
- MOCK_METHOD4(AddConnectionIdToTimeWait,
+ MOCK_METHOD5(AddConnectionIdToTimeWait,
void(QuicConnectionId connection_id,
ParsedQuicVersion version,
+ bool ietf_quic,
bool connection_rejected_statelessly,
std::vector<std::unique_ptr<QuicEncryptedPacket>>*
termination_packets));
@@ -29,10 +30,11 @@ class MockTimeWaitListManager : public QuicTimeWaitListManager {
void QuicTimeWaitListManager_AddConnectionIdToTimeWait(
QuicConnectionId connection_id,
ParsedQuicVersion version,
+ bool ietf_quic,
bool connection_rejected_statelessly,
std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets) {
QuicTimeWaitListManager::AddConnectionIdToTimeWait(
- connection_id, version, connection_rejected_statelessly,
+ connection_id, version, ietf_quic, connection_rejected_statelessly,
termination_packets);
}
@@ -41,8 +43,9 @@ class MockTimeWaitListManager : public QuicTimeWaitListManager {
const QuicSocketAddress& client_address,
QuicConnectionId connection_id));
- MOCK_METHOD4(SendVersionNegotiationPacket,
+ MOCK_METHOD5(SendVersionNegotiationPacket,
void(QuicConnectionId connection_id,
+ bool ietf_quic,
const ParsedQuicVersionVector& supported_versions,
const QuicSocketAddress& server_address,
const QuicSocketAddress& client_address));
diff --git a/chromium/net/tools/quic/test_tools/quic_test_client.cc b/chromium/net/tools/quic/test_tools/quic_test_client.cc
index ea67f70202e..e44ccc39820 100644
--- a/chromium/net/tools/quic/test_tools/quic_test_client.cc
+++ b/chromium/net/tools/quic/test_tools/quic_test_client.cc
@@ -371,7 +371,7 @@ ssize_t QuicTestClient::GetOrCreateStreamAndSendRequest(
ret = stream->SendRequest(std::move(spdy_headers), body, fin);
++num_requests_;
} else {
- stream->WriteOrBufferBody(body.as_string(), fin, ack_listener);
+ stream->WriteOrBufferBody(string(body), fin, ack_listener);
ret = body.length();
}
if (GetQuicReloadableFlag(enable_quic_stateless_reject_support)) {
@@ -857,5 +857,20 @@ void QuicTestClient::ClearPerConnectionState() {
latest_created_stream_ = nullptr;
}
+void QuicTestClient::WaitForDelayedAcks() {
+ // kWaitDuration is a period of time that is long enough for all delayed
+ // acks to be sent and received on the other end.
+ const QuicTime::Delta kWaitDuration =
+ 4 * QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+
+ const QuicClock* clock = client()->client_session()->connection()->clock();
+
+ QuicTime wait_until = clock->ApproximateNow() + kWaitDuration;
+ while (clock->ApproximateNow() < wait_until) {
+ // This waits for up to 50 ms.
+ client()->WaitForEvents();
+ }
+}
+
} // namespace test
} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/quic_test_client.h b/chromium/net/tools/quic/test_tools/quic_test_client.h
index 6d7bfe2367f..99a78f13421 100644
--- a/chromium/net/tools/quic/test_tools/quic_test_client.h
+++ b/chromium/net/tools/quic/test_tools/quic_test_client.h
@@ -302,6 +302,10 @@ class QuicTestClient : public QuicSpdyStream::Visitor,
bool PopulateHeaderBlockFromUrl(const std::string& uri,
SpdyHeaderBlock* headers);
+ // Waits for a period of time that is long enough to receive all delayed acks
+ // sent by peer.
+ void WaitForDelayedAcks();
+
protected:
QuicTestClient();
diff --git a/chromium/net/tools/testserver/testserver.py b/chromium/net/tools/testserver/testserver.py
index 8d2369bd39c..345c4cd421b 100755
--- a/chromium/net/tools/testserver/testserver.py
+++ b/chromium/net/tools/testserver/testserver.py
@@ -124,6 +124,13 @@ class HTTPServer(testserver_base.ClientRestrictingServerMixIn,
pass
+class ThreadingHTTPServer(SocketServer.ThreadingMixIn,
+ HTTPServer):
+ """This variant of HTTPServer creates a new thread for every connection. It
+ should only be used with handlers that are known to be threadsafe."""
+
+ pass
+
class OCSPServer(testserver_base.ClientRestrictingServerMixIn,
testserver_base.BrokenPipeHandlerMixIn,
BaseHTTPServer.HTTPServer):
@@ -2119,7 +2126,7 @@ class ServerRunner(testserver_base.TestServerRunner):
elif self.options.server_type == SERVER_BASIC_AUTH_PROXY:
BasicAuthProxyRequestHandler.redirect_connect_to_localhost = \
self.options.redirect_connect_to_localhost
- server = HTTPServer((host, port), BasicAuthProxyRequestHandler)
+ server = ThreadingHTTPServer((host, port), BasicAuthProxyRequestHandler)
print 'BasicAuthProxy server started on port %d...' % server.server_port
server_data['port'] = server.server_port
elif self.options.server_type == SERVER_FTP:
diff --git a/chromium/net/tools/transport_security_state_generator/input_file_parsers.cc b/chromium/net/tools/transport_security_state_generator/input_file_parsers.cc
index 757afaa2d8f..85e2245cd3c 100644
--- a/chromium/net/tools/transport_security_state_generator/input_file_parsers.cc
+++ b/chromium/net/tools/transport_security_state_generator/input_file_parsers.cc
@@ -205,7 +205,7 @@ bool ParseCertificatesFile(base::StringPiece certs_input, Pinsets* pinsets) {
for (const base::StringPiece& line : SplitStringPiece(
certs_input, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL)) {
- if (line[0] == '#') {
+ if (!line.empty() && line[0] == '#') {
continue;
}
diff --git a/chromium/net/tools/update_ios_bundle_data.py b/chromium/net/tools/update_ios_bundle_data.py
index a142ca18b93..e6b8ad577e3 100755
--- a/chromium/net/tools/update_ios_bundle_data.py
+++ b/chromium/net/tools/update_ios_bundle_data.py
@@ -47,6 +47,7 @@ net_unittest_bundle_data_globs = [
"data/filter_unittests/*",
"data/name_constraints_unittest/*.pem",
"data/ocsp_unittest/*.pem",
+ "data/ov_name_constraints/*.pem",
"data/parse_certificate_unittest/*.pem",
"data/parse_certificate_unittest/*.pk8",
"data/test.html",
diff --git a/chromium/net/traffic_annotation/network_traffic_annotation.h b/chromium/net/traffic_annotation/network_traffic_annotation.h
index ae9ce305567..a3cdf49e36c 100644
--- a/chromium/net/traffic_annotation/network_traffic_annotation.h
+++ b/chromium/net/traffic_annotation/network_traffic_annotation.h
@@ -298,12 +298,6 @@ struct MutablePartialNetworkTrafficAnnotationTag {
net::DefineNetworkTrafficAnnotation( \
"missing", "Function called without traffic annotation.")
-// TODO(crbug.com/656607): Remove this temporary tag which is only used during
-// refactoring.
-#define NO_TRAFFIC_ANNOTATION_BUG_656607 \
- net::DefineNetworkTrafficAnnotation("undefined-656607", \
- "Temporary tag for crbug.com/656607.")
-
#undef COMPUTE_STRING_HASH
#endif // NET_TRAFFIC_ANNOTATION_NETWORK_TRAFFIC_ANNOTATION_H_
diff --git a/chromium/net/traffic_annotation/network_traffic_annotation_test_helper.h b/chromium/net/traffic_annotation/network_traffic_annotation_test_helper.h
index ce77c41d682..82b2ba1ae52 100644
--- a/chromium/net/traffic_annotation/network_traffic_annotation_test_helper.h
+++ b/chromium/net/traffic_annotation/network_traffic_annotation_test_helper.h
@@ -7,7 +7,7 @@
#include "net/traffic_annotation/network_traffic_annotation.h"
-// Macro for unit tests traffic annotations.
+// Macros for tests traffic annotations.
#define TRAFFIC_ANNOTATION_FOR_TESTS \
net::DefineNetworkTrafficAnnotation( \
"test", "Traffic annotation for unit, browser and other tests")
diff --git a/chromium/net/url_request/report_sender.cc b/chromium/net/url_request/report_sender.cc
index 63fc6e38aea..4b0f05eeabb 100644
--- a/chromium/net/url_request/report_sender.cc
+++ b/chromium/net/url_request/report_sender.cc
@@ -40,6 +40,10 @@ class CallbackInfo : public base::SupportsUserData::Data {
namespace net {
+const int ReportSender::kLoadFlags =
+ LOAD_BYPASS_CACHE | LOAD_DISABLE_CACHE | LOAD_DO_NOT_SEND_AUTH_DATA |
+ LOAD_DO_NOT_SEND_COOKIES | LOAD_DO_NOT_SAVE_COOKIES;
+
ReportSender::ReportSender(URLRequestContext* request_context,
net::NetworkTrafficAnnotationTag traffic_annotation)
: request_context_(request_context),
@@ -59,9 +63,7 @@ void ReportSender::Send(const GURL& report_uri,
&kUserDataKey,
std::make_unique<CallbackInfo>(success_callback, error_callback));
- url_request->SetLoadFlags(
- LOAD_BYPASS_CACHE | LOAD_DISABLE_CACHE | LOAD_DO_NOT_SEND_AUTH_DATA |
- LOAD_DO_NOT_SEND_COOKIES | LOAD_DO_NOT_SAVE_COOKIES);
+ url_request->SetLoadFlags(kLoadFlags);
HttpRequestHeaders extra_headers;
extra_headers.SetHeader(HttpRequestHeaders::kContentType, content_type);
diff --git a/chromium/net/url_request/report_sender.h b/chromium/net/url_request/report_sender.h
index 93e0c67b526..83f581c86b1 100644
--- a/chromium/net/url_request/report_sender.h
+++ b/chromium/net/url_request/report_sender.h
@@ -31,6 +31,8 @@ class NET_EXPORT ReportSender
: public URLRequest::Delegate,
public TransportSecurityState::ReportSenderInterface {
public:
+ static const int kLoadFlags;
+
using SuccessCallback = base::Callback<void()>;
using ErrorCallback = base::Callback<
void(const GURL&, int /* net_error */, int /* http_response_code */)>;
diff --git a/chromium/net/url_request/static_http_user_agent_settings.h b/chromium/net/url_request/static_http_user_agent_settings.h
index f6d90bdf758..eda424096ca 100644
--- a/chromium/net/url_request/static_http_user_agent_settings.h
+++ b/chromium/net/url_request/static_http_user_agent_settings.h
@@ -14,20 +14,24 @@
namespace net {
-// An implementation of |HttpUserAgentSettings| that always provides the
-// same constant values for the HTTP Accept-Language and User-Agent headers.
+// An implementation of |HttpUserAgentSettings| that provides configured
+// values for the HTTP Accept-Language and User-Agent headers.
class NET_EXPORT StaticHttpUserAgentSettings : public HttpUserAgentSettings {
public:
StaticHttpUserAgentSettings(const std::string& accept_language,
const std::string& user_agent);
~StaticHttpUserAgentSettings() override;
+ void set_accept_language(const std::string& new_accept_language) {
+ accept_language_ = new_accept_language;
+ }
+
// HttpUserAgentSettings implementation
std::string GetAcceptLanguage() const override;
std::string GetUserAgent() const override;
private:
- const std::string accept_language_;
+ std::string accept_language_;
const std::string user_agent_;
DISALLOW_COPY_AND_ASSIGN(StaticHttpUserAgentSettings);
diff --git a/chromium/net/url_request/url_fetcher.h b/chromium/net/url_request/url_fetcher.h
index 4b4caec2864..f4bddb1f00b 100644
--- a/chromium/net/url_request/url_fetcher.h
+++ b/chromium/net/url_request/url_fetcher.h
@@ -39,6 +39,11 @@ class URLFetcherResponseWriter;
class URLRequestContextGetter;
class URLRequestStatus;
+// NOTE: This class should not be used by content embedders, as it requires an
+// in-process network stack. Content embedders should use
+// network::SimpleURLLoader instead, which works with both in-process and
+// out-of-process network stacks.
+//
// To use this class, create an instance with the desired URL and a pointer to
// the object to be notified when the URL has been loaded:
// std::unique_ptr<URLFetcher> fetcher =
diff --git a/chromium/net/url_request/url_fetcher_impl_unittest.cc b/chromium/net/url_request/url_fetcher_impl_unittest.cc
index 57d1a57c291..ac30924bb5e 100644
--- a/chromium/net/url_request/url_fetcher_impl_unittest.cc
+++ b/chromium/net/url_request/url_fetcher_impl_unittest.cc
@@ -32,7 +32,6 @@
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
-#include "crypto/nss_util.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/network_change_notifier.h"
#include "net/base/upload_bytes_element_reader.h"
@@ -51,10 +50,6 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#if defined(USE_NSS_CERTS)
-#include "net/cert_net/nss_ocsp.h"
-#endif
-
namespace net {
using base::Time;
@@ -456,17 +451,6 @@ class URLFetcherTest : public testing::Test {
"http://example.com:%d%s", test_server_->host_port_pair().port(),
kDefaultResponsePath));
ASSERT_TRUE(hanging_url_.is_valid());
-
-#if defined(USE_NSS_CERTS)
- crypto::EnsureNSSInit();
- EnsureNSSHttpIOInit();
-#endif
- }
-
- void TearDown() override {
-#if defined(USE_NSS_CERTS)
- ShutdownNSSHttpIO();
-#endif
}
// Initializes |test_server_| without starting it. Allows subclasses to use
@@ -515,7 +499,7 @@ TEST_F(URLFetcherTest, FetchedUsingProxy) {
std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
ProxyResolutionService::CreateFixedFromPacResult(
- proxy_server.ToPacString());
+ proxy_server.ToPacString(), TRAFFIC_ANNOTATION_FOR_TESTS);
context_getter->set_proxy_resolution_service(
std::move(proxy_resolution_service));
diff --git a/chromium/net/url_request/url_request.cc b/chromium/net/url_request/url_request.cc
index 323d0db7647..7418a38294b 100644
--- a/chromium/net/url_request/url_request.cc
+++ b/chromium/net/url_request/url_request.cc
@@ -31,6 +31,7 @@
#include "net/log/net_log.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_source_type.h"
+#include "net/socket/next_proto.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "net/url_request/redirect_info.h"
#include "net/url_request/redirect_util.h"
@@ -557,6 +558,7 @@ URLRequest::URLRequest(const GURL& url,
net_log_(NetLogWithSource::Make(context->net_log(),
NetLogSourceType::URL_REQUEST)),
url_chain_(1, url),
+ attach_same_site_cookies_(false),
method_("GET"),
referrer_policy_(CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE),
first_party_url_policy_(NEVER_CHANGE_FIRST_PARTY_URL),
@@ -700,7 +702,7 @@ void URLRequest::CancelWithSSLError(int error, const SSLInfo& ssl_info) {
}
int URLRequest::DoCancel(int error, const SSLInfo& ssl_info) {
- DCHECK(error < 0);
+ DCHECK_LT(error, 0);
// If cancelled while calling a delegate, clear delegate info.
if (calling_delegate_) {
LogUnblocked();
@@ -1166,8 +1168,11 @@ void URLRequest::OnCallToDelegateComplete() {
void URLRequest::MaybeGenerateNetworkErrorLoggingReport() {
NetworkErrorLoggingService* service =
context()->network_error_logging_service();
- if (!service)
+ if (!service) {
+ NetworkErrorLoggingService::
+ RecordRequestDiscardedForNoNetworkErrorLoggingService();
return;
+ }
// TODO(juliatuttle): Figure out whether we should be ignoring errors from
// non-HTTPS origins.
@@ -1179,22 +1184,28 @@ void URLRequest::MaybeGenerateNetworkErrorLoggingReport() {
IPEndPoint endpoint;
if (GetRemoteEndpoint(&endpoint))
details.server_ip = endpoint.address();
- // TODO(juliatuttle): Plumb this.
- details.protocol = kProtoUnknown;
if (response_headers()) {
// HttpResponseHeaders::response_code() returns 0 if response code couldn't
// be parsed, which is also how NEL represents the same.
details.status_code = response_headers()->response_code();
+ // If we got response headers, assume that the connection used HTTP/1.1
+ // unless ALPN negotation tells us otherwise (handled below).
+ details.protocol = "http/1.1";
} else {
details.status_code = 0;
}
+ if (response_info().was_alpn_negotiated)
+ details.protocol = response_info().alpn_negotiated_protocol;
details.elapsed_time =
base::TimeTicks::Now() - load_timing_info_.request_start;
details.type = status().ToNetError();
- details.is_reporting_upload =
- context()->reporting_service() &&
- context()->reporting_service()->RequestIsUpload(*this);
+ if (context()->reporting_service()) {
+ details.reporting_upload_depth =
+ context()->reporting_service()->GetUploadDepth(*this);
+ } else {
+ details.reporting_upload_depth = 0;
+ }
service->OnRequest(details);
}
diff --git a/chromium/net/url_request/url_request.h b/chromium/net/url_request/url_request.h
index c0fc8aeee53..57273101f21 100644
--- a/chromium/net/url_request/url_request.h
+++ b/chromium/net/url_request/url_request.h
@@ -35,7 +35,7 @@
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "net/log/net_log_with_source.h"
-#include "net/net_features.h"
+#include "net/net_buildflags.h"
#include "net/socket/connection_attempts.h"
#include "net/socket/socket_tag.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
@@ -285,6 +285,13 @@ class NET_EXPORT URLRequest : public base::SupportsUserData {
// This method may only be called before Start().
void set_site_for_cookies(const GURL& site_for_cookies);
+ // Indicate whether SameSite cookies should be attached even though the
+ // request is cross-site.
+ bool attach_same_site_cookies() const { return attach_same_site_cookies_; }
+ void set_attach_same_site_cookies(bool attach) {
+ attach_same_site_cookies_ = attach;
+ }
+
// The first-party URL policy to apply when updating the first party URL
// during redirects. The first-party URL policy may only be changed before
// Start() is called.
@@ -815,6 +822,7 @@ class NET_EXPORT URLRequest : public base::SupportsUserData {
std::vector<GURL> url_chain_;
GURL site_for_cookies_;
+ bool attach_same_site_cookies_;
base::Optional<url::Origin> initiator_;
GURL delegate_redirect_url_;
std::string method_; // "GET", "POST", etc. Should be all uppercase.
diff --git a/chromium/net/url_request/url_request_context.cc b/chromium/net/url_request/url_request_context.cc
index 381107eac1e..e23b9ec4ff3 100644
--- a/chromium/net/url_request/url_request_context.cc
+++ b/chromium/net/url_request/url_request_context.cc
@@ -172,6 +172,9 @@ bool URLRequestContext::OnMemoryDump(
if (http_cache)
http_cache->DumpMemoryStats(pmd, dump->absolute_name());
}
+ if (cookie_store_) {
+ cookie_store_->DumpMemoryStats(pmd, dump->absolute_name());
+ }
return true;
}
diff --git a/chromium/net/url_request/url_request_context.h b/chromium/net/url_request/url_request_context.h
index e26a3f047fc..45640d69b66 100644
--- a/chromium/net/url_request/url_request_context.h
+++ b/chromium/net/url_request/url_request_context.h
@@ -22,7 +22,7 @@
#include "net/http/http_network_session.h"
#include "net/http/http_server_properties.h"
#include "net/http/transport_security_state.h"
-#include "net/net_features.h"
+#include "net/net_buildflags.h"
#include "net/ssl/ssl_config_service.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request.h"
@@ -144,8 +144,8 @@ class NET_EXPORT URLRequestContext
SSLConfigService* ssl_config_service() const {
return ssl_config_service_.get();
}
- void set_ssl_config_service(SSLConfigService* service) {
- ssl_config_service_ = service;
+ void set_ssl_config_service(scoped_refptr<SSLConfigService> service) {
+ ssl_config_service_ = std::move(service);
}
// Gets the HTTP Authentication Handler Factory for this context.
diff --git a/chromium/net/url_request/url_request_context_builder.cc b/chromium/net/url_request/url_request_context_builder.cc
index 442addd21cf..dcd957b56d8 100644
--- a/chromium/net/url_request/url_request_context_builder.cc
+++ b/chromium/net/url_request/url_request_context_builder.cc
@@ -33,7 +33,8 @@
#include "net/http/http_server_properties_manager.h"
#include "net/http/transport_security_persister.h"
#include "net/http/transport_security_state.h"
-#include "net/net_features.h"
+#include "net/log/net_log.h"
+#include "net/net_buildflags.h"
#include "net/nqe/network_quality_estimator.h"
#include "net/quic/chromium/quic_stream_factory.h"
#include "net/ssl/channel_id_service.h"
@@ -125,7 +126,7 @@ class BasicNetworkDelegate : public NetworkDelegateImpl {
}
bool OnCanSetCookie(const URLRequest& request,
- const net::CanonicalCookie& cookie,
+ const CanonicalCookie& cookie,
CookieOptions* options) override {
return true;
}
@@ -197,7 +198,6 @@ URLRequestContextBuilder::HttpCacheParams::~HttpCacheParams() = default;
URLRequestContextBuilder::URLRequestContextBuilder()
: enable_brotli_(false),
network_quality_estimator_(nullptr),
- shared_http_user_agent_settings_(nullptr),
data_enabled_(false),
#if !BUILDFLAG(DISABLE_FILE_SUPPORT)
file_enabled_(false),
@@ -253,18 +253,17 @@ void URLRequestContextBuilder::SetHttpNetworkSessionComponents(
void URLRequestContextBuilder::set_accept_language(
const std::string& accept_language) {
- DCHECK(!shared_http_user_agent_settings_);
+ DCHECK(!http_user_agent_settings_);
accept_language_ = accept_language;
}
void URLRequestContextBuilder::set_user_agent(const std::string& user_agent) {
- DCHECK(!shared_http_user_agent_settings_);
+ DCHECK(!http_user_agent_settings_);
user_agent_ = user_agent;
}
-void URLRequestContextBuilder::set_shared_http_user_agent_settings(
- HttpUserAgentSettings* shared_http_user_agent_settings) {
- DCHECK(accept_language_.empty());
- DCHECK(user_agent_.empty());
- shared_http_user_agent_settings_ = shared_http_user_agent_settings;
+
+void URLRequestContextBuilder::set_http_user_agent_settings(
+ std::unique_ptr<HttpUserAgentSettings> http_user_agent_settings) {
+ http_user_agent_settings_ = std::move(http_user_agent_settings);
}
void URLRequestContextBuilder::EnableHttpCache(const HttpCacheParams& params) {
@@ -300,7 +299,7 @@ void URLRequestContextBuilder::SetCertVerifier(
#if BUILDFLAG(ENABLE_REPORTING)
void URLRequestContextBuilder::set_reporting_policy(
- std::unique_ptr<net::ReportingPolicy> reporting_policy) {
+ std::unique_ptr<ReportingPolicy> reporting_policy) {
reporting_policy_ = std::move(reporting_policy);
}
#endif // BUILDFLAG(ENABLE_REPORTING)
@@ -395,8 +394,8 @@ std::unique_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
context->set_enable_brotli(enable_brotli_);
context->set_network_quality_estimator(network_quality_estimator_);
- if (shared_http_user_agent_settings_) {
- context->set_http_user_agent_settings(shared_http_user_agent_settings_);
+ if (http_user_agent_settings_) {
+ storage->set_http_user_agent_settings(std::move(http_user_agent_settings_));
} else {
storage->set_http_user_agent_settings(
std::make_unique<StaticHttpUserAgentSettings>(accept_language_,
@@ -428,7 +427,7 @@ std::unique_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
if (ssl_config_service_) {
// This takes a raw pointer, but |storage| will hold onto a reference to the
// service.
- storage->set_ssl_config_service(ssl_config_service_.get());
+ storage->set_ssl_config_service(ssl_config_service_);
} else {
storage->set_ssl_config_service(new SSLConfigServiceDefaults);
}
@@ -517,10 +516,10 @@ std::unique_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
base::ThreadTaskRunnerHandle::Get().get());
}
#endif // !defined(OS_LINUX) && !defined(OS_ANDROID)
- proxy_resolution_service_ =
- CreateProxyService(std::move(proxy_config_service_), context.get(),
- context->host_resolver(),
- context->network_delegate(), context->net_log());
+ proxy_resolution_service_ = CreateProxyResolutionService(
+ std::move(proxy_config_service_), context.get(),
+ context->host_resolver(), context->network_delegate(),
+ context->net_log());
proxy_resolution_service_->set_quick_check_enabled(pac_quick_check_enabled_);
proxy_resolution_service_->set_sanitize_url_policy(pac_sanitize_url_policy_);
}
@@ -614,13 +613,13 @@ std::unique_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
}
#endif // !BUILDFLAG(DISABLE_FTP_SUPPORT)
- std::unique_ptr<net::URLRequestJobFactory> top_job_factory(job_factory);
+ std::unique_ptr<URLRequestJobFactory> top_job_factory(job_factory);
if (!url_request_interceptors_.empty()) {
// Set up interceptors in the reverse order.
for (auto i = url_request_interceptors_.rbegin();
i != url_request_interceptors_.rend(); ++i) {
- top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
+ top_job_factory.reset(new URLRequestInterceptingJobFactory(
std::move(top_job_factory), std::move(*i)));
}
url_request_interceptors_.clear();
@@ -660,7 +659,7 @@ std::unique_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
}
std::unique_ptr<ProxyResolutionService>
-URLRequestContextBuilder::CreateProxyService(
+URLRequestContextBuilder::CreateProxyResolutionService(
std::unique_ptr<ProxyConfigService> proxy_config_service,
URLRequestContext* url_request_context,
HostResolver* host_resolver,
diff --git a/chromium/net/url_request/url_request_context_builder.h b/chromium/net/url_request/url_request_context_builder.h
index 2ecaaf01bb9..eae0d24a808 100644
--- a/chromium/net/url_request/url_request_context_builder.h
+++ b/chromium/net/url_request/url_request_context_builder.h
@@ -35,11 +35,10 @@
#include "net/base/proxy_delegate.h"
#include "net/dns/host_resolver.h"
#include "net/http/http_network_session.h"
-#include "net/net_features.h"
+#include "net/net_buildflags.h"
#include "net/proxy_resolution/proxy_config_service.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/quic/core/quic_packets.h"
-#include "net/socket/next_proto.h"
#include "net/ssl/ssl_config_service.h"
#include "net/url_request/url_request_job_factory.h"
@@ -82,14 +81,14 @@ struct ReportingPolicy;
class NET_EXPORT URLRequestContextBuilder {
public:
using CreateInterceptingJobFactory =
- base::OnceCallback<std::unique_ptr<net::URLRequestJobFactory>(
- std::unique_ptr<net::URLRequestJobFactory> inner_job_factory)>;
+ base::OnceCallback<std::unique_ptr<URLRequestJobFactory>(
+ std::unique_ptr<URLRequestJobFactory> inner_job_factory)>;
// Creates an HttpNetworkTransactionFactory given an HttpNetworkSession. Does
// not take ownership of the session.
using CreateHttpTransactionFactoryCallback =
- base::OnceCallback<std::unique_ptr<net::HttpTransactionFactory>(
- net::HttpNetworkSession* session)>;
+ base::OnceCallback<std::unique_ptr<HttpTransactionFactory>(
+ HttpNetworkSession* session)>;
struct NET_EXPORT HttpCacheParams {
enum Type {
@@ -160,21 +159,21 @@ class NET_EXPORT URLRequestContextBuilder {
// ProxyResolutionService::SanitizeUrlPolicy::SAFE. Ignored if
// a ProxyResolutionService is set directly.
void set_pac_sanitize_url_policy(
- net::ProxyResolutionService::SanitizeUrlPolicy pac_sanitize_url_policy) {
+ ProxyResolutionService::SanitizeUrlPolicy pac_sanitize_url_policy) {
pac_sanitize_url_policy_ = pac_sanitize_url_policy;
}
// Sets the proxy service. If one is not provided, by default, uses system
// libraries to evaluate PAC scripts, if available (And if not, skips PAC
- // resolution). Subclasses may override CreateProxyService for different
- // default behavior.
+ // resolution). Subclasses may override CreateProxyResolutionService for
+ // different default behavior.
void set_proxy_resolution_service(
std::unique_ptr<ProxyResolutionService> proxy_resolution_service) {
proxy_resolution_service_ = std::move(proxy_resolution_service);
}
void set_ssl_config_service(
- scoped_refptr<net::SSLConfigService> ssl_config_service) {
+ scoped_refptr<SSLConfigService> ssl_config_service) {
ssl_config_service_ = std::move(ssl_config_service);
}
@@ -183,15 +182,13 @@ class NET_EXPORT URLRequestContextBuilder {
// have the headers already set.
void set_accept_language(const std::string& accept_language);
void set_user_agent(const std::string& user_agent);
- // Makes the created URLRequestContext use a shared HttpUserAgentSettings
- // object. Not compatible with set_accept_language() / set_user_agent(). The
- // consumer must ensure the HttpUserAgentSettings outlives the
- // URLRequestContext returned by the builder.
+
+ // Makes the created URLRequestContext use a particular HttpUserAgentSettings
+ // object. Not compatible with set_accept_language() / set_user_agent().
//
- // TODO(mmenke): Take ownership of the object instead. See:
- // https://crbug.com/743251
- void set_shared_http_user_agent_settings(
- HttpUserAgentSettings* shared_http_user_agent_settings);
+ // The object will be live until the URLRequestContext is destroyed.
+ void set_http_user_agent_settings(
+ std::unique_ptr<HttpUserAgentSettings> http_user_agent_settings);
// Control support for data:// requests. By default it's disabled.
void set_data_enabled(bool enable) {
@@ -296,8 +293,7 @@ class NET_EXPORT URLRequestContextBuilder {
void SetCertVerifier(std::unique_ptr<CertVerifier> cert_verifier);
#if BUILDFLAG(ENABLE_REPORTING)
- void set_reporting_policy(
- std::unique_ptr<net::ReportingPolicy> reporting_policy);
+ void set_reporting_policy(std::unique_ptr<ReportingPolicy> reporting_policy);
void set_network_error_logging_enabled(bool network_error_logging_enabled) {
network_error_logging_enabled_ = network_error_logging_enabled;
@@ -350,7 +346,7 @@ class NET_EXPORT URLRequestContextBuilder {
// ProxyResolutionService that uses the URLRequestContext itself to get PAC
// scripts. When this method is invoked, the URLRequestContext is not yet
// ready to service requests.
- virtual std::unique_ptr<ProxyResolutionService> CreateProxyService(
+ virtual std::unique_ptr<ProxyResolutionService> CreateProxyResolutionService(
std::unique_ptr<ProxyConfigService> proxy_config_service,
URLRequestContext* url_request_context,
HostResolver* host_resolver,
@@ -364,7 +360,7 @@ class NET_EXPORT URLRequestContextBuilder {
std::string accept_language_;
std::string user_agent_;
- HttpUserAgentSettings* shared_http_user_agent_settings_;
+ std::unique_ptr<HttpUserAgentSettings> http_user_agent_settings_;
// Include support for data:// requests.
bool data_enabled_;
@@ -386,13 +382,13 @@ class NET_EXPORT URLRequestContextBuilder {
base::FilePath transport_security_persister_path_;
NetLog* net_log_;
std::unique_ptr<HostResolver> host_resolver_;
- net::HostResolver* shared_host_resolver_;
+ HostResolver* shared_host_resolver_;
std::unique_ptr<ChannelIDService> channel_id_service_;
std::unique_ptr<ProxyConfigService> proxy_config_service_;
bool pac_quick_check_enabled_;
ProxyResolutionService::SanitizeUrlPolicy pac_sanitize_url_policy_;
std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
- scoped_refptr<net::SSLConfigService> ssl_config_service_;
+ scoped_refptr<SSLConfigService> ssl_config_service_;
std::unique_ptr<NetworkDelegate> network_delegate_;
std::unique_ptr<ProxyDelegate> proxy_delegate_;
ProxyDelegate* shared_proxy_delegate_;
@@ -403,7 +399,7 @@ class NET_EXPORT URLRequestContextBuilder {
std::unique_ptr<CTVerifier> ct_verifier_;
std::unique_ptr<CTPolicyEnforcer> ct_policy_enforcer_;
#if BUILDFLAG(ENABLE_REPORTING)
- std::unique_ptr<net::ReportingPolicy> reporting_policy_;
+ std::unique_ptr<ReportingPolicy> reporting_policy_;
bool network_error_logging_enabled_;
#endif // BUILDFLAG(ENABLE_REPORTING)
std::vector<std::unique_ptr<URLRequestInterceptor>> url_request_interceptors_;
diff --git a/chromium/net/url_request/url_request_context_builder_unittest.cc b/chromium/net/url_request/url_request_context_builder_unittest.cc
index c044aa069d9..74988663168 100644
--- a/chromium/net/url_request/url_request_context_builder_unittest.cc
+++ b/chromium/net/url_request/url_request_context_builder_unittest.cc
@@ -60,8 +60,8 @@ class URLRequestContextBuilderTest : public PlatformTest {
test_server_.AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
#if defined(OS_LINUX) || defined(OS_ANDROID)
- builder_.set_proxy_config_service(
- std::make_unique<ProxyConfigServiceFixed>(ProxyConfig::CreateDirect()));
+ builder_.set_proxy_config_service(std::make_unique<ProxyConfigServiceFixed>(
+ ProxyConfigWithAnnotation::CreateDirect()));
#endif // defined(OS_LINUX) || defined(OS_ANDROID)
}
diff --git a/chromium/net/url_request/url_request_context_storage.cc b/chromium/net/url_request/url_request_context_storage.cc
index ca3825c2f9d..4915c8fed48 100644
--- a/chromium/net/url_request/url_request_context_storage.cc
+++ b/chromium/net/url_request/url_request_context_storage.cc
@@ -18,7 +18,7 @@
#include "net/http/http_server_properties.h"
#include "net/http/http_transaction_factory.h"
#include "net/log/net_log.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/ssl/channel_id_service.h"
#include "net/url_request/http_user_agent_settings.h"
#include "net/url_request/url_request_context.h"
@@ -86,7 +86,7 @@ void URLRequestContextStorage::set_proxy_resolution_service(
}
void URLRequestContextStorage::set_ssl_config_service(
- SSLConfigService* ssl_config_service) {
+ scoped_refptr<SSLConfigService> ssl_config_service) {
context_->set_ssl_config_service(ssl_config_service);
ssl_config_service_ = ssl_config_service;
}
diff --git a/chromium/net/url_request/url_request_context_storage.h b/chromium/net/url_request/url_request_context_storage.h
index b44a0605582..655c42de6a2 100644
--- a/chromium/net/url_request/url_request_context_storage.h
+++ b/chromium/net/url_request/url_request_context_storage.h
@@ -11,7 +11,7 @@
#include "base/memory/ref_counted.h"
#include "build/buildflag.h"
#include "net/base/net_export.h"
-#include "net/net_features.h"
+#include "net/net_buildflags.h"
namespace net {
@@ -65,7 +65,8 @@ class NET_EXPORT URLRequestContextStorage {
void set_network_delegate(std::unique_ptr<NetworkDelegate> network_delegate);
void set_proxy_resolution_service(
std::unique_ptr<ProxyResolutionService> proxy_resolution_service);
- void set_ssl_config_service(SSLConfigService* ssl_config_service);
+ void set_ssl_config_service(
+ scoped_refptr<SSLConfigService> ssl_config_service);
void set_http_server_properties(
std::unique_ptr<HttpServerProperties> http_server_properties);
void set_cookie_store(std::unique_ptr<CookieStore> cookie_store);
diff --git a/chromium/net/url_request/url_request_context_unittest.cc b/chromium/net/url_request/url_request_context_unittest.cc
index 02b6f40d25b..eeef64ac374 100644
--- a/chromium/net/url_request/url_request_context_unittest.cc
+++ b/chromium/net/url_request/url_request_context_unittest.cc
@@ -7,6 +7,7 @@
#include "base/trace_event/memory_dump_request_args.h"
#include "base/trace_event/process_memory_dump.h"
#include "net/proxy_resolution/proxy_config_service_fixed.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_context_builder.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -29,8 +30,8 @@ TEST_P(URLRequestContextMemoryDumpTest, MemoryDumpProvider) {
new base::trace_event::ProcessMemoryDump(nullptr, dump_args));
URLRequestContextBuilder builder;
#if defined(OS_LINUX) || defined(OS_ANDROID)
- builder.set_proxy_config_service(
- std::make_unique<ProxyConfigServiceFixed>(ProxyConfig::CreateDirect()));
+ builder.set_proxy_config_service(std::make_unique<ProxyConfigServiceFixed>(
+ ProxyConfigWithAnnotation::CreateDirect()));
#endif // defined(OS_LINUX) || defined(OS_ANDROID)
std::unique_ptr<URLRequestContext> context(builder.Build());
context->OnMemoryDump(dump_args, process_memory_dump.get());
diff --git a/chromium/net/url_request/url_request_data_job_fuzzer.cc b/chromium/net/url_request/url_request_data_job_fuzzer.cc
index dc14e1d7fb9..fa6ad4b33b3 100644
--- a/chromium/net/url_request/url_request_data_job_fuzzer.cc
+++ b/chromium/net/url_request/url_request_data_job_fuzzer.cc
@@ -44,10 +44,8 @@ class URLRequestDataJobFuzzerHarness : public net::URLRequest::Delegate {
read_lengths_.clear();
// Allocate an IOBuffer with fuzzed size.
- uint32_t buf_size = provider.ConsumeUint32InRange(1, 127); // 7 bits.
- scoped_refptr<net::IOBuffer> buf(
- new net::IOBuffer(static_cast<size_t>(buf_size)));
- buf_.swap(buf);
+ int buf_size = provider.ConsumeUint32InRange(1, 127); // 7 bits.
+ buf_ = base::MakeRefCounted<net::IOBufferWithSize>(buf_size);
// Generate a range header, and a bool determining whether to use it.
// Generate the header regardless of the bool value to keep the data URL and
@@ -56,9 +54,12 @@ class URLRequestDataJobFuzzerHarness : public net::URLRequest::Delegate {
bool use_range = provider.ConsumeBool();
std::string range(provider.ConsumeBytes(kMaxLengthForFuzzedRange));
- // Generate a sequence of reads sufficient to read the entire data URL.
+ // Generate a sequence of reads sufficient to read the entire data URL,
+ // capping it at 20000 reads, to avoid hangs. Once the limit is reached,
+ // all subsequent reads will be 32k.
size_t simulated_bytes_read = 0;
- while (simulated_bytes_read < provider.remaining_bytes()) {
+ while (simulated_bytes_read < provider.remaining_bytes() &&
+ read_lengths_.size() < 20000u) {
size_t read_length = provider.ConsumeUint32InRange(1, buf_size);
read_lengths_.push_back(read_length);
simulated_bytes_read += read_length;
@@ -100,14 +101,14 @@ class URLRequestDataJobFuzzerHarness : public net::URLRequest::Delegate {
void ReadFromRequest(net::URLRequest* request) {
int bytes_read = 0;
do {
- // If possible, pop the next read size. If none exists, then this should
- // be the last call to Read.
- bool using_populated_read = read_lengths_.size() > 0;
- size_t read_size = 1;
- if (using_populated_read) {
+ size_t read_size = 32 * 1024;
+ // If possible, pop the next read size.
+ if (read_lengths_.size() > 0) {
read_size = read_lengths_.back();
read_lengths_.pop_back();
}
+ if (read_size > static_cast<size_t>(buf_->size()))
+ buf_ = base::MakeRefCounted<net::IOBufferWithSize>(read_size);
bytes_read = request->Read(buf_.get(), read_size);
} while (bytes_read > 0);
@@ -159,8 +160,8 @@ class URLRequestDataJobFuzzerHarness : public net::URLRequest::Delegate {
net::TestURLRequestContext context_;
net::URLRequestJobFactoryImpl job_factory_;
std::vector<size_t> read_lengths_;
- scoped_refptr<net::IOBuffer> buf_;
- base::RunLoop* read_loop_;
+ scoped_refptr<net::IOBufferWithSize> buf_;
+ base::RunLoop* read_loop_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(URLRequestDataJobFuzzerHarness);
};
diff --git a/chromium/net/url_request/url_request_ftp_job.h b/chromium/net/url_request/url_request_ftp_job.h
index e6e8fde4ef3..9b56e7cd2f1 100644
--- a/chromium/net/url_request/url_request_ftp_job.h
+++ b/chromium/net/url_request/url_request_ftp_job.h
@@ -17,7 +17,7 @@
#include "net/http/http_request_info.h"
#include "net/http/http_transaction.h"
#include "net/proxy_resolution/proxy_info.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/url_request/url_request_job.h"
namespace net {
diff --git a/chromium/net/url_request/url_request_ftp_job_unittest.cc b/chromium/net/url_request/url_request_ftp_job_unittest.cc
index 2bfbec17d99..d7bc7c6148f 100644
--- a/chromium/net/url_request/url_request_ftp_job_unittest.cc
+++ b/chromium/net/url_request/url_request_ftp_job_unittest.cc
@@ -44,11 +44,10 @@ class MockProxyResolverFactory : public ProxyResolverFactory {
MockProxyResolverFactory()
: ProxyResolverFactory(false), resolver_(nullptr) {}
- int CreateProxyResolver(
- const scoped_refptr<ProxyResolverScriptData>& pac_script,
- std::unique_ptr<ProxyResolver>* resolver,
- const CompletionCallback& callback,
- std::unique_ptr<Request>* request) override {
+ int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
+ std::unique_ptr<ProxyResolver>* resolver,
+ const CompletionCallback& callback,
+ std::unique_ptr<Request>* request) override {
EXPECT_FALSE(resolver_);
std::unique_ptr<MockAsyncProxyResolver> owned_resolver(
new MockAsyncProxyResolver());
@@ -114,7 +113,10 @@ class SimpleProxyConfigService : public ProxyConfigService {
public:
SimpleProxyConfigService() {
// Any FTP requests that ever go through HTTP paths are proxied requests.
- config_.proxy_rules().ParseFromString("ftp=localhost");
+ ProxyConfig proxy_config = config_.value();
+ proxy_config.proxy_rules().ParseFromString("ftp=localhost");
+ config_ =
+ ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS);
}
void AddObserver(Observer* observer) override { observer_ = observer; }
@@ -125,13 +127,14 @@ class SimpleProxyConfigService : public ProxyConfigService {
}
}
- ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) override {
+ ConfigAvailability GetLatestProxyConfig(
+ ProxyConfigWithAnnotation* config) override {
*config = config_;
return CONFIG_VALID;
}
private:
- ProxyConfig config_;
+ ProxyConfigWithAnnotation config_;
Observer* observer_;
};
@@ -327,8 +330,9 @@ TEST_F(URLRequestFtpJobTest, FtpProxyRequestOrphanJob) {
// Use a PAC URL so that URLRequestFtpJob's |pac_request_| field is non-NULL.
request_context()->set_proxy_resolution_service(
std::make_unique<ProxyResolutionService>(
- std::make_unique<ProxyConfigServiceFixed>(
- ProxyConfig::CreateFromCustomPacURL(GURL("http://foo"))),
+ std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
+ ProxyConfig::CreateFromCustomPacURL(GURL("http://foo")),
+ TRAFFIC_ANNOTATION_FOR_TESTS)),
std::move(owned_resolver_factory), nullptr));
TestDelegate request_delegate;
@@ -360,8 +364,9 @@ TEST_F(URLRequestFtpJobTest, FtpProxyRequestCancelRequest) {
// Use a PAC URL so that URLRequestFtpJob's |pac_request_| field is non-NULL.
request_context()->set_proxy_resolution_service(
std::make_unique<ProxyResolutionService>(
- std::make_unique<ProxyConfigServiceFixed>(
- ProxyConfig::CreateFromCustomPacURL(GURL("http://foo"))),
+ std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
+ ProxyConfig::CreateFromCustomPacURL(GURL("http://foo")),
+ TRAFFIC_ANNOTATION_FOR_TESTS)),
std::move(owned_resolver_factory), nullptr));
TestDelegate request_delegate;
diff --git a/chromium/net/url_request/url_request_http_job.cc b/chromium/net/url_request/url_request_http_job.cc
index c7408ebc8f0..ec4eeca9d21 100644
--- a/chromium/net/url_request/url_request_http_job.cc
+++ b/chromium/net/url_request/url_request_http_job.cc
@@ -51,13 +51,14 @@
#include "net/http/http_transaction.h"
#include "net/http/http_transaction_factory.h"
#include "net/http/http_util.h"
+#include "net/log/net_log.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_with_source.h"
-#include "net/net_features.h"
+#include "net/net_buildflags.h"
#include "net/nqe/network_quality_estimator.h"
#include "net/proxy_resolution/proxy_info.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/proxy_resolution/proxy_retry_info.h"
-#include "net/proxy_resolution/proxy_service.h"
#include "net/ssl/channel_id_service.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "net/ssl/ssl_config_service.h"
@@ -65,10 +66,11 @@
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_error_job.h"
+#include "net/url_request/url_request_http_job_histogram.h"
#include "net/url_request/url_request_job_factory.h"
#include "net/url_request/url_request_redirect_job.h"
#include "net/url_request/url_request_throttler_manager.h"
-#include "net/websockets/websocket_handshake_stream_base.h"
+#include "net/url_request/websocket_handshake_userdata_key.h"
#include "url/origin.h"
#if defined(OS_ANDROID)
@@ -228,22 +230,86 @@ void LogChannelIDAndCookieStores(const GURL& url,
EPHEMERALITY_MAX);
}
-void LogCookieAgeForNonSecureRequest(const net::CookieList& cookie_list,
- const net::URLRequest& request) {
+net::CookieNetworkSecurity HistogramEntryForCookie(
+ const net::CanonicalCookie& cookie,
+ const net::URLRequest& request,
+ const net::HttpRequestInfo& request_info) {
+ if (!request_info.url.SchemeIsCryptographic()) {
+ return net::CookieNetworkSecurity::k1pNonsecureConnection;
+ }
+
+ if (cookie.IsSecure()) {
+ return net::CookieNetworkSecurity::k1pSecureAttribute;
+ }
+
+ net::TransportSecurityState* transport_security_state =
+ request.context()->transport_security_state();
+ net::TransportSecurityState::STSState sts_state;
+ const std::string cookie_domain =
+ cookie.IsHostCookie() ? request.url().host() : cookie.Domain().substr(1);
+ const bool hsts =
+ transport_security_state->GetSTSState(cookie_domain, &sts_state) &&
+ sts_state.ShouldUpgradeToSSL();
+ if (!hsts) {
+ return net::CookieNetworkSecurity::k1pSecureConnection;
+ }
+
+ if (cookie.IsHostCookie()) {
+ if (cookie.IsPersistent() && sts_state.expiry >= cookie.ExpiryDate()) {
+ return net::CookieNetworkSecurity::k1pHSTSHostCookie;
+ } else {
+ // Session cookies are assumed to live forever.
+ return net::CookieNetworkSecurity::k1pExpiringHSTSHostCookie;
+ }
+ }
+
+ // Domain cookies require HSTS to include subdomains to prevent spoofing.
+ if (sts_state.include_subdomains) {
+ if (cookie.IsPersistent() && sts_state.expiry >= cookie.ExpiryDate()) {
+ return net::CookieNetworkSecurity::k1pHSTSSubdomainsIncluded;
+ } else {
+ // Session cookies are assumed to live forever.
+ return net::CookieNetworkSecurity::k1pExpiringHSTSSubdomainsIncluded;
+ }
+ }
+
+ return net::CookieNetworkSecurity::k1pHSTSSpoofable;
+}
+
+void LogCookieUMA(const net::CookieList& cookie_list,
+ const net::URLRequest& request,
+ const net::HttpRequestInfo& request_info) {
+ const bool secure_request = request_info.url.SchemeIsCryptographic();
+ const bool same_site = net::registry_controlled_domains::SameDomainOrHost(
+ request.url(), request.site_for_cookies(),
+ net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
+
+ const base::Time now = base::Time::Now();
base::Time oldest = base::Time::Max();
- for (const auto& cookie : cookie_list)
+ for (const auto& cookie : cookie_list) {
+ const std::string histogram_name =
+ std::string("Cookie.AllAgesFor") +
+ (secure_request ? "Secure" : "NonSecure") +
+ (same_site ? "SameSite" : "CrossSite") + "Request";
+ const int age_in_days = (now - cookie.CreationDate()).InDays();
+ base::UmaHistogramCounts1000(histogram_name, age_in_days);
oldest = std::min(cookie.CreationDate(), oldest);
- base::TimeDelta delta = base::Time::Now() - oldest;
- if (net::registry_controlled_domains::SameDomainOrHost(
- request.url(), request.site_for_cookies(),
- net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)) {
- UMA_HISTOGRAM_COUNTS_1000("Cookie.AgeForNonSecureSameSiteRequest",
- delta.InDays());
- } else {
- UMA_HISTOGRAM_COUNTS_1000("Cookie.AgeForNonSecureCrossSiteRequest",
- delta.InDays());
+ net::CookieNetworkSecurity entry =
+ HistogramEntryForCookie(cookie, request, request_info);
+ if (!same_site) {
+ entry =
+ static_cast<net::CookieNetworkSecurity>(static_cast<int>(entry) | 1);
+ }
+ UMA_HISTOGRAM_ENUMERATION("Cookie.NetworkSecurity", entry,
+ net::CookieNetworkSecurity::kCount);
}
+
+ const std::string histogram_name =
+ std::string("Cookie.AgeFor") + (secure_request ? "Secure" : "NonSecure") +
+ (same_site ? "SameSite" : "CrossSite") + "Request";
+ const int age_in_days = (now - oldest).InDays();
+ base::UmaHistogramCounts1000(histogram_name, age_in_days);
}
} // namespace
@@ -551,8 +617,8 @@ void URLRequestHttpJob::StartTransactionInternal() {
priority_, &transaction_);
if (rv == OK && request_info_.url.SchemeIsWSOrWSS()) {
- base::SupportsUserData::Data* data = request_->GetUserData(
- WebSocketHandshakeStreamBase::CreateHelper::DataKey());
+ base::SupportsUserData::Data* data =
+ request_->GetUserData(kWebSocketHandshakeUserDataKey);
if (data) {
transaction_->SetWebSocketHandshakeStreamCreateHelper(
static_cast<WebSocketHandshakeStreamBase::CreateHelper*>(data));
@@ -652,6 +718,12 @@ void URLRequestHttpJob::AddCookieHeaderAndStart() {
// Note that this will generally be the case only for cross-site requests
// which target a top-level browsing context.
//
+ // * Include both "strict" and "lax" same-site cookies if the request is
+ // tagged with a flag allowing it.
+ // Note that this can be the case for requests initiated by extensions,
+ // which need to behave as though they are made by the document itself,
+ // but appear like cross-site ones.
+ //
// * Otherwise, do not include same-site cookies.
if (registry_controlled_domains::SameDomainOrHost(
request_->url(), request_->site_for_cookies(),
@@ -659,7 +731,8 @@ void URLRequestHttpJob::AddCookieHeaderAndStart() {
if (!request_->initiator() ||
registry_controlled_domains::SameDomainOrHost(
request_->url(), request_->initiator().value().GetURL(),
- registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)) {
+ registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES) ||
+ request_->attach_same_site_cookies()) {
options.set_same_site_cookie_mode(
CookieOptions::SameSiteCookieMode::INCLUDE_STRICT_AND_LAX);
} else if (HttpUtil::IsMethodSafe(request_->method())) {
@@ -679,8 +752,7 @@ void URLRequestHttpJob::AddCookieHeaderAndStart() {
void URLRequestHttpJob::SetCookieHeaderAndStart(const CookieList& cookie_list) {
if (!cookie_list.empty() && CanGetCookies(cookie_list)) {
- if (!request_info_.url.SchemeIsCryptographic())
- LogCookieAgeForNonSecureRequest(cookie_list, *request_);
+ LogCookieUMA(cookie_list, *request_, request_info_);
std::string cookie_line = CanonicalCookie::BuildCookieLine(cookie_list);
UMA_HISTOGRAM_COUNTS_10000("Cookie.HeaderLength", cookie_line.length());
@@ -862,14 +934,23 @@ void URLRequestHttpJob::ProcessNetworkErrorLoggingHeader() {
NetworkErrorLoggingService* service =
request_->context()->network_error_logging_service();
- if (!service)
+ if (!service) {
+ NetworkErrorLoggingService::
+ RecordHeaderDiscardedForNoNetworkErrorLoggingService();
return;
+ }
- // Only accept Report-To headers on HTTPS connections that have no
- // certificate errors.
+ // Only accept NEL headers on HTTPS connections that have no certificate
+ // errors.
const SSLInfo& ssl_info = response_info_->ssl_info;
- if (!ssl_info.is_valid() || IsCertStatusError(ssl_info.cert_status))
+ if (!ssl_info.is_valid()) {
+ NetworkErrorLoggingService::RecordHeaderDiscardedForInvalidSSLInfo();
return;
+ }
+ if (IsCertStatusError(ssl_info.cert_status)) {
+ NetworkErrorLoggingService::RecordHeaderDiscardedForCertStatusError();
+ return;
+ }
service->OnHeader(url::Origin::Create(request_info_.url), value);
}
diff --git a/chromium/net/url_request/url_request_http_job.h b/chromium/net/url_request/url_request_http_job.h
index 1f050c2c4cf..f5f84b7dc98 100644
--- a/chromium/net/url_request/url_request_http_job.h
+++ b/chromium/net/url_request/url_request_http_job.h
@@ -21,7 +21,7 @@
#include "net/base/net_export.h"
#include "net/cookies/cookie_store.h"
#include "net/http/http_request_info.h"
-#include "net/net_features.h"
+#include "net/net_buildflags.h"
#include "net/socket/connection_attempts.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_throttler_entry_interface.h"
diff --git a/chromium/net/url_request/url_request_http_job_histogram.h b/chromium/net/url_request/url_request_http_job_histogram.h
new file mode 100644
index 00000000000..ca84fc54c5e
--- /dev/null
+++ b/chromium/net/url_request/url_request_http_job_histogram.h
@@ -0,0 +1,39 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_URL_REQUEST_URL_REQUEST_HTTP_JOB_HISTOGRAM_H_
+#define NET_URL_REQUEST_URL_REQUEST_HTTP_JOB_HISTOGRAM_H_
+
+namespace net {
+
+// Degree of protection against cookie theft in decreasing order (split by 1st
+// party and 3rd party cookies).
+//
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused. First-party entries need to reside at
+// even values and the corresponding third-party entry needs to be at
+// [first-party] + 1 to allow bit manipulation.
+enum class CookieNetworkSecurity {
+ k1pSecureAttribute = 0, // Secure attribute
+ k3pSecureAttribute = 1, // "
+ k1pHSTSHostCookie = 2, // HSTS covering cookie lifetime
+ k3pHSTSHostCookie = 3, // host cookie
+ k1pHSTSSubdomainsIncluded = 4, // HSTS covering cookie lifetime
+ k3pHSTSSubdomainsIncluded = 5, // subdomains included
+ k1pExpiringHSTSHostCookie = 6, // HSTS not covering cookie lifetime
+ k3pExpiringHSTSHostCookie = 7, // host cookie
+ k1pExpiringHSTSSubdomainsIncluded = 8, // HSTS not covering cookie lifetime
+ k3pExpiringHSTSSubdomainsIncluded = 9, // subdomains included
+ k1pHSTSSpoofable = 10, // HSTS and neither host cookie nor
+ k3pHSTSSpoofable = 11, // subdomains included
+ k1pSecureConnection = 12, // Secure connection but no HSTS
+ k3pSecureConnection = 13, // "
+ k1pNonsecureConnection = 14, // Nonsecure connection
+ k3pNonsecureConnection = 15, // "
+ kCount
+};
+
+} // namespace net
+
+#endif // NET_URL_REQUEST_URL_REQUEST_HTTP_JOB_HISTOGRAM_H_ \ No newline at end of file
diff --git a/chromium/net/url_request/url_request_http_job_unittest.cc b/chromium/net/url_request/url_request_http_job_unittest.cc
index 73d11c14c33..7c601a7ab0a 100644
--- a/chromium/net/url_request/url_request_http_job_unittest.cc
+++ b/chromium/net/url_request/url_request_http_job_unittest.cc
@@ -29,7 +29,8 @@
#include "net/log/test_net_log.h"
#include "net/log/test_net_log_entry.h"
#include "net/log/test_net_log_util.h"
-#include "net/net_features.h"
+#include "net/net_buildflags.h"
+#include "net/socket/next_proto.h"
#include "net/socket/socket_test_util.h"
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
@@ -39,7 +40,7 @@
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_status.h"
#include "net/url_request/url_request_test_util.h"
-#include "net/websockets/websocket_handshake_stream_base.h"
+#include "net/url_request/websocket_handshake_userdata_key.h"
#include "net/websockets/websocket_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -261,7 +262,7 @@ TEST(URLRequestHttpJobWithProxy, TestSuccessfulWithOneProxy) {
std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
ProxyResolutionService::CreateFixedFromPacResult(
- proxy_server.ToPacString());
+ proxy_server.ToPacString(), TRAFFIC_ANNOTATION_FOR_TESTS);
MockWrite writes[] = {MockWrite(kSimpleProxyGetMockWrite)};
MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET)};
@@ -310,7 +311,8 @@ TEST(URLRequestHttpJobWithProxy,
std::unique_ptr<ProxyResolutionService> proxy_resolution_service =
ProxyResolutionService::CreateFixedFromPacResult(
proxy_server.ToPacString() + "; " +
- ProxyServer::Direct().ToPacString());
+ ProxyServer::Direct().ToPacString(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
MockWrite writes[] = {MockWrite(kSimpleGetMockWrite)};
MockRead reads[] = {MockRead("HTTP/1.1 200 OK\r\n"
@@ -1581,7 +1583,7 @@ TEST_F(URLRequestHttpJobWebSocketTest, CreateHelperPassedThrough) {
auto websocket_stream_create_helper =
std::make_unique<TestWebSocketHandshakeStreamCreateHelper>();
- req_->SetUserData(WebSocketHandshakeStreamBase::CreateHelper::DataKey(),
+ req_->SetUserData(kWebSocketHandshakeUserDataKey,
std::move(websocket_stream_create_helper));
req_->SetLoadFlags(LOAD_DISABLE_CACHE);
req_->Start();
diff --git a/chromium/net/url_request/url_request_job_manager.cc b/chromium/net/url_request/url_request_job_manager.cc
index 0817a128ecc..ab244be6bb0 100644
--- a/chromium/net/url_request/url_request_job_manager.cc
+++ b/chromium/net/url_request/url_request_job_manager.cc
@@ -7,12 +7,12 @@
#include <algorithm>
#include "base/memory/singleton.h"
-#include "build/build_config.h"
#include "base/strings/string_util.h"
+#include "build/build_config.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/network_delegate.h"
-#include "net/net_features.h"
+#include "net/net_buildflags.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_error_job.h"
#include "net/url_request/url_request_http_job.h"
diff --git a/chromium/net/url_request/url_request_test_util.h b/chromium/net/url_request/url_request_test_util.h
index a8bf758c197..6906d38c1f7 100644
--- a/chromium/net/url_request/url_request_test_util.h
+++ b/chromium/net/url_request/url_request_test_util.h
@@ -35,7 +35,7 @@
#include "net/http/http_network_layer.h"
#include "net/http/http_network_session.h"
#include "net/http/http_request_headers.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
diff --git a/chromium/net/url_request/url_request_throttler_test_support.cc b/chromium/net/url_request/url_request_throttler_test_support.cc
index d1ef6ca0c9c..530612bae60 100644
--- a/chromium/net/url_request/url_request_throttler_test_support.cc
+++ b/chromium/net/url_request/url_request_throttler_test_support.cc
@@ -14,7 +14,7 @@ TestTickClock::TestTickClock(base::TimeTicks now) : now_ticks_(now) {}
TestTickClock::~TestTickClock() = default;
-base::TimeTicks TestTickClock::NowTicks() {
+base::TimeTicks TestTickClock::NowTicks() const {
return now_ticks_;
}
diff --git a/chromium/net/url_request/url_request_throttler_test_support.h b/chromium/net/url_request/url_request_throttler_test_support.h
index 93e4e2a39ba..80f33836017 100644
--- a/chromium/net/url_request/url_request_throttler_test_support.h
+++ b/chromium/net/url_request/url_request_throttler_test_support.h
@@ -20,7 +20,7 @@ class TestTickClock : public base::TickClock {
explicit TestTickClock(base::TimeTicks now);
~TestTickClock() override;
- base::TimeTicks NowTicks() override;
+ base::TimeTicks NowTicks() const override;
void set_now(base::TimeTicks now) { now_ticks_ = now; }
private:
diff --git a/chromium/net/url_request/url_request_unittest.cc b/chromium/net/url_request/url_request_unittest.cc
index a7bb6637d42..ff80637d224 100644
--- a/chromium/net/url_request/url_request_unittest.cc
+++ b/chromium/net/url_request/url_request_unittest.cc
@@ -88,8 +88,8 @@
#include "net/log/test_net_log.h"
#include "net/log/test_net_log_entry.h"
#include "net/log/test_net_log_util.h"
-#include "net/net_features.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/net_buildflags.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/quic/chromium/mock_crypto_client_stream_factory.h"
#include "net/quic/chromium/quic_server_info.h"
#include "net/socket/socket_test_util.h"
@@ -115,6 +115,7 @@
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_http_job.h"
+#include "net/url_request/url_request_http_job_histogram.h"
#include "net/url_request/url_request_intercepting_job_factory.h"
#include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job_factory_impl.h"
@@ -422,18 +423,8 @@ class BlockingNetworkDelegate : public TestNetworkDelegate {
USER_CALLBACK, // User takes care of doing a callback. |retval_| and
// |auth_retval_| are ignored. In every blocking stage the
// message loop is quit.
- USER_NOTIFY, // User is notified by a provided callback of the
- // blocking, and synchronously returns instructions
- // for handling it.
};
- using NotificationCallback =
- base::Callback<Error(const CompletionCallback&, const URLRequest*)>;
-
- using NotificationAuthCallback =
- base::Callback<NetworkDelegate::AuthRequiredResponse(const AuthCallback&,
- const URLRequest*)>;
-
// Creates a delegate which does not block at all.
explicit BlockingNetworkDelegate(BlockMode block_mode);
@@ -470,17 +461,6 @@ class BlockingNetworkDelegate : public TestNetworkDelegate {
block_on_ = block_on;
}
- // Only valid if |block_mode_| == USER_NOTIFY
- void set_notification_callback(
- const NotificationCallback& notification_callback) {
- notification_callback_ = notification_callback;
- }
-
- void set_notification_auth_callback(
- const NotificationAuthCallback& notification_auth_callback) {
- notification_auth_callback_ = notification_auth_callback;
- }
-
// Allows the user to check in which state did we block.
Stage stage_blocked_for_callback() const {
EXPECT_EQ(USER_CALLBACK, block_mode_);
@@ -520,7 +500,6 @@ class BlockingNetworkDelegate : public TestNetworkDelegate {
// Checks whether we should block in |stage|. If yes, returns an error code
// and optionally sets up callback based on |block_mode_|. If no, returns OK.
int MaybeBlockStage(Stage stage,
- const URLRequest* request,
const CompletionCallback& callback);
// Configuration parameters, can be adjusted by public methods:
@@ -548,10 +527,6 @@ class BlockingNetworkDelegate : public TestNetworkDelegate {
CompletionCallback callback_;
AuthCallback auth_callback_;
- // Callback to request user instructions for blocking.
- NotificationCallback notification_callback_;
- NotificationAuthCallback notification_auth_callback_;
-
base::WeakPtrFactory<BlockingNetworkDelegate> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(BlockingNetworkDelegate);
@@ -611,7 +586,7 @@ int BlockingNetworkDelegate::OnBeforeURLRequest(
if (!redirect_url_.is_empty())
*new_url = redirect_url_;
- return MaybeBlockStage(ON_BEFORE_URL_REQUEST, request, callback);
+ return MaybeBlockStage(ON_BEFORE_URL_REQUEST, callback);
}
int BlockingNetworkDelegate::OnBeforeStartTransaction(
@@ -620,7 +595,7 @@ int BlockingNetworkDelegate::OnBeforeStartTransaction(
HttpRequestHeaders* headers) {
TestNetworkDelegate::OnBeforeStartTransaction(request, callback, headers);
- return MaybeBlockStage(ON_BEFORE_SEND_HEADERS, request, callback);
+ return MaybeBlockStage(ON_BEFORE_SEND_HEADERS, callback);
}
int BlockingNetworkDelegate::OnHeadersReceived(
@@ -635,7 +610,7 @@ int BlockingNetworkDelegate::OnHeadersReceived(
override_response_headers,
allowed_unsafe_redirect_url);
- return MaybeBlockStage(ON_HEADERS_RECEIVED, request, callback);
+ return MaybeBlockStage(ON_HEADERS_RECEIVED, callback);
}
NetworkDelegate::AuthRequiredResponse BlockingNetworkDelegate::OnAuthRequired(
@@ -673,11 +648,6 @@ NetworkDelegate::AuthRequiredResponse BlockingNetworkDelegate::OnAuthRequired(
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
return AUTH_REQUIRED_RESPONSE_IO_PENDING;
-
- case USER_NOTIFY:
- // If the callback returns ERR_IO_PENDING, the user has accepted
- // responsibility for running the callback in the future.
- return notification_auth_callback_.Run(callback, request);
}
NOTREACHED();
return AUTH_REQUIRED_RESPONSE_NO_ACTION; // Dummy value.
@@ -692,7 +662,6 @@ void BlockingNetworkDelegate::Reset() {
int BlockingNetworkDelegate::MaybeBlockStage(
BlockingNetworkDelegate::Stage stage,
- const URLRequest* request,
const CompletionCallback& callback) {
// Check that the user has provided callback for the previous blocked stage.
EXPECT_EQ(NOT_BLOCKED, stage_blocked_for_callback_);
@@ -718,11 +687,6 @@ int BlockingNetworkDelegate::MaybeBlockStage(
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
return ERR_IO_PENDING;
-
- case USER_NOTIFY:
- // If the callback returns ERR_IO_PENDING, the user has accepted
- // responsibility for running the callback in the future.
- return notification_callback_.Run(callback, request);
}
NOTREACHED();
return 0;
@@ -735,7 +699,8 @@ class TestURLRequestContextWithProxy : public TestURLRequestContext {
NetworkDelegate* delegate)
: TestURLRequestContext(true) {
context_storage_.set_proxy_resolution_service(
- ProxyResolutionService::CreateFixed(proxy));
+ ProxyResolutionService::CreateFixed(proxy,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
set_network_delegate(delegate);
Init();
}
@@ -3155,6 +3120,7 @@ TEST_F(URLRequestTest, SecureCookiePrefixNonsecure) {
TRAFFIC_ANNOTATION_FOR_TESTS));
req->Start();
base::RunLoop().Run();
+ EXPECT_EQ(0, network_delegate.set_cookie_count());
EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
}
@@ -3296,73 +3262,473 @@ TEST_F(URLRequestTest, StrictSecureCookiesOnSecureOrigin) {
}
}
-TEST_F(URLRequestTest, CookieAgeMetrics) {
+// The parameter is true for same-site and false for cross-site requests.
+class URLRequestTestParameterizedSameSite
+ : public URLRequestTest,
+ public ::testing::WithParamInterface<bool> {
+ protected:
+ URLRequestTestParameterizedSameSite() {
+ auto params = std::make_unique<HttpNetworkSession::Params>();
+ params->ignore_certificate_errors = true;
+ context_.set_http_network_session_params(std::move(params));
+ context_.set_network_delegate(&network_delegate_);
+ https_server_.AddDefaultHandlers(
+ base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ EXPECT_TRUE(https_server_.Start());
+ }
+
+ // To be called after configuration of |context_| has been finalized.
+ void InitContext() { context_.Init(); }
+
+ const std::string kHost_ = "example.test";
+ const std::string kCrossHost_ = "cross-site.test";
+ TestURLRequestContext context_{true};
+ TestNetworkDelegate network_delegate_;
+ base::HistogramTester histograms_;
+ EmbeddedTestServer https_server_{EmbeddedTestServer::TYPE_HTTPS};
+};
+
+INSTANTIATE_TEST_CASE_P(URLRequestTest,
+ URLRequestTestParameterizedSameSite,
+ ::testing::Bool());
+
+TEST_P(URLRequestTestParameterizedSameSite, CookieAgeMetrics) {
+ const bool same_site = GetParam();
+ const std::string kInitiatingHost = same_site ? kHost_ : kCrossHost_;
+ InitContext();
+
EmbeddedTestServer http_server;
http_server.AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
- EmbeddedTestServer https_server(EmbeddedTestServer::TYPE_HTTPS);
- https_server.AddDefaultHandlers(
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
ASSERT_TRUE(http_server.Start());
- ASSERT_TRUE(https_server.Start());
- TestNetworkDelegate network_delegate;
- default_context_.set_network_delegate(&network_delegate);
- base::HistogramTester histograms;
+ // Set two test cookies.
+ {
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ http_server.GetURL(kHost_, "/set-cookie?cookie=value&cookie2=value2"),
+ DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->Start();
+ base::RunLoop().Run();
+ ASSERT_EQ(2, network_delegate_.set_cookie_count());
+ histograms_.ExpectTotalCount("Cookie.AgeForNonSecureCrossSiteRequest", 0);
+ histograms_.ExpectTotalCount("Cookie.AgeForNonSecureSameSiteRequest", 0);
+ histograms_.ExpectTotalCount("Cookie.AgeForSecureCrossSiteRequest", 0);
+ histograms_.ExpectTotalCount("Cookie.AgeForSecureSameSiteRequest", 0);
+ histograms_.ExpectTotalCount("Cookie.AllAgesForNonSecureCrossSiteRequest",
+ 0);
+ histograms_.ExpectTotalCount("Cookie.AllAgesForNonSecureSameSiteRequest",
+ 0);
+ histograms_.ExpectTotalCount("Cookie.AllAgesForSecureCrossSiteRequest", 0);
+ histograms_.ExpectTotalCount("Cookie.AllAgesForSecureSameSiteRequest", 0);
+ }
- const std::string kHost = "example.test";
- const std::string kCrossHost = "cross-origin.test";
+ // Make a secure request.
+ {
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ https_server_.GetURL(kHost_, "/echoheader?Cookie"), DEFAULT_PRIORITY,
+ &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->set_site_for_cookies(https_server_.GetURL(kInitiatingHost, "/"));
+ req->set_initiator(
+ url::Origin::Create(https_server_.GetURL(kInitiatingHost, "/")));
+ req->Start();
+ base::RunLoop().Run();
+ histograms_.ExpectTotalCount("Cookie.AgeForNonSecureCrossSiteRequest", 0);
+ histograms_.ExpectTotalCount("Cookie.AgeForNonSecureSameSiteRequest", 0);
+ histograms_.ExpectTotalCount("Cookie.AgeForSecureCrossSiteRequest",
+ !same_site);
+ histograms_.ExpectTotalCount("Cookie.AgeForSecureSameSiteRequest",
+ same_site);
+ histograms_.ExpectTotalCount("Cookie.AllAgesForNonSecureCrossSiteRequest",
+ 0);
+ histograms_.ExpectTotalCount("Cookie.AllAgesForNonSecureSameSiteRequest",
+ 0);
+ histograms_.ExpectTotalCount("Cookie.AllAgesForSecureCrossSiteRequest",
+ same_site ? 0 : 2);
+ histograms_.ExpectTotalCount("Cookie.AllAgesForSecureSameSiteRequest",
+ same_site ? 2 : 0);
+ EXPECT_TRUE(d.data_received().find("cookie=value") != std::string::npos);
+ EXPECT_TRUE(d.data_received().find("cookie2=value2") != std::string::npos);
+ }
+
+ // Make a non-secure request.
+ {
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ http_server.GetURL(kHost_, "/echoheader?Cookie"), DEFAULT_PRIORITY, &d,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->set_site_for_cookies(http_server.GetURL(kInitiatingHost, "/"));
+ req->set_initiator(
+ url::Origin::Create(http_server.GetURL(kInitiatingHost, "/")));
+ req->Start();
+ base::RunLoop().Run();
+ histograms_.ExpectTotalCount("Cookie.AgeForNonSecureCrossSiteRequest",
+ !same_site);
+ histograms_.ExpectTotalCount("Cookie.AgeForNonSecureSameSiteRequest",
+ same_site);
+ histograms_.ExpectTotalCount("Cookie.AgeForSecureCrossSiteRequest",
+ !same_site);
+ histograms_.ExpectTotalCount("Cookie.AgeForSecureSameSiteRequest",
+ same_site);
+ histograms_.ExpectTotalCount("Cookie.AllAgesForNonSecureCrossSiteRequest",
+ same_site ? 0 : 2);
+ histograms_.ExpectTotalCount("Cookie.AllAgesForNonSecureSameSiteRequest",
+ same_site ? 2 : 0);
+ histograms_.ExpectTotalCount("Cookie.AllAgesForSecureCrossSiteRequest",
+ same_site ? 0 : 2);
+ histograms_.ExpectTotalCount("Cookie.AllAgesForSecureSameSiteRequest",
+ same_site ? 2 : 0);
+ EXPECT_TRUE(d.data_received().find("cookie=value") != std::string::npos);
+ EXPECT_TRUE(d.data_received().find("cookie2=value2") != std::string::npos);
+ }
+}
+
+// Cookies with secure attribute (no HSTS) --> k1pSecureAttribute
+TEST_P(URLRequestTestParameterizedSameSite,
+ CookieNetworkSecurityMetricSecureAttribute) {
+ const bool same_site = GetParam();
+ const std::string kInitiatingHost = same_site ? kHost_ : kCrossHost_;
+ InitContext();
+
+ // Set cookies.
+ {
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ https_server_.GetURL(kHost_,
+ "/set-cookie?session-cookie=value;Secure&"
+ "longlived-cookie=value;Secure;domain=" +
+ kHost_ + ";Max-Age=360000"),
+ DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->Start();
+ base::RunLoop().Run();
+ ASSERT_EQ(2, network_delegate_.set_cookie_count());
+ histograms_.ExpectTotalCount("Cookie.NetworkSecurity", 0);
+ }
- // Set a test cookie.
+ // Verify that the cookies fall into the correct metrics bucket.
{
TestDelegate d;
- std::unique_ptr<URLRequest> req(default_context_.CreateRequest(
- http_server.GetURL(kHost, "/set-cookie?cookie=value"), DEFAULT_PRIORITY,
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ https_server_.GetURL(kHost_, "/echoheader?Cookie"), DEFAULT_PRIORITY,
&d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->set_site_for_cookies(https_server_.GetURL(kInitiatingHost, "/"));
+ req->set_initiator(url::Origin::Create(https_server_.GetURL(kHost_, "/")));
req->Start();
base::RunLoop().Run();
- ASSERT_EQ(1, network_delegate.set_cookie_count());
+ histograms_.ExpectTotalCount("Cookie.NetworkSecurity", 2);
+ // Static cast of boolean required for MSVC 1911.
+ histograms_.ExpectBucketCount(
+ "Cookie.NetworkSecurity",
+ static_cast<int>(CookieNetworkSecurity::k1pSecureAttribute) |
+ static_cast<int>(!same_site),
+ 2);
}
+}
+
+// Short-lived host cookie --> k1pHSTSHostCookie
+TEST_P(URLRequestTestParameterizedSameSite,
+ CookieNetworkSecurityMetricShortlivedHostCookie) {
+ const bool same_site = GetParam();
+ const std::string kInitiatingHost = same_site ? kHost_ : kCrossHost_;
- // Make a secure request to `example.test`: we shouldn't record data.
+ TransportSecurityState transport_security_state;
+ transport_security_state.AddHSTS(
+ kHost_, base::Time::Now() + base::TimeDelta::FromHours(10),
+ false /* include_subdomains */);
+ context_.set_transport_security_state(&transport_security_state);
+ InitContext();
+
+ // Set cookie.
{
TestDelegate d;
- std::unique_ptr<URLRequest> req(default_context_.CreateRequest(
- https_server.GetURL(kHost, "/echoheader?Cookie"), DEFAULT_PRIORITY, &d,
- TRAFFIC_ANNOTATION_FOR_TESTS));
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ https_server_.GetURL(kHost_, "/set-cookie?cookie=value;Max-Age=3600"),
+ DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
req->Start();
base::RunLoop().Run();
- histograms.ExpectTotalCount("Cookie.AgeForNonSecureCrossSiteRequest", 0);
- histograms.ExpectTotalCount("Cookie.AgeForNonSecureSameSiteRequest", 0);
+ ASSERT_EQ(1, network_delegate_.set_cookie_count());
+ histograms_.ExpectTotalCount("Cookie.NetworkSecurity", 0);
}
- // Make a non-secure same-site request.
+ // Verify that the cookie falls into the correct metrics bucket.
{
TestDelegate d;
- std::unique_ptr<URLRequest> req(default_context_.CreateRequest(
- http_server.GetURL(kHost, "/echoheader?Cookie"), DEFAULT_PRIORITY, &d,
- TRAFFIC_ANNOTATION_FOR_TESTS));
- req->set_site_for_cookies(http_server.GetURL(kHost, "/"));
- req->set_initiator(url::Origin::Create(http_server.GetURL(kHost, "/")));
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ https_server_.GetURL(kHost_, "/echoheader?Cookie"), DEFAULT_PRIORITY,
+ &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->set_site_for_cookies(https_server_.GetURL(kInitiatingHost, "/"));
+ req->set_initiator(url::Origin::Create(https_server_.GetURL(kHost_, "/")));
+ req->Start();
+ base::RunLoop().Run();
+ histograms_.ExpectTotalCount("Cookie.NetworkSecurity", 1);
+ // Static cast of boolean required for MSVC 1911.
+ histograms_.ExpectBucketCount(
+ "Cookie.NetworkSecurity",
+ static_cast<int>(CookieNetworkSecurity::k1pHSTSHostCookie) |
+ static_cast<int>(!same_site),
+ 1);
+ }
+}
+
+// Long-lived (either due to expiry or due to being a session cookie) host
+// cookies --> k1pExpiringHSTSHostCookie
+TEST_P(URLRequestTestParameterizedSameSite,
+ CookieNetworkSecurityMetricLonglivedHostCookie) {
+ const bool same_site = GetParam();
+ const std::string kInitiatingHost = same_site ? kHost_ : kCrossHost_;
+
+ TransportSecurityState transport_security_state;
+ transport_security_state.AddHSTS(
+ kHost_, base::Time::Now() + base::TimeDelta::FromHours(10),
+ false /* include_subdomains */);
+ context_.set_transport_security_state(&transport_security_state);
+ InitContext();
+
+ // Set cookies.
+ {
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ https_server_.GetURL(kHost_,
+ "/set-cookie?session-cookie=value&"
+ "longlived-cookie=value;Max-Age=360000"),
+ DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
req->Start();
base::RunLoop().Run();
- histograms.ExpectTotalCount("Cookie.AgeForNonSecureCrossSiteRequest", 0);
- histograms.ExpectTotalCount("Cookie.AgeForNonSecureSameSiteRequest", 1);
+ ASSERT_EQ(2, network_delegate_.set_cookie_count());
+ histograms_.ExpectTotalCount("Cookie.NetworkSecurity", 0);
}
- // Make a non-secure cross-site request.
+ // Verify that the cookies fall into the correct metrics bucket.
{
TestDelegate d;
- std::unique_ptr<URLRequest> req(default_context_.CreateRequest(
- http_server.GetURL(kHost, "/echoheader?Cookie"), DEFAULT_PRIORITY, &d,
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ https_server_.GetURL(kHost_, "/echoheader?Cookie"), DEFAULT_PRIORITY,
+ &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->set_site_for_cookies(https_server_.GetURL(kInitiatingHost, "/"));
+ req->set_initiator(url::Origin::Create(https_server_.GetURL(kHost_, "/")));
+ req->Start();
+ base::RunLoop().Run();
+ histograms_.ExpectTotalCount("Cookie.NetworkSecurity", 2);
+ // Static cast of boolean required for MSVC 1911.
+ histograms_.ExpectBucketCount(
+ "Cookie.NetworkSecurity",
+ static_cast<int>(CookieNetworkSecurity::k1pExpiringHSTSHostCookie) |
+ static_cast<int>(!same_site),
+ 2);
+ }
+}
+
+// Domain cookie with HSTS subdomains with cookie expiry before HSTS expiry -->
+// k1pHSTSSubdomainsIncluded
+TEST_P(URLRequestTestParameterizedSameSite,
+ CookieNetworkSecurityMetricShortlivedDomainCookie) {
+ const bool same_site = GetParam();
+ const std::string kInitiatingHost = same_site ? kHost_ : kCrossHost_;
+
+ TransportSecurityState transport_security_state;
+ transport_security_state.AddHSTS(
+ kHost_, base::Time::Now() + base::TimeDelta::FromHours(10),
+ true /* include_subdomains */);
+ context_.set_transport_security_state(&transport_security_state);
+ InitContext();
+
+ // Set cookie.
+ {
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ https_server_.GetURL(kHost_, "/set-cookie?cookie=value;domain=" +
+ kHost_ + ";Max-Age=3600"),
+ DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->Start();
+ base::RunLoop().Run();
+ ASSERT_EQ(1, network_delegate_.set_cookie_count());
+ histograms_.ExpectTotalCount("Cookie.NetworkSecurity", 0);
+ }
+
+ // Verify that the cookie falls into the correct metrics bucket.
+ {
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ https_server_.GetURL(kHost_, "/echoheader?Cookie"), DEFAULT_PRIORITY,
+ &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->set_site_for_cookies(https_server_.GetURL(kInitiatingHost, "/"));
+ req->set_initiator(url::Origin::Create(https_server_.GetURL(kHost_, "/")));
+ req->Start();
+ base::RunLoop().Run();
+ histograms_.ExpectTotalCount("Cookie.NetworkSecurity", 1);
+ // Static cast of boolean required for MSVC 1911.
+ histograms_.ExpectBucketCount(
+ "Cookie.NetworkSecurity",
+ static_cast<int>(CookieNetworkSecurity::k1pHSTSSubdomainsIncluded) |
+ static_cast<int>(!same_site),
+ 1);
+ }
+}
+
+// Long-lived (either due to expiry or due to being a session cookie) domain
+// cookies with HSTS subdomains --> k1pExpiringHSTSSubdomainsIncluded
+TEST_P(URLRequestTestParameterizedSameSite,
+ CookieNetworkSecurityMetricLonglivedDomainCookie) {
+ const bool same_site = GetParam();
+ const std::string kInitiatingHost = same_site ? kHost_ : kCrossHost_;
+
+ TransportSecurityState transport_security_state;
+ transport_security_state.AddHSTS(
+ kHost_, base::Time::Now() + base::TimeDelta::FromHours(10),
+ true /* include_subdomains */);
+ context_.set_transport_security_state(&transport_security_state);
+ InitContext();
+
+ // Set cookies.
+ {
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ https_server_.GetURL(
+ kHost_, "/set-cookie?session-cookie=value;domain=" + kHost_ + "&" +
+ "longlived-cookie=value;domain=" + kHost_ +
+ ";Max-Age=360000"),
+ DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->Start();
+ base::RunLoop().Run();
+ ASSERT_EQ(2, network_delegate_.set_cookie_count());
+ histograms_.ExpectTotalCount("Cookie.NetworkSecurity", 0);
+ }
+
+ // Verify that the cookies fall into the correct metrics bucket.
+ {
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ https_server_.GetURL(kHost_, "/echoheader?Cookie"), DEFAULT_PRIORITY,
+ &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->set_site_for_cookies(https_server_.GetURL(kInitiatingHost, "/"));
+ req->set_initiator(url::Origin::Create(https_server_.GetURL(kHost_, "/")));
+ req->Start();
+ base::RunLoop().Run();
+ histograms_.ExpectTotalCount("Cookie.NetworkSecurity", 2);
+ // Static cast of boolean required for MSVC 1911.
+ histograms_.ExpectBucketCount(
+ "Cookie.NetworkSecurity",
+ static_cast<int>(
+ CookieNetworkSecurity::k1pExpiringHSTSSubdomainsIncluded) |
+ static_cast<int>(!same_site),
+ 2);
+ }
+}
+
+// Domain cookie with HSTS subdomains not included --> k1pHSTSSpoofable
+TEST_P(URLRequestTestParameterizedSameSite,
+ CookieNetworkSecurityMetricSpoofableDomainCookie) {
+ const bool same_site = GetParam();
+ const std::string kInitiatingHost = same_site ? kHost_ : kCrossHost_;
+
+ TransportSecurityState transport_security_state;
+ transport_security_state.AddHSTS(
+ kHost_, base::Time::Now() + base::TimeDelta::FromHours(10),
+ false /* include_subdomains */);
+ context_.set_transport_security_state(&transport_security_state);
+ InitContext();
+
+ // Set cookie.
+ {
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ https_server_.GetURL(kHost_, "/set-cookie?cookie=value;domain=" +
+ kHost_ + ";Max-Age=3600"),
+ DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->Start();
+ base::RunLoop().Run();
+ ASSERT_EQ(1, network_delegate_.set_cookie_count());
+ histograms_.ExpectTotalCount("Cookie.NetworkSecurity", 0);
+ }
+
+ // Verify that the cookie falls into the correct metrics bucket.
+ {
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ https_server_.GetURL(kHost_, "/echoheader?Cookie"), DEFAULT_PRIORITY,
+ &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->set_site_for_cookies(https_server_.GetURL(kInitiatingHost, "/"));
+ req->set_initiator(url::Origin::Create(https_server_.GetURL(kHost_, "/")));
+ req->Start();
+ base::RunLoop().Run();
+ histograms_.ExpectTotalCount("Cookie.NetworkSecurity", 1);
+ // Static cast of boolean required for MSVC 1911.
+ histograms_.ExpectBucketCount(
+ "Cookie.NetworkSecurity",
+ static_cast<int>(CookieNetworkSecurity::k1pHSTSSpoofable) |
+ static_cast<int>(!same_site),
+ 1);
+ }
+}
+
+// Cookie without HSTS --> k1p(Non)SecureConnection
+TEST_P(URLRequestTestParameterizedSameSite, CookieNetworkSecurityMetricNoHSTS) {
+ const bool same_site = GetParam();
+ const std::string kInitiatingHost = same_site ? kHost_ : kCrossHost_;
+ InitContext();
+
+ EmbeddedTestServer http_server;
+ http_server.AddDefaultHandlers(
+ base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
+ ASSERT_TRUE(http_server.Start());
+
+ // Set cookies.
+ {
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ https_server_.GetURL(kHost_,
+ "/set-cookie?cookie=value;domain=" + kHost_ +
+ ";Max-Age=3600&host-cookie=value"),
+ DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->Start();
+ base::RunLoop().Run();
+ ASSERT_EQ(2, network_delegate_.set_cookie_count());
+ histograms_.ExpectTotalCount("Cookie.NetworkSecurity", 0);
+ }
+
+ // Verify that the cookie falls into the correct metrics bucket.
+ {
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ https_server_.GetURL(kHost_, "/echoheader?Cookie"), DEFAULT_PRIORITY,
+ &d, TRAFFIC_ANNOTATION_FOR_TESTS));
+ req->set_site_for_cookies(https_server_.GetURL(kInitiatingHost, "/"));
+ req->set_initiator(url::Origin::Create(https_server_.GetURL(kHost_, "/")));
+ req->Start();
+ base::RunLoop().Run();
+ histograms_.ExpectTotalCount("Cookie.NetworkSecurity", 2);
+ // Static cast of boolean required for MSVC 1911.
+ histograms_.ExpectBucketCount(
+ "Cookie.NetworkSecurity",
+ static_cast<int>(CookieNetworkSecurity::k1pSecureConnection) |
+ static_cast<int>(!same_site),
+ 2);
+ }
+
+ // Verify that the cookie falls into the correct metrics bucket.
+ {
+ TestDelegate d;
+ std::unique_ptr<URLRequest> req(context_.CreateRequest(
+ http_server.GetURL(kHost_, "/echoheader?Cookie"), DEFAULT_PRIORITY, &d,
TRAFFIC_ANNOTATION_FOR_TESTS));
- req->set_site_for_cookies(http_server.GetURL(kCrossHost, "/"));
- req->set_initiator(
- url::Origin::Create(http_server.GetURL(kCrossHost, "/")));
+ req->set_site_for_cookies(https_server_.GetURL(kInitiatingHost, "/"));
+ req->set_initiator(url::Origin::Create(https_server_.GetURL(kHost_, "/")));
req->Start();
base::RunLoop().Run();
- histograms.ExpectTotalCount("Cookie.AgeForNonSecureCrossSiteRequest", 1);
- histograms.ExpectTotalCount("Cookie.AgeForNonSecureSameSiteRequest", 1);
+ histograms_.ExpectTotalCount("Cookie.NetworkSecurity", 4);
+ // Static cast of boolean required for MSVC 1911.
+ histograms_.ExpectBucketCount(
+ "Cookie.NetworkSecurity",
+ static_cast<int>(CookieNetworkSecurity::k1pSecureConnection) |
+ static_cast<int>(!same_site),
+ 2);
+ // Static cast of boolean required for MSVC 1911.
+ histograms_.ExpectBucketCount(
+ "Cookie.NetworkSecurity",
+ static_cast<int>(CookieNetworkSecurity::k1pNonsecureConnection) |
+ static_cast<int>(!same_site),
+ 2);
}
}
@@ -3722,12 +4088,10 @@ std::unique_ptr<test_server::HttpResponse> HandleRedirectConnect(
class TestSSLConfigService : public SSLConfigService {
public:
- TestSSLConfigService(bool ev_enabled,
- bool online_rev_checking,
+ TestSSLConfigService(bool online_rev_checking,
bool rev_checking_required_local_anchors,
bool token_binding_enabled)
- : ev_enabled_(ev_enabled),
- online_rev_checking_(online_rev_checking),
+ : online_rev_checking_(online_rev_checking),
rev_checking_required_local_anchors_(
rev_checking_required_local_anchors),
token_binding_enabled_(token_binding_enabled),
@@ -3741,7 +4105,6 @@ class TestSSLConfigService : public SSLConfigService {
void GetSSLConfig(SSLConfig* config) override {
*config = SSLConfig();
config->rev_checking_enabled = online_rev_checking_;
- config->verify_ev_cert = ev_enabled_;
config->rev_checking_required_local_anchors =
rev_checking_required_local_anchors_;
config->version_min = min_version_;
@@ -3755,7 +4118,6 @@ class TestSSLConfigService : public SSLConfigService {
~TestSSLConfigService() override = default;
private:
- const bool ev_enabled_;
const bool online_rev_checking_;
const bool rev_checking_required_local_anchors_;
const bool token_binding_enabled_;
@@ -3771,7 +4133,7 @@ class TokenBindingURLRequestTest : public URLRequestTestHTTP {
void SetUp() override {
default_context_.set_ssl_config_service(
- new TestSSLConfigService(false, false, false, true));
+ new TestSSLConfigService(false, false, true));
channel_id_service_.reset(
new ChannelIDService(new DefaultChannelIDStore(NULL)));
default_context_.set_channel_id_service(channel_id_service_.get());
@@ -7070,7 +7432,8 @@ class TestReportingService : public ReportingService {
void QueueReport(const GURL& url,
const std::string& group,
const std::string& type,
- std::unique_ptr<const base::Value> body) override {
+ std::unique_ptr<const base::Value> body,
+ int depth) override {
NOTIMPLEMENTED();
}
@@ -7085,9 +7448,9 @@ class TestReportingService : public ReportingService {
NOTIMPLEMENTED();
}
- bool RequestIsUpload(const URLRequest& request) override {
+ int GetUploadDepth(const URLRequest& request) override {
NOTIMPLEMENTED();
- return true;
+ return 0;
}
const ReportingPolicy& GetPolicy() const override {
@@ -8866,290 +9229,6 @@ TEST_F(URLRequestTestHTTP, ThrottledPriority) {
EXPECT_TRUE(req->status().is_success());
}
-// A class to hold state for responding to USER_NOTIFY callbacks from
-// BlockingNetworkDelegate. It also accepts a RunLoop that will be
-// signaled via QuitWhenIdle() when any request is blocked.
-//
-class NotificationCallbackHandler {
- public:
- // Default constructed object doesn't block anything.
- NotificationCallbackHandler() : run_loop_(nullptr) {}
-
- void AddURLRequestToBlockList(const URLRequest* request) {
- requests_to_block_.insert(request);
- }
-
- Error ShouldBlockRequest(const CompletionCallback& callback,
- const URLRequest* request) {
- if (requests_to_block_.find(request) == requests_to_block_.end()) {
- return OK;
- }
-
- DCHECK(blocked_callbacks_.find(request) == blocked_callbacks_.end());
- blocked_callbacks_[request] = callback;
- if (run_loop_ && blocked_callbacks_.size() == requests_to_block_.size())
- run_loop_->QuitWhenIdle();
- return ERR_IO_PENDING;
- }
-
- // Erases object's memory of blocked callbacks as a side effect.
- void GetBlockedCallbacks(
- std::map<const URLRequest*, CompletionCallback>* blocked_callbacks) {
- blocked_callbacks_.swap(*blocked_callbacks);
- }
-
- // Set a RunLoop that, if non-null, will be signaled if any request
- // is blocked. It is the callers responsibility to make sure the
- // passed object lives past the destruction of this class or
- // next call to SetRunLoop().
- void SetRunLoop(base::RunLoop* run_loop) { run_loop_ = run_loop; }
-
- private:
- std::set<const URLRequest*> requests_to_block_;
- std::map<const URLRequest*, CompletionCallback> blocked_callbacks_;
-
- base::RunLoop* run_loop_;
-
- DISALLOW_COPY_AND_ASSIGN(NotificationCallbackHandler);
-};
-
-TEST_F(URLRequestTestHTTP, MultiThrottledPriority) {
- ASSERT_TRUE(http_test_server()->Start());
-
- base::RunLoop run_until_request_blocked;
-
- NotificationCallbackHandler notification_handler;
- notification_handler.SetRunLoop(&run_until_request_blocked);
- BlockingNetworkDelegate network_delegate(
- BlockingNetworkDelegate::USER_NOTIFY);
- network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED);
- network_delegate.set_notification_callback(
- base::Bind(&NotificationCallbackHandler::ShouldBlockRequest,
- // Both objects are owned by this function, and
- // |*network_delegate| will be destroyed first, so
- // it's safe to pass it an unretained pointer.
- base::Unretained(&notification_handler)));
-
- TestURLRequestContext context(true);
- context.set_network_delegate(&network_delegate);
- context.Init();
-
- // Use different test URLs to make sure all three requests turn into
- // HttpNetworkTransacations. Use different URLRequest::Delegates so that
- // the requests may be waited on separately.
- TestDelegate d1;
- std::unique_ptr<URLRequest> req1(
- context.CreateRequest(http_test_server()->GetURL("/echoall/l"), THROTTLED,
- &d1, TRAFFIC_ANNOTATION_FOR_TESTS));
- notification_handler.AddURLRequestToBlockList(req1.get());
-
- TestDelegate d2;
- std::unique_ptr<URLRequest> req2(
- context.CreateRequest(http_test_server()->GetURL("/echoall/2"), THROTTLED,
- &d2, TRAFFIC_ANNOTATION_FOR_TESTS));
- notification_handler.AddURLRequestToBlockList(req2.get());
-
- TestDelegate d3;
- std::unique_ptr<URLRequest> req3(
- context.CreateRequest(http_test_server()->GetURL("/echoall/3"), THROTTLED,
- &d3, TRAFFIC_ANNOTATION_FOR_TESTS));
- req1->Start();
- req2->Start();
- req3->Start();
- run_until_request_blocked.Run();
- notification_handler.SetRunLoop(nullptr);
-
- // The first two requests should be blocked based on the notification
- // callback, and their status should have blocked the third request
- // through throttling.
- EXPECT_TRUE(req1->status().is_io_pending());
- EXPECT_TRUE(req2->status().is_io_pending());
- EXPECT_TRUE(req3->status().is_io_pending());
-
- std::map<const URLRequest*, CompletionCallback> blocked_callbacks;
- notification_handler.GetBlockedCallbacks(&blocked_callbacks);
- ASSERT_EQ(2u, blocked_callbacks.size());
- ASSERT_TRUE(blocked_callbacks.find(req1.get()) != blocked_callbacks.end());
- ASSERT_TRUE(blocked_callbacks.find(req2.get()) != blocked_callbacks.end());
-
- // Unblocking one of the requests blocked on the notification callback
- // should let it complete, which should then let the third request
- // complete. Unblock the second request, then wait for the third
- // request to complete.
- // TODO(rdsmith): Find something to wait on other than the third
- // requests completion; if there's a bug in throttling, that will
- // result in this test hanging rather than failing quickly.
- d1.set_quit_on_complete(false);
- d2.set_quit_on_complete(false);
- d3.set_quit_on_complete(true);
- blocked_callbacks[req2.get()].Run(OK);
- base::RunLoop().Run();
-
- notification_handler.GetBlockedCallbacks(&blocked_callbacks);
- EXPECT_EQ(0u, blocked_callbacks.size());
- EXPECT_TRUE(req1->status().is_io_pending());
- // req3 is only unblocked after req2 completes, so req2's
- // success is guaranteed at this point in the function.
- EXPECT_EQ(URLRequestStatus::SUCCESS, req2->status().status());
- EXPECT_EQ(URLRequestStatus::SUCCESS, req3->status().status());
-}
-
-// Confirm that failing a request unblocks following requests.
-TEST_F(URLRequestTestHTTP, ThrottledFailure) {
- ASSERT_TRUE(http_test_server()->Start());
-
- base::RunLoop run_until_request_blocked;
-
- NotificationCallbackHandler notification_handler;
- notification_handler.SetRunLoop(&run_until_request_blocked);
- BlockingNetworkDelegate network_delegate(
- BlockingNetworkDelegate::USER_NOTIFY);
- network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED);
- network_delegate.set_notification_callback(
- base::Bind(&NotificationCallbackHandler::ShouldBlockRequest,
- // Both objects are owned by this function, and
- // |*network_delegate| will be destroyed first, so
- // it's safe to pass it an unretained pointer.
- base::Unretained(&notification_handler)));
-
- TestURLRequestContext context(true);
- context.set_network_delegate(&network_delegate);
- context.Init();
-
- // Use different test URLs to make sure all three requests turn into
- // HttpNetworkTransacations. Use different URLRequest::Delegates so that
- // the requests may be waited on separately.
- TestDelegate d1;
- std::unique_ptr<URLRequest> req1(
- context.CreateRequest(http_test_server()->GetURL("/echoall/l"), THROTTLED,
- &d1, TRAFFIC_ANNOTATION_FOR_TESTS));
- notification_handler.AddURLRequestToBlockList(req1.get());
-
- TestDelegate d2;
- std::unique_ptr<URLRequest> req2(
- context.CreateRequest(http_test_server()->GetURL("/echoall/2"), THROTTLED,
- &d2, TRAFFIC_ANNOTATION_FOR_TESTS));
- notification_handler.AddURLRequestToBlockList(req2.get());
-
- TestDelegate d3;
- std::unique_ptr<URLRequest> req3(
- context.CreateRequest(http_test_server()->GetURL("/echoall/3"), THROTTLED,
- &d3, TRAFFIC_ANNOTATION_FOR_TESTS));
- req1->Start();
- req2->Start();
- req3->Start();
- run_until_request_blocked.Run();
- notification_handler.SetRunLoop(nullptr);
-
- // The first two requests should be blocked based on the notification
- // callback, and their status should have blocked the third request
- // through throttling.
- EXPECT_TRUE(req1->status().is_io_pending());
- EXPECT_TRUE(req2->status().is_io_pending());
- EXPECT_TRUE(req3->status().is_io_pending());
-
- std::map<const URLRequest*, CompletionCallback> blocked_callbacks;
- notification_handler.GetBlockedCallbacks(&blocked_callbacks);
- ASSERT_EQ(2u, blocked_callbacks.size());
- ASSERT_TRUE(blocked_callbacks.find(req1.get()) != blocked_callbacks.end());
- ASSERT_TRUE(blocked_callbacks.find(req2.get()) != blocked_callbacks.end());
-
- // Confirm canceling one of the outstanding requests allows the
- // blocked request to complete.
-
- // TODO(rdsmith): Find something to wait on other than the third
- // requests completion; if there's a bug in throttling, that will
- // result in this test hanging rather than failing quickly.
- d1.set_quit_on_complete(false);
- d2.set_quit_on_complete(false);
- d3.set_quit_on_complete(true);
- req2->Cancel();
- base::RunLoop().Run();
-
- notification_handler.GetBlockedCallbacks(&blocked_callbacks);
- EXPECT_EQ(0u, blocked_callbacks.size());
- EXPECT_TRUE(req1->status().is_io_pending());
- EXPECT_EQ(URLRequestStatus::CANCELED, req2->status().status());
- EXPECT_EQ(URLRequestStatus::SUCCESS, req3->status().status());
-}
-
-TEST_F(URLRequestTestHTTP, ThrottledRepriUnblock) {
- ASSERT_TRUE(http_test_server()->Start());
-
- base::RunLoop run_until_request_blocked;
-
- NotificationCallbackHandler notification_handler;
- notification_handler.SetRunLoop(&run_until_request_blocked);
- BlockingNetworkDelegate network_delegate(
- BlockingNetworkDelegate::USER_NOTIFY);
- network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED);
- network_delegate.set_notification_callback(
- base::Bind(&NotificationCallbackHandler::ShouldBlockRequest,
- // Both objects are owned by this function, and
- // |*network_delegate| will be destroyed first, so
- // it's safe to pass it an unretained pointer.
- base::Unretained(&notification_handler)));
-
- TestURLRequestContext context(true);
- context.set_network_delegate(&network_delegate);
- context.Init();
-
- // Use different test URLs to make sure all three requests turn into
- // HttpNetworkTransacations. Use different URLRequest::Delegates so that
- // the requests may be waited on separately.
- TestDelegate d1;
- std::unique_ptr<URLRequest> req1(
- context.CreateRequest(http_test_server()->GetURL("/echoall/l"), THROTTLED,
- &d1, TRAFFIC_ANNOTATION_FOR_TESTS));
- notification_handler.AddURLRequestToBlockList(req1.get());
-
- TestDelegate d2;
- std::unique_ptr<URLRequest> req2(
- context.CreateRequest(http_test_server()->GetURL("/echoall/2"), THROTTLED,
- &d2, TRAFFIC_ANNOTATION_FOR_TESTS));
- notification_handler.AddURLRequestToBlockList(req2.get());
-
- TestDelegate d3;
- std::unique_ptr<URLRequest> req3(
- context.CreateRequest(http_test_server()->GetURL("/echoall/3"), THROTTLED,
- &d3, TRAFFIC_ANNOTATION_FOR_TESTS));
- req1->Start();
- req2->Start();
- req3->Start();
- run_until_request_blocked.Run();
- notification_handler.SetRunLoop(nullptr);
-
- // The first two requests should be blocked based on the notification
- // callback, and their status should have blocked the third request
- // through throttling.
- EXPECT_TRUE(req1->status().is_io_pending());
- EXPECT_TRUE(req2->status().is_io_pending());
- EXPECT_TRUE(req3->status().is_io_pending());
-
- std::map<const URLRequest*, CompletionCallback> blocked_callbacks;
- notification_handler.GetBlockedCallbacks(&blocked_callbacks);
- ASSERT_EQ(2u, blocked_callbacks.size());
- ASSERT_TRUE(blocked_callbacks.find(req1.get()) != blocked_callbacks.end());
- ASSERT_TRUE(blocked_callbacks.find(req2.get()) != blocked_callbacks.end());
-
- // Confirm raising the priority of the third request allows it to complete.
-
- // TODO(rdsmith): Find something to wait on other than the third
- // requests completion; if there's a bug in throttling, that will
- // result in this test hanging rather than failing quickly.
- d1.set_quit_on_complete(false);
- d2.set_quit_on_complete(false);
- d3.set_quit_on_complete(true);
- req3->SetPriority(IDLE);
- base::RunLoop().Run();
-
- notification_handler.GetBlockedCallbacks(&blocked_callbacks);
- EXPECT_EQ(0u, blocked_callbacks.size());
- EXPECT_TRUE(req1->status().is_io_pending());
- EXPECT_TRUE(req2->status().is_io_pending());
- EXPECT_EQ(URLRequestStatus::SUCCESS, req3->status().status());
-}
-
TEST_F(URLRequestTestHTTP, RawBodyBytesNoContentEncoding) {
ASSERT_TRUE(http_test_server()->Start());
@@ -10490,7 +10569,7 @@ class HTTPSFallbackTest : public testing::Test {
public:
HTTPSFallbackTest() : context_(true) {
ssl_config_service_ = new TestSSLConfigService(
- true /* check for EV */, false /* online revocation checking */,
+ false /* online revocation checking */,
false /* require rev. checking for local anchors */,
false /* token binding enabled */);
context_.set_ssl_config_service(ssl_config_service_.get());
@@ -10713,7 +10792,6 @@ class HTTPSOCSPTest : public HTTPSRequestTest {
#if defined(USE_NSS_CERTS)
SetURLRequestContextForNSSHttpIO(&context_);
- EnsureNSSHttpIOInit();
#endif
}
@@ -10761,7 +10839,7 @@ class HTTPSOCSPTest : public HTTPSRequestTest {
#endif
#if defined(USE_NSS_CERTS)
- ShutdownNSSHttpIO();
+ SetURLRequestContextForNSSHttpIO(nullptr);
#endif
}
@@ -10782,11 +10860,11 @@ class HTTPSOCSPTest : public HTTPSRequestTest {
// connetions to testserver. This can be overridden in test subclasses for
// different behaviour.
virtual void SetupContext() {
- context_.set_ssl_config_service(new TestSSLConfigService(
- true /* check for EV */, true /* online revocation checking */,
- false /* require rev. checking for local
+ context_.set_ssl_config_service(
+ new TestSSLConfigService(true /* online revocation checking */,
+ false /* require rev. checking for local
anchors */,
- false /* token binding enabled */));
+ false /* token binding enabled */));
}
std::unique_ptr<ScopedTestRoot> test_root_;
@@ -11506,7 +11584,7 @@ class HTTPSAIATest : public HTTPSOCSPTest {
public:
void SetupContext() override {
context_.set_ssl_config_service(new TestSSLConfigService(
- false /* check for EV */, false /* online revocation checking */,
+ false /* online revocation checking */,
false /* require rev. checking for local anchors */,
false /* token binding enabled */));
}
@@ -11520,6 +11598,10 @@ TEST_F(HTTPSAIATest, AIAFetching) {
base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
ASSERT_TRUE(test_server.Start());
+ // Unmark the certificate's OID as EV, which will disable revocation
+ // checking.
+ ev_test_policy_.reset();
+
TestDelegate d;
d.set_allow_certificate_errors(true);
std::unique_ptr<URLRequest> r(context_.CreateRequest(
@@ -11546,9 +11628,8 @@ class HTTPSHardFailTest : public HTTPSOCSPTest {
protected:
void SetupContext() override {
context_.set_ssl_config_service(new TestSSLConfigService(
- false /* check for EV */, false /* online revocation checking */,
- true /* require rev. checking for local
- anchors */,
+ false /* online revocation checking */,
+ true /* require rev. checking for local anchors */,
false /* token binding enabled */));
}
};
@@ -11590,11 +11671,11 @@ TEST_F(HTTPSHardFailTest, FailsOnOCSPInvalid) {
class HTTPSEVCRLSetTest : public HTTPSOCSPTest {
protected:
void SetupContext() override {
- context_.set_ssl_config_service(new TestSSLConfigService(
- true /* check for EV */, false /* online revocation checking */,
- false /* require rev. checking for local
+ context_.set_ssl_config_service(
+ new TestSSLConfigService(false /* online revocation checking */,
+ false /* require rev. checking for local
anchors */,
- false /* token binding enabled */));
+ false /* token binding enabled */));
}
};
@@ -11762,57 +11843,60 @@ TEST_F(HTTPSEVCRLSetTest, FreshCRLSetNotCovered) {
static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
}
-TEST_F(HTTPSEVCRLSetTest, ExpiredCRLSetAndRevokedNonEVCert) {
- // Test that when EV verification is requested, but online revocation
- // checking is disabled, and the leaf certificate is not in fact EV, that
- // no revocation checking actually happens.
- if (!SystemSupportsOCSP()) {
- LOG(WARNING) << "Skipping test because system doesn't support OCSP";
- return;
+class HTTPSCRLSetTest : public HTTPSOCSPTest {
+ protected:
+ void SetupContext() override {
+ context_.set_ssl_config_service(
+ new TestSSLConfigService(false /* online revocation checking */,
+ false /* require rev. checking for local
+ anchors */,
+ false /* token binding enabled */));
}
- // Unmark the certificate's OID as EV, which should disable revocation
- // checking (as per the user preference)
- ev_test_policy_.reset();
+ void SetUp() override {
+ HTTPSOCSPTest::SetUp();
+
+ // Unmark the certificate's OID as EV, which should disable revocation
+ // checking (as per the user preference).
+ ev_test_policy_.reset();
+ }
+};
+TEST_F(HTTPSCRLSetTest, ExpiredCRLSet) {
SpawnedTestServer::SSLOptions ssl_options(
SpawnedTestServer::SSLOptions::CERT_AUTO);
- ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED;
+ ssl_options.ocsp_status =
+ SpawnedTestServer::SSLOptions::OCSP_INVALID_RESPONSE;
ScopedSetCRLSet set_crlset(CRLSet::ExpiredCRLSetForTesting());
CertStatus cert_status;
DoConnection(ssl_options, &cert_status);
+ // If we're not trying EV verification then, even if the CRLSet has expired,
+ // we don't fall back to online revocation checks.
EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);
-
EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
}
-class HTTPSCRLSetTest : public HTTPSOCSPTest {
- protected:
- void SetupContext() override {
- context_.set_ssl_config_service(new TestSSLConfigService(
- false /* check for EV */, false /* online revocation checking */,
- false /* require rev. checking for local
- anchors */,
- false /* token binding enabled */));
+TEST_F(HTTPSCRLSetTest, ExpiredCRLSetAndRevoked) {
+ // Test that when online revocation checking is disabled, and the leaf
+ // certificate is not EV, that no revocation checking actually happens.
+ if (!SystemSupportsOCSP()) {
+ LOG(WARNING) << "Skipping test because system doesn't support OCSP";
+ return;
}
-};
-TEST_F(HTTPSCRLSetTest, ExpiredCRLSet) {
SpawnedTestServer::SSLOptions ssl_options(
SpawnedTestServer::SSLOptions::CERT_AUTO);
- ssl_options.ocsp_status =
- SpawnedTestServer::SSLOptions::OCSP_INVALID_RESPONSE;
+ ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED;
ScopedSetCRLSet set_crlset(CRLSet::ExpiredCRLSetForTesting());
CertStatus cert_status;
DoConnection(ssl_options, &cert_status);
- // If we're not trying EV verification then, even if the CRLSet has expired,
- // we don't fall back to online revocation checks.
EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);
+
EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
}
@@ -11837,8 +11921,7 @@ TEST_F(HTTPSCRLSetTest, CRLSetRevoked) {
// reflected without online revocation checking.
EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS);
EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
- EXPECT_FALSE(
- static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
+ EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
}
TEST_F(HTTPSCRLSetTest, CRLSetRevokedBySubject) {
@@ -11864,8 +11947,7 @@ TEST_F(HTTPSCRLSetTest, CRLSetRevokedBySubject) {
// reflected without online revocation checking.
EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS);
EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
- EXPECT_FALSE(
- static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
+ EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
}
const uint8_t kTestServerSPKISHA256[32] = {
diff --git a/chromium/net/websockets/OWNERS b/chromium/net/websockets/OWNERS
index 74c62dcea9d..d5f50691953 100644
--- a/chromium/net/websockets/OWNERS
+++ b/chromium/net/websockets/OWNERS
@@ -1,4 +1,3 @@
-tyoshino@chromium.org
ricea@chromium.org
yhirano@chromium.org
diff --git a/chromium/net/websockets/websocket_basic_handshake_stream.cc b/chromium/net/websockets/websocket_basic_handshake_stream.cc
index b7c212bda2a..0701d203cec 100644
--- a/chromium/net/websockets/websocket_basic_handshake_stream.cc
+++ b/chromium/net/websockets/websocket_basic_handshake_stream.cc
@@ -9,7 +9,6 @@
#include <iterator>
#include <set>
#include <string>
-#include <unordered_set>
#include <utility>
#include <vector>
@@ -18,7 +17,6 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
@@ -34,6 +32,8 @@
#include "net/http/http_status_code.h"
#include "net/http/http_stream_parser.h"
#include "net/socket/client_socket_handle.h"
+#include "net/socket/ssl_client_socket.h"
+#include "net/socket/websocket_endpoint_lock_manager.h"
#include "net/socket/websocket_transport_client_socket_pool.h"
#include "net/websockets/websocket_basic_stream.h"
#include "net/websockets/websocket_basic_stream_adapters.h"
@@ -42,7 +42,6 @@
#include "net/websockets/websocket_deflate_predictor_impl.h"
#include "net/websockets/websocket_deflate_stream.h"
#include "net/websockets/websocket_deflater.h"
-#include "net/websockets/websocket_extension_parser.h"
#include "net/websockets/websocket_handshake_challenge.h"
#include "net/websockets/websocket_handshake_constants.h"
#include "net/websockets/websocket_handshake_request_info.h"
@@ -57,13 +56,6 @@ const char kConnectionErrorStatusLine[] = "HTTP/1.1 503 Connection Error";
} // namespace
-// TODO(ricea): If more extensions are added, replace this with a more general
-// mechanism.
-struct WebSocketExtensionParams {
- bool deflate_enabled = false;
- WebSocketDeflateParameters deflate_parameters;
-};
-
namespace {
enum GetHeaderResult {
@@ -76,13 +68,6 @@ std::string MissingHeaderMessage(const std::string& header_name) {
return std::string("'") + header_name + "' header is missing";
}
-std::string MultipleHeaderValuesMessage(const std::string& header_name) {
- return
- std::string("'") +
- header_name +
- "' header must not appear more than once in a response";
-}
-
std::string GenerateHandshakeChallenge() {
std::string raw_challenge(websockets::kRawChallengeLength, '\0');
crypto::RandBytes(base::string_as_array(&raw_challenge),
@@ -92,14 +77,6 @@ std::string GenerateHandshakeChallenge() {
return encoded_challenge;
}
-void AddVectorHeaderIfNonEmpty(const char* name,
- const std::vector<std::string>& value,
- HttpRequestHeaders* headers) {
- if (value.empty())
- return;
- headers->SetHeader(name, base::JoinString(value, ", "));
-}
-
GetHeaderResult GetSingleHeaderValue(const HttpResponseHeaders* headers,
const base::StringPiece& name,
std::string* value) {
@@ -122,7 +99,8 @@ bool ValidateHeaderHasSingleValue(GetHeaderResult result,
return false;
}
if (result == GET_HEADER_MULTIPLE) {
- *failure_message = MultipleHeaderValuesMessage(header_name);
+ *failure_message =
+ WebSocketHandshakeStreamBase::MultipleHeaderValuesMessage(header_name);
return false;
}
DCHECK_EQ(result, GET_HEADER_OK);
@@ -182,111 +160,6 @@ bool ValidateConnection(const HttpResponseHeaders* headers,
return true;
}
-bool ValidateSubProtocol(
- const HttpResponseHeaders* headers,
- const std::vector<std::string>& requested_sub_protocols,
- std::string* sub_protocol,
- std::string* failure_message) {
- size_t iter = 0;
- std::string value;
- std::unordered_set<std::string> requested_set(requested_sub_protocols.begin(),
- requested_sub_protocols.end());
- int count = 0;
- bool has_multiple_protocols = false;
- bool has_invalid_protocol = false;
-
- while (!has_invalid_protocol || !has_multiple_protocols) {
- std::string temp_value;
- if (!headers->EnumerateHeader(&iter, websockets::kSecWebSocketProtocol,
- &temp_value))
- break;
- value = temp_value;
- if (requested_set.count(value) == 0)
- has_invalid_protocol = true;
- if (++count > 1)
- has_multiple_protocols = true;
- }
-
- if (has_multiple_protocols) {
- *failure_message =
- MultipleHeaderValuesMessage(websockets::kSecWebSocketProtocol);
- return false;
- } else if (count > 0 && requested_sub_protocols.size() == 0) {
- *failure_message =
- std::string("Response must not include 'Sec-WebSocket-Protocol' "
- "header if not present in request: ")
- + value;
- return false;
- } else if (has_invalid_protocol) {
- *failure_message =
- "'Sec-WebSocket-Protocol' header value '" +
- value +
- "' in response does not match any of sent values";
- return false;
- } else if (requested_sub_protocols.size() > 0 && count == 0) {
- *failure_message =
- "Sent non-empty 'Sec-WebSocket-Protocol' header "
- "but no response was received";
- return false;
- }
- *sub_protocol = value;
- return true;
-}
-
-bool ValidateExtensions(const HttpResponseHeaders* headers,
- std::string* accepted_extensions_descriptor,
- std::string* failure_message,
- WebSocketExtensionParams* params) {
- size_t iter = 0;
- std::string header_value;
- std::vector<std::string> header_values;
- // TODO(ricea): If adding support for additional extensions, generalise this
- // code.
- bool seen_permessage_deflate = false;
- while (headers->EnumerateHeader(&iter, websockets::kSecWebSocketExtensions,
- &header_value)) {
- WebSocketExtensionParser parser;
- if (!parser.Parse(header_value)) {
- // TODO(yhirano) Set appropriate failure message.
- *failure_message =
- "'Sec-WebSocket-Extensions' header value is "
- "rejected by the parser: " +
- header_value;
- return false;
- }
-
- const std::vector<WebSocketExtension>& extensions = parser.extensions();
- for (const auto& extension : extensions) {
- if (extension.name() == "permessage-deflate") {
- if (seen_permessage_deflate) {
- *failure_message = "Received duplicate permessage-deflate response";
- return false;
- }
- seen_permessage_deflate = true;
- auto& deflate_parameters = params->deflate_parameters;
- if (!deflate_parameters.Initialize(extension, failure_message) ||
- !deflate_parameters.IsValidAsResponse(failure_message)) {
- *failure_message = "Error in permessage-deflate: " + *failure_message;
- return false;
- }
- // Note that we don't have to check the request-response compatibility
- // here because we send a request compatible with any valid responses.
- // TODO(yhirano): Place a DCHECK here.
-
- header_values.push_back(header_value);
- } else {
- *failure_message = "Found an unsupported extension '" +
- extension.name() +
- "' in 'Sec-WebSocket-Extensions' header";
- return false;
- }
- }
- }
- *accepted_extensions_descriptor = base::JoinString(header_values, ", ");
- params->deflate_enabled = seen_permessage_deflate;
- return true;
-}
-
} // namespace
WebSocketBasicHandshakeStream::WebSocketBasicHandshakeStream(
@@ -295,20 +168,25 @@ WebSocketBasicHandshakeStream::WebSocketBasicHandshakeStream(
bool using_proxy,
std::vector<std::string> requested_sub_protocols,
std::vector<std::string> requested_extensions,
- WebSocketStreamRequest* request)
- : state_(std::move(connection),
+ WebSocketStreamRequest* request,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager)
+ : result_(HandshakeResult::INCOMPLETE),
+ state_(std::move(connection),
using_proxy,
false /* http_09_on_non_default_ports_enabled */),
connect_delegate_(connect_delegate),
http_response_info_(nullptr),
requested_sub_protocols_(requested_sub_protocols),
requested_extensions_(requested_extensions),
- stream_request_(request) {
+ stream_request_(request),
+ websocket_endpoint_lock_manager_(websocket_endpoint_lock_manager) {
DCHECK(connect_delegate);
DCHECK(request);
}
-WebSocketBasicHandshakeStream::~WebSocketBasicHandshakeStream() = default;
+WebSocketBasicHandshakeStream::~WebSocketBasicHandshakeStream() {
+ RecordHandshakeResult(result_);
+}
int WebSocketBasicHandshakeStream::InitializeStream(
const HttpRequestInfo* request_info,
@@ -342,8 +220,8 @@ int WebSocketBasicHandshakeStream::SendRequest(
HttpRequestHeaders enriched_headers;
enriched_headers.CopyFrom(headers);
std::string handshake_challenge;
- if (handshake_challenge_for_testing_) {
- handshake_challenge = *handshake_challenge_for_testing_;
+ if (handshake_challenge_for_testing_.has_value()) {
+ handshake_challenge = handshake_challenge_for_testing_.value();
handshake_challenge_for_testing_.reset();
} else {
handshake_challenge = GenerateHandshakeChallenge();
@@ -361,8 +239,8 @@ int WebSocketBasicHandshakeStream::SendRequest(
ComputeSecWebSocketAccept(handshake_challenge);
DCHECK(connect_delegate_);
- std::unique_ptr<WebSocketHandshakeRequestInfo> request(
- new WebSocketHandshakeRequestInfo(url_, base::Time::Now()));
+ auto request =
+ std::make_unique<WebSocketHandshakeRequestInfo>(url_, base::Time::Now());
request->headers.CopyFrom(enriched_headers);
connect_delegate_->OnStartOpeningHandshake(std::move(request));
@@ -460,8 +338,12 @@ Error WebSocketBasicHandshakeStream::GetTokenBindingSignature(
crypto::ECPrivateKey* key,
TokenBindingType tb_type,
std::vector<uint8_t>* out) {
- NOTREACHED();
- return ERR_NOT_IMPLEMENTED;
+ DCHECK(url_.SchemeIsCryptographic());
+
+ // Encrypted WebSocket must use an SSL socket.
+ StreamSocket* socket = state_.connection()->socket();
+ SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(socket);
+ return ssl_socket->GetTokenBindingSignature(key, tb_type, out);
}
void WebSocketBasicHandshakeStream::Drain(HttpNetworkSession* session) {
@@ -484,7 +366,8 @@ std::unique_ptr<WebSocketStream> WebSocketBasicHandshakeStream::Upgrade() {
// The HttpStreamParser object has a pointer to our ClientSocketHandle. Make
// sure it does not touch it again before it is destroyed.
state_.DeleteParser();
- WebSocketTransportClientSocketPool::UnlockEndpoint(state_.connection());
+ WebSocketTransportClientSocketPool::UnlockEndpoint(
+ state_.connection(), websocket_endpoint_lock_manager_);
std::unique_ptr<WebSocketStream> basic_stream =
std::make_unique<WebSocketBasicStream>(
std::make_unique<WebSocketClientSocketHandleAdapter>(
@@ -492,15 +375,12 @@ std::unique_ptr<WebSocketStream> WebSocketBasicHandshakeStream::Upgrade() {
state_.read_buf(), sub_protocol_, extensions_);
DCHECK(extension_params_.get());
if (extension_params_->deflate_enabled) {
- UMA_HISTOGRAM_ENUMERATION(
- "Net.WebSocket.DeflateMode",
- extension_params_->deflate_parameters.client_context_take_over_mode(),
- WebSocketDeflater::NUM_CONTEXT_TAKEOVER_MODE_TYPES);
+ RecordDeflateMode(
+ extension_params_->deflate_parameters.client_context_take_over_mode());
- return std::unique_ptr<WebSocketStream>(new WebSocketDeflateStream(
+ return std::make_unique<WebSocketDeflateStream>(
std::move(basic_stream), extension_params_->deflate_parameters,
- std::unique_ptr<WebSocketDeflatePredictor>(
- new WebSocketDeflatePredictorImpl)));
+ std::make_unique<WebSocketDeflatePredictorImpl>());
} else {
return basic_stream;
}
@@ -508,7 +388,7 @@ std::unique_ptr<WebSocketStream> WebSocketBasicHandshakeStream::Upgrade() {
void WebSocketBasicHandshakeStream::SetWebSocketKeyForTesting(
const std::string& key) {
- handshake_challenge_for_testing_.reset(new std::string(key));
+ handshake_challenge_for_testing_ = key;
}
void WebSocketBasicHandshakeStream::ReadResponseHeadersCallback(
@@ -559,11 +439,13 @@ int WebSocketBasicHandshakeStream::ValidateResponse(int rv) {
headers->response_code()));
}
OnFinishOpeningHandshake();
+ result_ = HandshakeResult::INVALID_STATUS;
return ERR_INVALID_RESPONSE;
}
} else {
if (rv == ERR_EMPTY_RESPONSE) {
OnFailure("Connection closed before receiving a handshake response");
+ result_ = HandshakeResult::EMPTY_RESPONSE;
return rv;
}
OnFailure(std::string("Error during WebSocket handshake: ") +
@@ -578,27 +460,33 @@ int WebSocketBasicHandshakeStream::ValidateResponse(int rv) {
HTTP_SWITCHING_PROTOCOLS) {
http_response_info_->headers->ReplaceStatusLine(
kConnectionErrorStatusLine);
+ result_ = HandshakeResult::FAILED_SWITCHING_PROTOCOLS;
+ return rv;
}
+ result_ = HandshakeResult::FAILED;
return rv;
}
}
int WebSocketBasicHandshakeStream::ValidateUpgradeResponse(
const HttpResponseHeaders* headers) {
- extension_params_.reset(new WebSocketExtensionParams);
+ extension_params_ = std::make_unique<WebSocketExtensionParams>();
std::string failure_message;
- if (ValidateUpgrade(headers, &failure_message) &&
- ValidateSecWebSocketAccept(
- headers, handshake_challenge_response_, &failure_message) &&
- ValidateConnection(headers, &failure_message) &&
- ValidateSubProtocol(headers,
- requested_sub_protocols_,
- &sub_protocol_,
- &failure_message) &&
- ValidateExtensions(headers,
- &extensions_,
- &failure_message,
- extension_params_.get())) {
+ if (!ValidateUpgrade(headers, &failure_message)) {
+ result_ = HandshakeResult::FAILED_UPGRADE;
+ } else if (!ValidateSecWebSocketAccept(headers, handshake_challenge_response_,
+ &failure_message)) {
+ result_ = HandshakeResult::FAILED_ACCEPT;
+ } else if (!ValidateConnection(headers, &failure_message)) {
+ result_ = HandshakeResult::FAILED_CONNECTION;
+ } else if (!ValidateSubProtocol(headers, requested_sub_protocols_,
+ &sub_protocol_, &failure_message)) {
+ result_ = HandshakeResult::FAILED_SUBPROTO;
+ } else if (!ValidateExtensions(headers, &extensions_, &failure_message,
+ extension_params_.get())) {
+ result_ = HandshakeResult::FAILED_EXTENSIONS;
+ } else {
+ result_ = HandshakeResult::CONNECTED;
return OK;
}
OnFailure("Error during WebSocket handshake: " + failure_message);
diff --git a/chromium/net/websockets/websocket_basic_handshake_stream.h b/chromium/net/websockets/websocket_basic_handshake_stream.h
index d325f313ea8..2197cb4330d 100644
--- a/chromium/net/websockets/websocket_basic_handshake_stream.h
+++ b/chromium/net/websockets/websocket_basic_handshake_stream.h
@@ -12,7 +12,7 @@
#include <vector>
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
+#include "base/optional.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_export.h"
#include "net/http/http_basic_state.h"
@@ -25,7 +25,7 @@ class ClientSocketHandle;
class HttpResponseHeaders;
class HttpResponseInfo;
class HttpStreamParser;
-
+class WebSocketEndpointLockManager;
struct WebSocketExtensionParams;
class WebSocketStreamRequest;
@@ -39,7 +39,8 @@ class NET_EXPORT_PRIVATE WebSocketBasicHandshakeStream
bool using_proxy,
std::vector<std::string> requested_sub_protocols,
std::vector<std::string> requested_extensions,
- WebSocketStreamRequest* request);
+ WebSocketStreamRequest* request,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager);
~WebSocketBasicHandshakeStream() override;
@@ -107,6 +108,8 @@ class NET_EXPORT_PRIVATE WebSocketBasicHandshakeStream
HttpStreamParser* parser() const { return state_.parser(); }
+ HandshakeResult result_;
+
// The request URL.
GURL url_;
@@ -122,7 +125,7 @@ class NET_EXPORT_PRIVATE WebSocketBasicHandshakeStream
// The key to be sent in the next Sec-WebSocket-Key header. Usually NULL (the
// key is generated on the fly).
- std::unique_ptr<std::string> handshake_challenge_for_testing_;
+ base::Optional<std::string> handshake_challenge_for_testing_;
// The required value for the Sec-WebSocket-Accept header.
std::string handshake_challenge_response_;
@@ -143,7 +146,9 @@ class NET_EXPORT_PRIVATE WebSocketBasicHandshakeStream
// to avoid including extension-related header files here.
std::unique_ptr<WebSocketExtensionParams> extension_params_;
- WebSocketStreamRequest* stream_request_;
+ WebSocketStreamRequest* const stream_request_;
+
+ WebSocketEndpointLockManager* const websocket_endpoint_lock_manager_;
DISALLOW_COPY_AND_ASSIGN(WebSocketBasicHandshakeStream);
};
diff --git a/chromium/net/websockets/websocket_basic_stream.cc b/chromium/net/websockets/websocket_basic_stream.cc
index 22d0c688621..31267ba9a80 100644
--- a/chromium/net/websockets/websocket_basic_stream.cc
+++ b/chromium/net/websockets/websocket_basic_stream.cc
@@ -99,7 +99,7 @@ WebSocketBasicStream::WebSocketBasicStream(
const scoped_refptr<GrowableIOBuffer>& http_read_buffer,
const std::string& sub_protocol,
const std::string& extensions)
- : read_buffer_(new IOBufferWithSize(kReadBufferSize)),
+ : read_buffer_(base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize)),
connection_(std::move(connection)),
http_read_buffer_(http_read_buffer),
sub_protocol_(sub_protocol),
@@ -166,8 +166,7 @@ int WebSocketBasicStream::WriteFrames(
//
// First calculate the size of the buffer we need to allocate.
int total_size = CalculateSerializedSizeAndTurnOnMaskBit(frames);
- scoped_refptr<IOBufferWithSize> combined_buffer(
- new IOBufferWithSize(total_size));
+ auto combined_buffer = base::MakeRefCounted<IOBufferWithSize>(total_size);
char* dest = combined_buffer->data();
int remaining_size = total_size;
@@ -195,8 +194,8 @@ int WebSocketBasicStream::WriteFrames(
}
DCHECK_EQ(0, remaining_size) << "Buffer size calculation was wrong; "
<< remaining_size << " bytes left over.";
- scoped_refptr<DrainableIOBuffer> drainable_buffer(
- new DrainableIOBuffer(combined_buffer.get(), total_size));
+ auto drainable_buffer = base::MakeRefCounted<DrainableIOBuffer>(
+ combined_buffer.get(), total_size);
return WriteEverything(drainable_buffer, callback);
}
@@ -348,7 +347,8 @@ int WebSocketBasicStream::ConvertChunkToFrame(
AddToIncompleteControlFrameBody(data_buffer);
} else {
DVLOG(3) << "Creating new storage for an incomplete control frame.";
- incomplete_control_frame_body_ = new GrowableIOBuffer();
+ incomplete_control_frame_body_ =
+ base::MakeRefCounted<GrowableIOBuffer>();
// This method checks for oversize control frames above, so as long as
// the frame parser is working correctly, this won't overflow. If a bug
// does cause it to overflow, it will CHECK() in
@@ -364,7 +364,7 @@ int WebSocketBasicStream::ConvertChunkToFrame(
const int body_size = incomplete_control_frame_body_->offset();
DCHECK_EQ(body_size,
static_cast<int>(current_frame_header_->payload_length));
- scoped_refptr<IOBufferWithSize> body = new IOBufferWithSize(body_size);
+ auto body = base::MakeRefCounted<IOBufferWithSize>(body_size);
memcpy(body->data(),
incomplete_control_frame_body_->StartOfBuffer(),
body_size);
@@ -402,7 +402,7 @@ std::unique_ptr<WebSocketFrame> WebSocketBasicStream::CreateFrame(
if (is_final_chunk_in_message || data_size > 0 ||
current_frame_header_->opcode !=
WebSocketFrameHeader::kOpCodeContinuation) {
- result_frame.reset(new WebSocketFrame(opcode));
+ result_frame = std::make_unique<WebSocketFrame>(opcode);
result_frame->header.CopyFrom(*current_frame_header_);
result_frame->header.final = is_final_chunk_in_message;
result_frame->header.payload_length = data_size;
diff --git a/chromium/net/websockets/websocket_basic_stream.h b/chromium/net/websockets/websocket_basic_stream.h
index 97fe554dfce..6064d628792 100644
--- a/chromium/net/websockets/websocket_basic_stream.h
+++ b/chromium/net/websockets/websocket_basic_stream.h
@@ -9,7 +9,7 @@
#include <string>
#include <vector>
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
diff --git a/chromium/net/websockets/websocket_basic_stream_adapters_test.cc b/chromium/net/websockets/websocket_basic_stream_adapters_test.cc
index 9e6f7645181..f7246c8ad6e 100644
--- a/chromium/net/websockets/websocket_basic_stream_adapters_test.cc
+++ b/chromium/net/websockets/websocket_basic_stream_adapters_test.cc
@@ -25,6 +25,7 @@
#include "net/socket/socket_test_util.h"
#include "net/socket/ssl_client_socket_pool.h"
#include "net/socket/transport_client_socket_pool.h"
+#include "net/socket/websocket_endpoint_lock_manager.h"
#include "net/spdy/chromium/spdy_session.h"
#include "net/spdy/chromium/spdy_session_key.h"
#include "net/spdy/chromium/spdy_test_util_common.h"
@@ -65,6 +66,7 @@ class WebSocketClientSocketHandleAdapterTest : public Test {
nullptr,
"test_shard",
nullptr,
+ &websocket_endpoint_lock_manager_,
HttpNetworkSession::NORMAL_SOCKET_POOL)),
transport_params_(base::MakeRefCounted<TransportSocketParams>(
host_port_pair_,
@@ -98,6 +100,7 @@ class WebSocketClientSocketHandleAdapterTest : public Test {
std::unique_ptr<ClientSocketPoolManagerImpl> socket_pool_manager_;
scoped_refptr<TransportSocketParams> transport_params_;
scoped_refptr<SSLSocketParams> ssl_params_;
+ WebSocketEndpointLockManager websocket_endpoint_lock_manager_;
};
TEST_F(WebSocketClientSocketHandleAdapterTest, Uninitialized) {
@@ -318,7 +321,7 @@ class WebSocketSpdyStreamAdapterTest : public Test {
void AddSSLSocketData() {
ssl_.ssl_info.cert =
- ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
+ ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
ASSERT_TRUE(ssl_.ssl_info.cert);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
}
diff --git a/chromium/net/websockets/websocket_basic_stream_test.cc b/chromium/net/websockets/websocket_basic_stream_test.cc
index a1dea4aef8d..e7c8d745f2b 100644
--- a/chromium/net/websockets/websocket_basic_stream_test.cc
+++ b/chromium/net/websockets/websocket_basic_stream_test.cc
@@ -125,13 +125,12 @@ class WebSocketBasicStreamSocketTest : public WebSocketBasicStreamTest {
size_t reads_count,
MockWrite writes[],
size_t writes_count) {
- socket_data_.reset(new StrictStaticSocketDataProvider(
- reads, reads_count, writes, writes_count, expect_all_io_to_complete_));
+ socket_data_ = std::make_unique<StrictStaticSocketDataProvider>(
+ reads, reads_count, writes, writes_count, expect_all_io_to_complete_);
socket_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
factory_.AddSocketDataProvider(socket_data_.get());
- std::unique_ptr<ClientSocketHandle> transport_socket(
- new ClientSocketHandle);
+ auto transport_socket = std::make_unique<ClientSocketHandle>();
scoped_refptr<MockTransportSocketParams> params;
transport_socket->Init("a", params, MEDIUM, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
@@ -140,7 +139,7 @@ class WebSocketBasicStreamSocketTest : public WebSocketBasicStreamTest {
}
void SetHttpReadBuffer(const char* data, size_t size) {
- http_read_buffer_ = new GrowableIOBuffer;
+ http_read_buffer_ = base::MakeRefCounted<GrowableIOBuffer>();
http_read_buffer_->SetCapacity(size);
memcpy(http_read_buffer_->data(), data, size);
http_read_buffer_->set_offset(size);
@@ -244,12 +243,12 @@ class WebSocketBasicStreamSocketWriteTest
// Creates a WebSocketFrame with a wire format matching kWriteFrame and adds
// it to |frames_|.
void PrepareWriteFrame() {
- std::unique_ptr<WebSocketFrame> frame(
- new WebSocketFrame(WebSocketFrameHeader::kOpCodeText));
+ auto frame =
+ std::make_unique<WebSocketFrame>(WebSocketFrameHeader::kOpCodeText);
const size_t payload_size =
kWriteFrameSize - (WebSocketFrameHeader::kBaseHeaderSize +
WebSocketFrameHeader::kMaskingKeyLength);
- frame->data = new IOBuffer(payload_size);
+ frame->data = base::MakeRefCounted<IOBuffer>(payload_size);
memcpy(frame->data->data(),
kWriteFrame + kWriteFrameSize - payload_size,
payload_size);
@@ -918,8 +917,8 @@ TEST_F(WebSocketBasicStreamSocketWriteTest, WriteNullPong) {
MockWrite(SYNCHRONOUS, kMaskedEmptyPong, kMaskedEmptyPongSize)};
CreateWriteOnly(writes);
- std::unique_ptr<WebSocketFrame> frame(
- new WebSocketFrame(WebSocketFrameHeader::kOpCodePong));
+ auto frame =
+ std::make_unique<WebSocketFrame>(WebSocketFrameHeader::kOpCodePong);
WebSocketFrameHeader& header = frame->header;
header.final = true;
header.masked = true;
@@ -939,11 +938,11 @@ TEST_F(WebSocketBasicStreamSocketTest, WriteNonNulMask) {
generator_ = &GenerateNonNulMaskingKey;
CreateStream(NULL, 0, writes, arraysize(writes));
- std::unique_ptr<WebSocketFrame> frame(
- new WebSocketFrame(WebSocketFrameHeader::kOpCodeText));
+ auto frame =
+ std::make_unique<WebSocketFrame>(WebSocketFrameHeader::kOpCodeText);
const std::string unmasked_payload = "graphics";
const size_t payload_size = unmasked_payload.size();
- frame->data = new IOBuffer(payload_size);
+ frame->data = base::MakeRefCounted<IOBuffer>(payload_size);
memcpy(frame->data->data(), unmasked_payload.data(), payload_size);
WebSocketFrameHeader& header = frame->header;
header.final = true;
diff --git a/chromium/net/websockets/websocket_channel.cc b/chromium/net/websockets/websocket_channel.cc
index d3c02e61fe3..b5c0639cae8 100644
--- a/chromium/net/websockets/websocket_channel.cc
+++ b/chromium/net/websockets/websocket_channel.cc
@@ -16,7 +16,6 @@
#include "base/containers/circular_deque.h"
#include "base/location.h"
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
@@ -58,9 +57,7 @@ const int kClosingHandshakeTimeoutSeconds = 60;
// recommendation.
const int kUnderlyingConnectionCloseTimeoutSeconds = 2;
-typedef WebSocketEventInterface::ChannelState ChannelState;
-const ChannelState CHANNEL_ALIVE = WebSocketEventInterface::CHANNEL_ALIVE;
-const ChannelState CHANNEL_DELETED = WebSocketEventInterface::CHANNEL_DELETED;
+using ChannelState = WebSocketChannel::ChannelState;
// Maximum close reason length = max control frame payload -
// status code length
@@ -225,7 +222,7 @@ class WebSocketChannel::HandshakeNotificationSender
static void Send(base::WeakPtr<HandshakeNotificationSender> sender);
- ChannelState SendImmediately(WebSocketEventInterface* event_interface);
+ void SendImmediately(WebSocketEventInterface* event_interface);
const WebSocketHandshakeRequestInfo* handshake_request_info() const {
return handshake_request_info_.get();
@@ -316,27 +313,20 @@ void WebSocketChannel::HandshakeNotificationSender::Send(
}
}
-ChannelState WebSocketChannel::HandshakeNotificationSender::SendImmediately(
+void WebSocketChannel::HandshakeNotificationSender::SendImmediately(
WebSocketEventInterface* event_interface) {
-
if (handshake_request_info_.get()) {
- if (CHANNEL_DELETED ==
- event_interface->OnStartOpeningHandshake(
- std::move(handshake_request_info_)))
- return CHANNEL_DELETED;
+ event_interface->OnStartOpeningHandshake(
+ std::move(handshake_request_info_));
}
if (handshake_response_info_.get()) {
- if (CHANNEL_DELETED ==
- event_interface->OnFinishOpeningHandshake(
- std::move(handshake_response_info_)))
- return CHANNEL_DELETED;
+ event_interface->OnFinishOpeningHandshake(
+ std::move(handshake_response_info_));
// TODO(yhirano): We can release |this| to save memory because
// there will be no more opening handshake notification.
}
-
- return CHANNEL_ALIVE;
}
WebSocketChannel::WebSocketChannel(
@@ -355,7 +345,7 @@ WebSocketChannel::WebSocketChannel(
has_received_close_frame_(false),
received_close_code_(0),
state_(FRESHLY_CONSTRUCTED),
- notification_sender_(new HandshakeNotificationSender(this)),
+ notification_sender_(std::make_unique<HandshakeNotificationSender>(this)),
sending_text_message_(false),
receiving_text_message_(false),
expecting_to_handle_continuation_(false),
@@ -428,7 +418,8 @@ WebSocketChannel::ChannelState WebSocketChannel::SendFrame(
}
if (buffer_size > base::checked_cast<size_t>(current_send_quota_)) {
// TODO(ricea): Kill renderer.
- return FailChannel("Send quota exceeded", kWebSocketErrorGoingAway, "");
+ FailChannel("Send quota exceeded", kWebSocketErrorGoingAway, "");
+ return CHANNEL_DELETED;
// |this| has been deleted.
}
if (!WebSocketFrameHeader::IsKnownDataOpCode(op_code)) {
@@ -445,8 +436,9 @@ WebSocketChannel::ChannelState WebSocketChannel::SendFrame(
if (state == StreamingUtf8Validator::INVALID ||
(state == StreamingUtf8Validator::VALID_MIDPOINT && fin)) {
// TODO(ricea): Kill renderer.
- return FailChannel("Browser sent a text frame containing invalid UTF-8",
- kWebSocketErrorGoingAway, "");
+ FailChannel("Browser sent a text frame containing invalid UTF-8",
+ kWebSocketErrorGoingAway, "");
+ return CHANNEL_DELETED;
// |this| has been deleted.
}
sending_text_message_ = !fin;
@@ -479,17 +471,16 @@ ChannelState WebSocketChannel::SendFlowControl(int64_t quota) {
const bool final = front.final() && data_size == bytes_to_send;
scoped_refptr<IOBuffer> buffer_to_pass;
if (front.data()) {
- buffer_to_pass = new DependentIOBuffer(front.data(), front.offset());
+ buffer_to_pass =
+ base::MakeRefCounted<DependentIOBuffer>(front.data(), front.offset());
} else {
DCHECK(!bytes_to_send) << "Non empty data should not be null.";
}
DVLOG(3) << "Sending frame previously split due to quota to the "
<< "renderer: quota=" << quota << " data_size=" << data_size
<< " bytes_to_send=" << bytes_to_send;
- if (event_interface_->OnDataFrame(final, front.opcode(),
- std::move(buffer_to_pass),
- bytes_to_send) == CHANNEL_DELETED)
- return CHANNEL_DELETED;
+ event_interface_->OnDataFrame(final, front.opcode(),
+ std::move(buffer_to_pass), bytes_to_send);
if (bytes_to_send < data_size) {
front.DidConsume(bytes_to_send);
front.ResetOpcode();
@@ -539,7 +530,8 @@ ChannelState WebSocketChannel::StartClosingHandshake(
// Abort the in-progress handshake and drop the connection immediately.
stream_request_.reset();
SetState(CLOSED);
- return DoDropChannel(false, kWebSocketErrorAbnormalClosure, "");
+ DoDropChannel(false, kWebSocketErrorAbnormalClosure, "");
+ return CHANNEL_DELETED;
}
if (state_ != CONNECTED) {
NOTREACHED() << "StartClosingHandshake() called in state " << state_;
@@ -569,10 +561,9 @@ ChannelState WebSocketChannel::StartClosingHandshake(
SetState(SEND_CLOSED);
return CHANNEL_ALIVE;
}
- if (SendClose(
- code,
- StreamingUtf8Validator::Validate(reason) ? reason : std::string()) ==
- CHANNEL_DELETED)
+ if (SendClose(code, StreamingUtf8Validator::Validate(reason)
+ ? reason
+ : std::string()) == CHANNEL_DELETED)
return CHANNEL_DELETED;
DCHECK_EQ(CONNECTED, state_);
SetState(SEND_CLOSED);
@@ -612,16 +603,14 @@ void WebSocketChannel::SendAddChannelRequestWithSuppliedCallback(
if (!socket_url.SchemeIsWSOrWSS()) {
// TODO(ricea): Kill the renderer (this error should have been caught by
// Javascript).
- ignore_result(event_interface_->OnFailChannel("Invalid scheme"));
+ event_interface_->OnFailChannel("Invalid scheme");
// |this| is deleted here.
return;
}
socket_url_ = socket_url;
- std::unique_ptr<WebSocketStream::ConnectDelegate> connect_delegate(
- new ConnectDelegate(this));
- std::unique_ptr<WebSocketHandshakeStreamCreateHelper> create_helper(
- new WebSocketHandshakeStreamCreateHelper(connect_delegate.get(),
- requested_subprotocols));
+ auto connect_delegate = std::make_unique<ConnectDelegate>(this);
+ auto create_helper = std::make_unique<WebSocketHandshakeStreamCreateHelper>(
+ connect_delegate.get(), requested_subprotocols);
stream_request_ =
callback.Run(socket_url_, std::move(create_helper), origin,
site_for_cookies, additional_headers, url_request_context_,
@@ -642,17 +631,13 @@ void WebSocketChannel::OnConnectSuccess(
SetState(CONNECTED);
- if (event_interface_->OnAddChannelResponse(stream_->GetSubProtocol(),
- stream_->GetExtensions()) ==
- CHANNEL_DELETED)
- return;
+ event_interface_->OnAddChannelResponse(stream_->GetSubProtocol(),
+ stream_->GetExtensions());
// TODO(ricea): Get flow control information from the WebSocketStream once we
// have a multiplexing WebSocketStream.
current_send_quota_ = send_quota_high_water_mark_;
- if (event_interface_->OnFlowControl(send_quota_high_water_mark_) ==
- CHANNEL_DELETED)
- return;
+ event_interface_->OnFlowControl(send_quota_high_water_mark_);
// |stream_request_| is not used once the connection has succeeded.
stream_request_.reset();
@@ -670,13 +655,8 @@ void WebSocketChannel::OnConnectFailure(const std::string& message) {
SetState(CLOSED);
stream_request_.reset();
- if (CHANNEL_DELETED ==
- notification_sender_->SendImmediately(event_interface_.get())) {
- // |this| has been deleted.
- return;
- }
- ChannelState result = event_interface_->OnFailChannel(message_copy);
- DCHECK_EQ(CHANNEL_DELETED, result);
+ notification_sender_->SendImmediately(event_interface_.get());
+ event_interface_->OnFailChannel(message_copy);
// |this| has been deleted.
}
@@ -685,8 +665,8 @@ void WebSocketChannel::OnSSLCertificateError(
ssl_error_callbacks,
const SSLInfo& ssl_info,
bool fatal) {
- ignore_result(event_interface_->OnSSLCertificateError(
- std::move(ssl_error_callbacks), socket_url_, ssl_info, fatal));
+ event_interface_->OnSSLCertificateError(std::move(ssl_error_callbacks),
+ socket_url_, ssl_info, fatal);
}
void WebSocketChannel::OnStartOpeningHandshake(
@@ -760,7 +740,8 @@ ChannelState WebSocketChannel::OnWriteDone(bool synchronous, int result) {
// server, if the protocol in use supports quota.
int fresh_quota = send_quota_high_water_mark_ - current_send_quota_;
current_send_quota_ += fresh_quota;
- return event_interface_->OnFlowControl(fresh_quota);
+ event_interface_->OnFlowControl(fresh_quota);
+ return CHANNEL_ALIVE;
}
}
return CHANNEL_ALIVE;
@@ -773,7 +754,8 @@ ChannelState WebSocketChannel::OnWriteDone(bool synchronous, int result) {
stream_->Close();
SetState(CLOSED);
- return DoDropChannel(false, kWebSocketErrorAbnormalClosure, "");
+ DoDropChannel(false, kWebSocketErrorAbnormalClosure, "");
+ return CHANNEL_DELETED;
}
}
@@ -823,9 +805,9 @@ ChannelState WebSocketChannel::OnReadDone(bool synchronous, int result) {
// This could be kWebSocketErrorProtocolError (specifically, non-minimal
// encoding of payload length) or kWebSocketErrorMessageTooBig, or an
// extension-specific error.
- return FailChannel("Invalid frame header",
- kWebSocketErrorProtocolError,
- "WebSocket Protocol Error");
+ FailChannel("Invalid frame header", kWebSocketErrorProtocolError,
+ "WebSocket Protocol Error");
+ return CHANNEL_DELETED;
default:
DCHECK_LT(result, 0)
@@ -843,7 +825,8 @@ ChannelState WebSocketChannel::OnReadDone(bool synchronous, int result) {
was_clean = (result == ERR_CONNECTION_CLOSED);
}
- return DoDropChannel(was_clean, code, reason);
+ DoDropChannel(was_clean, code, reason);
+ return CHANNEL_DELETED;
}
}
@@ -852,25 +835,25 @@ ChannelState WebSocketChannel::HandleFrame(
if (frame->header.masked) {
// RFC6455 Section 5.1 "A client MUST close a connection if it detects a
// masked frame."
- return FailChannel(
+ FailChannel(
"A server must not mask any frames that it sends to the "
"client.",
- kWebSocketErrorProtocolError,
- "Masked frame from server");
+ kWebSocketErrorProtocolError, "Masked frame from server");
+ return CHANNEL_DELETED;
}
const WebSocketFrameHeader::OpCode opcode = frame->header.opcode;
DCHECK(!WebSocketFrameHeader::IsKnownControlOpCode(opcode) ||
frame->header.final);
if (frame->header.reserved1 || frame->header.reserved2 ||
frame->header.reserved3) {
- return FailChannel(base::StringPrintf(
- "One or more reserved bits are on: reserved1 = %d, "
+ FailChannel(
+ base::StringPrintf("One or more reserved bits are on: reserved1 = %d, "
"reserved2 = %d, reserved3 = %d",
static_cast<int>(frame->header.reserved1),
static_cast<int>(frame->header.reserved2),
static_cast<int>(frame->header.reserved3)),
- kWebSocketErrorProtocolError,
- "Invalid reserved bit");
+ kWebSocketErrorProtocolError, "Invalid reserved bit");
+ return CHANNEL_DELETED;
}
// Respond to the frame appropriately to its type.
@@ -892,8 +875,9 @@ ChannelState WebSocketChannel::HandleFrameByState(
GetFrameTypeForOpcode(opcode, &frame_name);
// FailChannel() won't send another Close frame.
- return FailChannel(
- frame_name + " received after close", kWebSocketErrorProtocolError, "");
+ FailChannel(frame_name + " received after close",
+ kWebSocketErrorProtocolError, "");
+ return CHANNEL_DELETED;
}
switch (opcode) {
case WebSocketFrameHeader::kOpCodeText: // fall-thru
@@ -919,7 +903,8 @@ ChannelState WebSocketChannel::HandleFrameByState(
std::string reason;
std::string message;
if (!ParseClose(std::move(data_buffer), size, &code, &reason, &message)) {
- return FailChannel(message, code, reason);
+ FailChannel(message, code, reason);
+ return CHANNEL_DELETED;
}
// TODO(ricea): Find a way to safely log the message from the close
// message (escape control codes and so on).
@@ -928,10 +913,9 @@ ChannelState WebSocketChannel::HandleFrameByState(
}
default:
- return FailChannel(
- base::StringPrintf("Unrecognized frame opcode: %d", opcode),
- kWebSocketErrorProtocolError,
- "Unknown opcode");
+ FailChannel(base::StringPrintf("Unrecognized frame opcode: %d", opcode),
+ kWebSocketErrorProtocolError, "Unknown opcode");
+ return CHANNEL_DELETED;
}
}
@@ -960,7 +944,8 @@ ChannelState WebSocketChannel::HandleDataFrame(
const std::string reason = got_continuation
? "Unexpected continuation"
: "Previous data frame unfinished";
- return FailChannel(console_log, kWebSocketErrorProtocolError, reason);
+ FailChannel(console_log, kWebSocketErrorProtocolError, reason);
+ return CHANNEL_DELETED;
}
expecting_to_handle_continuation_ = !final;
WebSocketFrameHeader::OpCode opcode_to_send = opcode;
@@ -979,9 +964,9 @@ ChannelState WebSocketChannel::HandleDataFrame(
size ? data_buffer->data() : NULL, static_cast<size_t>(size));
if (state == StreamingUtf8Validator::INVALID ||
(state == StreamingUtf8Validator::VALID_MIDPOINT && final)) {
- return FailChannel("Could not decode a text frame as UTF-8.",
- kWebSocketErrorProtocolError,
- "Invalid UTF-8 in text frame");
+ FailChannel("Could not decode a text frame as UTF-8.",
+ kWebSocketErrorProtocolError, "Invalid UTF-8 in text frame");
+ return CHANNEL_DELETED;
}
receiving_text_message_ = !final;
DCHECK(!final || state == StreamingUtf8Validator::VALID_ENDPOINT);
@@ -1008,8 +993,9 @@ ChannelState WebSocketChannel::HandleDataFrame(
current_receive_quota_ -= size;
// Sends the received frame to the renderer process.
- return event_interface_->OnDataFrame(final, opcode_to_send,
- std::move(data_buffer), size);
+ event_interface_->OnDataFrame(final, opcode_to_send, std::move(data_buffer),
+ size);
+ return CHANNEL_ALIVE;
}
ChannelState WebSocketChannel::HandleCloseFrame(uint16_t code,
@@ -1069,7 +1055,8 @@ ChannelState WebSocketChannel::RespondToClosingHandshake() {
FROM_HERE, underlying_connection_close_timeout_,
base::Bind(&WebSocketChannel::CloseTimeout, base::Unretained(this)));
- return event_interface_->OnClosingHandshake();
+ event_interface_->OnClosingHandshake();
+ return CHANNEL_ALIVE;
}
ChannelState WebSocketChannel::SendFrameInternal(
@@ -1080,7 +1067,7 @@ ChannelState WebSocketChannel::SendFrameInternal(
DCHECK(state_ == CONNECTED || state_ == RECV_CLOSED);
DCHECK(stream_);
- std::unique_ptr<WebSocketFrame> frame(new WebSocketFrame(op_code));
+ auto frame = std::make_unique<WebSocketFrame>(op_code);
WebSocketFrameHeader& header = frame->header;
header.final = fin;
header.masked = true;
@@ -1093,19 +1080,19 @@ ChannelState WebSocketChannel::SendFrameInternal(
// TODO(ricea): Keep some statistics to work out the situation and adjust
// quota appropriately.
if (!data_to_send_next_)
- data_to_send_next_.reset(new SendBuffer);
+ data_to_send_next_ = std::make_unique<SendBuffer>();
data_to_send_next_->AddFrame(std::move(frame));
return CHANNEL_ALIVE;
}
- data_being_sent_.reset(new SendBuffer);
+ data_being_sent_ = std::make_unique<SendBuffer>();
data_being_sent_->AddFrame(std::move(frame));
return WriteFrames();
}
-ChannelState WebSocketChannel::FailChannel(const std::string& message,
- uint16_t code,
- const std::string& reason) {
+void WebSocketChannel::FailChannel(const std::string& message,
+ uint16_t code,
+ const std::string& reason) {
DCHECK_NE(FRESHLY_CONSTRUCTED, state_);
DCHECK_NE(CONNECTING, state_);
DCHECK_NE(CLOSED, state_);
@@ -1113,7 +1100,7 @@ ChannelState WebSocketChannel::FailChannel(const std::string& message,
// TODO(ricea): Logging.
if (state_ == CONNECTED) {
if (SendClose(code, reason) == CHANNEL_DELETED)
- return CHANNEL_DELETED;
+ return;
}
// Careful study of RFC6455 section 7.1.7 and 7.1.1 indicates the browser
@@ -1121,9 +1108,7 @@ ChannelState WebSocketChannel::FailChannel(const std::string& message,
// handshake.
stream_->Close();
SetState(CLOSED);
- ChannelState result = event_interface_->OnFailChannel(message);
- DCHECK_EQ(CHANNEL_DELETED, result);
- return result;
+ event_interface_->OnFailChannel(message);
}
ChannelState WebSocketChannel::SendClose(uint16_t code,
@@ -1136,10 +1121,10 @@ ChannelState WebSocketChannel::SendClose(uint16_t code,
// Special case: translate kWebSocketErrorNoStatusReceived into a Close
// frame with no payload.
DCHECK(reason.empty());
- body = new IOBuffer(0);
+ body = base::MakeRefCounted<IOBuffer>(0);
} else {
const size_t payload_length = kWebSocketCloseCodeLength + reason.length();
- body = new IOBuffer(payload_length);
+ body = base::MakeRefCounted<IOBuffer>(payload_length);
size = payload_length;
base::WriteBigEndian(body->data(), code);
static_assert(sizeof(code) == kWebSocketCloseCodeLength,
@@ -1147,10 +1132,8 @@ ChannelState WebSocketChannel::SendClose(uint16_t code,
std::copy(
reason.begin(), reason.end(), body->data() + kWebSocketCloseCodeLength);
}
- if (SendFrameInternal(true, WebSocketFrameHeader::kOpCodeClose,
- std::move(body), size) == CHANNEL_DELETED)
- return CHANNEL_DELETED;
- return CHANNEL_ALIVE;
+ return SendFrameInternal(true, WebSocketFrameHeader::kOpCodeClose,
+ std::move(body), size);
}
bool WebSocketChannel::ParseClose(scoped_refptr<IOBuffer> buffer,
@@ -1206,16 +1189,11 @@ bool WebSocketChannel::ParseClose(scoped_refptr<IOBuffer> buffer,
return false;
}
-ChannelState WebSocketChannel::DoDropChannel(bool was_clean,
- uint16_t code,
- const std::string& reason) {
- if (CHANNEL_DELETED ==
- notification_sender_->SendImmediately(event_interface_.get()))
- return CHANNEL_DELETED;
- ChannelState result =
- event_interface_->OnDropChannel(was_clean, code, reason);
- DCHECK_EQ(CHANNEL_DELETED, result);
- return result;
+void WebSocketChannel::DoDropChannel(bool was_clean,
+ uint16_t code,
+ const std::string& reason) {
+ notification_sender_->SendImmediately(event_interface_.get());
+ event_interface_->OnDropChannel(was_clean, code, reason);
}
void WebSocketChannel::CloseTimeout() {
diff --git a/chromium/net/websockets/websocket_channel.h b/chromium/net/websockets/websocket_channel.h
index 987b8231458..470a7775314 100644
--- a/chromium/net/websockets/websocket_channel.h
+++ b/chromium/net/websockets/websocket_channel.h
@@ -16,7 +16,7 @@
#include "base/containers/queue.h"
#include "base/i18n/streaming_utf8_validator.h"
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/net_export.h"
@@ -62,7 +62,7 @@ class NET_EXPORT WebSocketChannel {
// Methods which return a value of type ChannelState may delete |this|. If the
// return value is CHANNEL_DELETED, then the caller must return without making
// any further access to member variables or methods.
- using ChannelState = WebSocketEventInterface::ChannelState;
+ enum ChannelState { CHANNEL_ALIVE, CHANNEL_DELETED };
// Creates a new WebSocketChannel in an idle state.
// SendAddChannelRequest() must be called immediately afterwards to start the
@@ -289,12 +289,11 @@ class NET_EXPORT WebSocketChannel {
// Javascript. Javascript will see a Close code of AbnormalClosure (1006) with
// an empty reason string. If state_ is CONNECTED then a Close message is sent
// to the remote host containing the supplied |code| and |reason|. If the
- // stream is open, closes it and sets state_ to CLOSED. FailChannel() always
- // returns CHANNEL_DELETED. It is not valid to access any member variables or
- // methods after calling FailChannel().
- ChannelState FailChannel(const std::string& message,
- uint16_t code,
- const std::string& reason) WARN_UNUSED_RESULT;
+ // stream is open, closes it and sets state_ to CLOSED. This function deletes
+ // |this|.
+ void FailChannel(const std::string& message,
+ uint16_t code,
+ const std::string& reason);
// Sends a Close frame to Start the WebSocket Closing Handshake, or to respond
// to a Close frame from the server. As a special case, setting |code| to
@@ -317,12 +316,8 @@ class NET_EXPORT WebSocketChannel {
// Drop this channel.
// If there are pending opening handshake notifications, notify them
- // before dropping.
- //
- // Always returns CHANNEL_DELETED.
- ChannelState DoDropChannel(bool was_clean,
- uint16_t code,
- const std::string& reason);
+ // before dropping. This function deletes |this|.
+ void DoDropChannel(bool was_clean, uint16_t code, const std::string& reason);
// Called if the closing handshake times out. Closes the connection and
// informs the |event_interface_| if appropriate.
diff --git a/chromium/net/websockets/websocket_channel_test.cc b/chromium/net/websockets/websocket_channel_test.cc
index 57904f77d75..09cd4a44b7a 100644
--- a/chromium/net/websockets/websocket_channel_test.cc
+++ b/chromium/net/websockets/websocket_channel_test.cc
@@ -20,7 +20,6 @@
#include "base/callback.h"
#include "base/location.h"
#include "base/macros.h"
-#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
@@ -144,9 +143,9 @@ const int kVeryTinyTimeoutMillis = 1;
// Enough quota to pass any test.
const int64_t kPlentyOfQuota = INT_MAX;
-typedef WebSocketEventInterface::ChannelState ChannelState;
-const ChannelState CHANNEL_ALIVE = WebSocketEventInterface::CHANNEL_ALIVE;
-const ChannelState CHANNEL_DELETED = WebSocketEventInterface::CHANNEL_DELETED;
+using ChannelState = WebSocketChannel::ChannelState;
+constexpr ChannelState CHANNEL_ALIVE = WebSocketChannel::CHANNEL_ALIVE;
+constexpr ChannelState CHANNEL_DELETED = WebSocketChannel::CHANNEL_DELETED;
// This typedef mainly exists to avoid having to repeat the "NOLINT" incantation
// all over the place.
@@ -157,10 +156,10 @@ class MockWebSocketEventInterface : public WebSocketEventInterface {
public:
MockWebSocketEventInterface() = default;
- ChannelState OnDataFrame(bool fin,
- WebSocketMessageType type,
- scoped_refptr<IOBuffer> buffer,
- size_t buffer_size) override {
+ void OnDataFrame(bool fin,
+ WebSocketMessageType type,
+ scoped_refptr<IOBuffer> buffer,
+ size_t buffer_size) override {
const char* data = buffer ? buffer->data() : nullptr;
return OnDataFrameVector(fin, type,
std::vector<char>(data, data + buffer_size));
@@ -168,37 +167,34 @@ class MockWebSocketEventInterface : public WebSocketEventInterface {
MOCK_METHOD1(OnCreateURLRequest, void(URLRequest*));
MOCK_METHOD2(OnAddChannelResponse,
- ChannelState(const std::string&,
- const std::string&)); // NOLINT
+ void(const std::string&,
+ const std::string&)); // NOLINT
MOCK_METHOD3(OnDataFrameVector,
- ChannelState(bool,
- WebSocketMessageType,
- const std::vector<char>&)); // NOLINT
- MOCK_METHOD1(OnFlowControl, ChannelState(int64_t)); // NOLINT
- MOCK_METHOD0(OnClosingHandshake, ChannelState(void)); // NOLINT
- MOCK_METHOD1(OnFailChannel, ChannelState(const std::string&)); // NOLINT
+ void(bool,
+ WebSocketMessageType,
+ const std::vector<char>&)); // NOLINT
+ MOCK_METHOD1(OnFlowControl, void(int64_t)); // NOLINT
+ MOCK_METHOD0(OnClosingHandshake, void(void)); // NOLINT
+ MOCK_METHOD1(OnFailChannel, void(const std::string&)); // NOLINT
MOCK_METHOD3(OnDropChannel,
- ChannelState(bool, uint16_t, const std::string&)); // NOLINT
+ void(bool, uint16_t, const std::string&)); // NOLINT
- // We can't use GMock with scoped_ptr.
- ChannelState OnStartOpeningHandshake(
+ // We can't use GMock with std::unique_ptr.
+ void OnStartOpeningHandshake(
std::unique_ptr<WebSocketHandshakeRequestInfo>) override {
OnStartOpeningHandshakeCalled();
- return CHANNEL_ALIVE;
}
- ChannelState OnFinishOpeningHandshake(
+ void OnFinishOpeningHandshake(
std::unique_ptr<WebSocketHandshakeResponseInfo>) override {
OnFinishOpeningHandshakeCalled();
- return CHANNEL_ALIVE;
}
- ChannelState OnSSLCertificateError(
+ void OnSSLCertificateError(
std::unique_ptr<SSLErrorCallbacks> ssl_error_callbacks,
const GURL& url,
const SSLInfo& ssl_info,
bool fatal) override {
OnSSLCertificateErrorCalled(
ssl_error_callbacks.get(), url, ssl_info, fatal);
- return CHANNEL_ALIVE;
}
MOCK_METHOD0(OnStartOpeningHandshakeCalled, void()); // NOLINT
@@ -212,41 +208,27 @@ class MockWebSocketEventInterface : public WebSocketEventInterface {
// implementation but are not verifying how it is used.
class FakeWebSocketEventInterface : public WebSocketEventInterface {
void OnCreateURLRequest(URLRequest* request) override {}
- ChannelState OnAddChannelResponse(const std::string& selected_protocol,
- const std::string& extensions) override {
- return CHANNEL_ALIVE;
- }
- ChannelState OnDataFrame(bool fin,
- WebSocketMessageType type,
- scoped_refptr<IOBuffer> data,
- size_t data_size) override {
- return CHANNEL_ALIVE;
- }
- ChannelState OnFlowControl(int64_t quota) override { return CHANNEL_ALIVE; }
- ChannelState OnClosingHandshake() override { return CHANNEL_ALIVE; }
- ChannelState OnFailChannel(const std::string& message) override {
- return CHANNEL_DELETED;
- }
- ChannelState OnDropChannel(bool was_clean,
- uint16_t code,
- const std::string& reason) override {
- return CHANNEL_DELETED;
- }
- ChannelState OnStartOpeningHandshake(
- std::unique_ptr<WebSocketHandshakeRequestInfo> request) override {
- return CHANNEL_ALIVE;
- }
- ChannelState OnFinishOpeningHandshake(
- std::unique_ptr<WebSocketHandshakeResponseInfo> response) override {
- return CHANNEL_ALIVE;
- }
- ChannelState OnSSLCertificateError(
+ void OnAddChannelResponse(const std::string& selected_protocol,
+ const std::string& extensions) override {}
+ void OnDataFrame(bool fin,
+ WebSocketMessageType type,
+ scoped_refptr<IOBuffer> data,
+ size_t data_size) override {}
+ void OnFlowControl(int64_t quota) override {}
+ void OnClosingHandshake() override {}
+ void OnFailChannel(const std::string& message) override {}
+ void OnDropChannel(bool was_clean,
+ uint16_t code,
+ const std::string& reason) override {}
+ void OnStartOpeningHandshake(
+ std::unique_ptr<WebSocketHandshakeRequestInfo> request) override {}
+ void OnFinishOpeningHandshake(
+ std::unique_ptr<WebSocketHandshakeResponseInfo> response) override {}
+ void OnSSLCertificateError(
std::unique_ptr<SSLErrorCallbacks> ssl_error_callbacks,
const GURL& url,
const SSLInfo& ssl_info,
- bool fatal) override {
- return CHANNEL_ALIVE;
- }
+ bool fatal) override {}
};
// This fake WebSocketStream is for tests that require a WebSocketStream but are
@@ -343,15 +325,14 @@ std::vector<std::unique_ptr<WebSocketFrame>> CreateFrameVector(
result_frames.reserve(N);
for (size_t i = 0; i < N; ++i) {
const InitFrame& source_frame = source_frames[i];
- std::unique_ptr<WebSocketFrame> result_frame(
- new WebSocketFrame(source_frame.opcode));
+ auto result_frame = std::make_unique<WebSocketFrame>(source_frame.opcode);
size_t frame_length = source_frame.data ? strlen(source_frame.data) : 0;
WebSocketFrameHeader& result_header = result_frame->header;
result_header.final = (source_frame.final == FINAL_FRAME);
result_header.masked = (source_frame.masked == MASKED);
result_header.payload_length = frame_length;
if (source_frame.data) {
- result_frame->data = new IOBuffer(frame_length);
+ result_frame->data = base::MakeRefCounted<IOBuffer>(frame_length);
memcpy(result_frame->data->data(), source_frame.data, frame_length);
}
result_frames.push_back(std::move(result_frame));
@@ -447,12 +428,6 @@ template <size_t N>
// A GoogleMock action to run a Closure.
ACTION_P(InvokeClosure, closure) { closure.Run(); }
-// A GoogleMock action to run a Closure and return CHANNEL_DELETED.
-ACTION_P(InvokeClosureReturnDeleted, closure) {
- closure.Run();
- return WebSocketEventInterface::CHANNEL_DELETED;
-}
-
// A FakeWebSocketStream whose ReadFrames() function returns data.
class ReadableFakeWebSocketStream : public FakeWebSocketStream {
public:
@@ -752,7 +727,7 @@ std::vector<char> AsVector(const base::StringPiece& s) {
// convenient to be able to specify data as a string, but the
// WebSocketEventInterface requires the IOBuffer type.
scoped_refptr<IOBuffer> AsIOBuffer(const base::StringPiece& s) {
- scoped_refptr<IOBuffer> buffer(new IOBuffer(s.size()));
+ auto buffer = base::MakeRefCounted<IOBuffer>(s.size());
std::copy(s.begin(), s.end(), buffer->data());
return buffer;
}
@@ -767,13 +742,13 @@ class FakeSSLErrorCallbacks
// Base class for all test fixtures.
class WebSocketChannelTest : public ::testing::Test {
protected:
- WebSocketChannelTest() : stream_(new FakeWebSocketStream) {}
+ WebSocketChannelTest() : stream_(std::make_unique<FakeWebSocketStream>()) {}
// Creates a new WebSocketChannel and connects it, using the settings stored
// in |connect_data_|.
void CreateChannelAndConnect() {
- channel_.reset(new WebSocketChannel(CreateEventInterface(),
- &connect_data_.url_request_context));
+ channel_ = std::make_unique<WebSocketChannel>(
+ CreateEventInterface(), &connect_data_.url_request_context);
channel_->SendAddChannelRequestForTesting(
connect_data_.socket_url, connect_data_.requested_subprotocols,
connect_data_.origin, connect_data_.site_for_cookies, "",
@@ -852,118 +827,16 @@ enum EventInterfaceCall {
EVENT_ON_SSL_CERTIFICATE_ERROR = 0x100,
};
-class WebSocketChannelDeletingTest : public WebSocketChannelTest {
- public:
- ChannelState DeleteIfDeleting(EventInterfaceCall call) {
- if (deleting_ & call) {
- channel_.reset();
- return CHANNEL_DELETED;
- } else {
- return CHANNEL_ALIVE;
- }
- }
-
- protected:
- WebSocketChannelDeletingTest()
- : deleting_(EVENT_ON_ADD_CHANNEL_RESPONSE | EVENT_ON_DATA_FRAME |
- EVENT_ON_FLOW_CONTROL |
- EVENT_ON_CLOSING_HANDSHAKE |
- EVENT_ON_FAIL_CHANNEL |
- EVENT_ON_DROP_CHANNEL |
- EVENT_ON_START_OPENING_HANDSHAKE |
- EVENT_ON_FINISH_OPENING_HANDSHAKE |
- EVENT_ON_SSL_CERTIFICATE_ERROR) {}
- // Create a ChannelDeletingFakeWebSocketEventInterface. Defined out-of-line to
- // avoid circular dependency.
- std::unique_ptr<WebSocketEventInterface> CreateEventInterface() override;
-
- // Tests can set deleting_ to a bitmap of EventInterfaceCall members that they
- // want to cause Channel deletion. The default is for all calls to cause
- // deletion.
- int deleting_;
-};
-
-// A FakeWebSocketEventInterface that deletes the WebSocketChannel on failure to
-// connect.
-class ChannelDeletingFakeWebSocketEventInterface
- : public FakeWebSocketEventInterface {
- public:
- ChannelDeletingFakeWebSocketEventInterface(
- WebSocketChannelDeletingTest* fixture)
- : fixture_(fixture) {}
-
- ChannelState OnAddChannelResponse(const std::string& selected_protocol,
- const std::string& extensions) override {
- return fixture_->DeleteIfDeleting(EVENT_ON_ADD_CHANNEL_RESPONSE);
- }
-
- ChannelState OnDataFrame(bool fin,
- WebSocketMessageType type,
- scoped_refptr<IOBuffer> data,
- size_t data_size) override {
- return fixture_->DeleteIfDeleting(EVENT_ON_DATA_FRAME);
- }
-
- ChannelState OnFlowControl(int64_t quota) override {
- return fixture_->DeleteIfDeleting(EVENT_ON_FLOW_CONTROL);
- }
-
- ChannelState OnClosingHandshake() override {
- return fixture_->DeleteIfDeleting(EVENT_ON_CLOSING_HANDSHAKE);
- }
-
- ChannelState OnFailChannel(const std::string& message) override {
- return fixture_->DeleteIfDeleting(EVENT_ON_FAIL_CHANNEL);
- }
-
- ChannelState OnDropChannel(bool was_clean,
- uint16_t code,
- const std::string& reason) override {
- return fixture_->DeleteIfDeleting(EVENT_ON_DROP_CHANNEL);
- }
-
- ChannelState OnStartOpeningHandshake(
- std::unique_ptr<WebSocketHandshakeRequestInfo> request) override {
- return fixture_->DeleteIfDeleting(EVENT_ON_START_OPENING_HANDSHAKE);
- }
- ChannelState OnFinishOpeningHandshake(
- std::unique_ptr<WebSocketHandshakeResponseInfo> response) override {
- return fixture_->DeleteIfDeleting(EVENT_ON_FINISH_OPENING_HANDSHAKE);
- }
- ChannelState OnSSLCertificateError(
- std::unique_ptr<SSLErrorCallbacks> ssl_error_callbacks,
- const GURL& url,
- const SSLInfo& ssl_info,
- bool fatal) override {
- return fixture_->DeleteIfDeleting(EVENT_ON_SSL_CERTIFICATE_ERROR);
- }
-
- private:
- // A pointer to the test fixture. Owned by the test harness; this object will
- // be deleted before it is.
- WebSocketChannelDeletingTest* fixture_;
-};
-
-std::unique_ptr<WebSocketEventInterface>
-WebSocketChannelDeletingTest::CreateEventInterface() {
- return std::make_unique<ChannelDeletingFakeWebSocketEventInterface>(this);
-}
-
// Base class for tests which verify that EventInterface methods are called
// appropriately.
class WebSocketChannelEventInterfaceTest : public WebSocketChannelTest {
protected:
WebSocketChannelEventInterfaceTest()
- : event_interface_(new StrictMock<MockWebSocketEventInterface>) {
- DefaultValue<ChannelState>::Set(CHANNEL_ALIVE);
- ON_CALL(*event_interface_, OnDropChannel(_, _, _))
- .WillByDefault(Return(CHANNEL_DELETED));
- ON_CALL(*event_interface_, OnFailChannel(_))
- .WillByDefault(Return(CHANNEL_DELETED));
+ : event_interface_(
+ std::make_unique<StrictMock<MockWebSocketEventInterface>>()) {
}
~WebSocketChannelEventInterfaceTest() override {
- DefaultValue<ChannelState>::Clear();
}
// Tests using this fixture must set expectations on the event_interface_ mock
@@ -971,7 +844,7 @@ class WebSocketChannelEventInterfaceTest : public WebSocketChannelTest {
// CreateChannelAndConnectSuccessfully(). This will only work once per test
// case, but once should be enough.
std::unique_ptr<WebSocketEventInterface> CreateEventInterface() override {
- return base::WrapUnique(event_interface_.release());
+ return std::move(event_interface_);
}
std::unique_ptr<MockWebSocketEventInterface> event_interface_;
@@ -982,7 +855,7 @@ class WebSocketChannelEventInterfaceTest : public WebSocketChannelTest {
class WebSocketChannelStreamTest : public WebSocketChannelTest {
protected:
WebSocketChannelStreamTest()
- : mock_stream_(new StrictMock<MockWebSocketStream>) {}
+ : mock_stream_(std::make_unique<StrictMock<MockWebSocketStream>>()) {}
void CreateChannelAndConnectSuccessfully() override {
set_stream(std::move(mock_stream_));
@@ -1064,294 +937,6 @@ TEST_F(WebSocketChannelTest, SendFlowControlDuringHandshakeOkay) {
ASSERT_EQ(CHANNEL_ALIVE, channel_->SendFlowControl(65536));
}
-// Any WebSocketEventInterface methods can delete the WebSocketChannel and
-// return CHANNEL_DELETED. The WebSocketChannelDeletingTests are intended to
-// verify that there are no use-after-free bugs when this happens. Problems will
-// probably only be found when running under Address Sanitizer or a similar
-// tool.
-TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseFail) {
- CreateChannelAndConnect();
- EXPECT_TRUE(channel_);
- connect_data_.argument_saver.connect_delegate->OnFailure("bye");
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-// Deletion is possible (due to IPC failure) even if the connect succeeds.
-TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseSuccess) {
- CreateChannelAndConnectSuccessfully();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, OnDataFrameSync) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
- static const InitFrame frames[] = {
- {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
- stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(std::move(stream));
- deleting_ = EVENT_ON_DATA_FRAME;
-
- CreateChannelAndConnectSuccessfully();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, OnDataFrameAsync) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
- static const InitFrame frames[] = {
- {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
- stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
- set_stream(std::move(stream));
- deleting_ = EVENT_ON_DATA_FRAME;
-
- CreateChannelAndConnectSuccessfully();
- EXPECT_TRUE(channel_);
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, OnFlowControlAfterConnect) {
- deleting_ = EVENT_ON_FLOW_CONTROL;
-
- CreateChannelAndConnectSuccessfully();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, OnFlowControlAfterSend) {
- set_stream(std::make_unique<WriteableFakeWebSocketStream>());
- // Avoid deleting the channel yet.
- deleting_ = EVENT_ON_FAIL_CHANNEL | EVENT_ON_DROP_CHANNEL;
- CreateChannelAndConnectSuccessfully();
- ASSERT_TRUE(channel_);
- deleting_ = EVENT_ON_FLOW_CONTROL;
- channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText,
- AsIOBuffer(std::string(kDefaultInitialQuota, 'B')),
- kDefaultInitialQuota);
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, OnClosingHandshakeSync) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
- static const InitFrame frames[] = {
- {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
- NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}};
- stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(std::move(stream));
- deleting_ = EVENT_ON_CLOSING_HANDSHAKE;
- CreateChannelAndConnectSuccessfully();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, OnClosingHandshakeAsync) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
- static const InitFrame frames[] = {
- {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
- NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}};
- stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
- set_stream(std::move(stream));
- deleting_ = EVENT_ON_CLOSING_HANDSHAKE;
- CreateChannelAndConnectSuccessfully();
- ASSERT_TRUE(channel_);
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, OnDropChannelWriteError) {
- set_stream(std::make_unique<UnWriteableFakeWebSocketStream>());
- deleting_ = EVENT_ON_DROP_CHANNEL;
- CreateChannelAndConnectSuccessfully();
- ASSERT_TRUE(channel_);
- channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText,
- AsIOBuffer("this will fail"), 14U);
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, OnDropChannelReadError) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
- stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC,
- ERR_FAILED);
- set_stream(std::move(stream));
- deleting_ = EVENT_ON_DROP_CHANNEL;
- CreateChannelAndConnectSuccessfully();
- ASSERT_TRUE(channel_);
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, OnNotifyStartOpeningHandshakeError) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
- static const InitFrame frames[] = {
- {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
- stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
- set_stream(std::move(stream));
- deleting_ = EVENT_ON_START_OPENING_HANDSHAKE;
-
- CreateChannelAndConnectSuccessfully();
- ASSERT_TRUE(channel_);
- channel_->OnStartOpeningHandshake(
- std::unique_ptr<WebSocketHandshakeRequestInfo>(
- new WebSocketHandshakeRequestInfo(GURL("http://www.example.com/"),
- base::Time())));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, OnNotifyFinishOpeningHandshakeError) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
- static const InitFrame frames[] = {
- {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
- stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
- set_stream(std::move(stream));
- deleting_ = EVENT_ON_FINISH_OPENING_HANDSHAKE;
-
- CreateChannelAndConnectSuccessfully();
- ASSERT_TRUE(channel_);
- scoped_refptr<HttpResponseHeaders> response_headers(
- new HttpResponseHeaders(""));
- channel_->OnFinishOpeningHandshake(
- std::make_unique<WebSocketHandshakeResponseInfo>(
- GURL("http://www.example.com/"), 200, "OK", response_headers,
- base::Time()));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, FailChannelInSendFrame) {
- set_stream(std::make_unique<WriteableFakeWebSocketStream>());
- deleting_ = EVENT_ON_FAIL_CHANNEL;
- CreateChannelAndConnectSuccessfully();
- ASSERT_TRUE(channel_);
- channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText,
- AsIOBuffer(std::string(kDefaultInitialQuota * 2, 'T')),
- kDefaultInitialQuota * 2);
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, FailChannelInOnReadDone) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
- stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC,
- ERR_WS_PROTOCOL_ERROR);
- set_stream(std::move(stream));
- deleting_ = EVENT_ON_FAIL_CHANNEL;
- CreateChannelAndConnectSuccessfully();
- ASSERT_TRUE(channel_);
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, FailChannelDueToMaskedFrame) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
- static const InitFrame frames[] = {
- {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"}};
- stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(std::move(stream));
- deleting_ = EVENT_ON_FAIL_CHANNEL;
-
- CreateChannelAndConnectSuccessfully();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, FailChannelDueToBadControlFrame) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
- static const InitFrame frames[] = {
- {FINAL_FRAME, 0xF, NOT_MASKED, ""}};
- stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(std::move(stream));
- deleting_ = EVENT_ON_FAIL_CHANNEL;
-
- CreateChannelAndConnectSuccessfully();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-// Version of above test with null data.
-TEST_F(WebSocketChannelDeletingTest, FailChannelDueToBadControlFrameNull) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
- static const InitFrame frames[] = {{FINAL_FRAME, 0xF, NOT_MASKED, nullptr}};
- stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(std::move(stream));
- deleting_ = EVENT_ON_FAIL_CHANNEL;
-
- CreateChannelAndConnectSuccessfully();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, FailChannelDueToPongAfterClose) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
- static const InitFrame frames[] = {
- {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED,
- CLOSE_DATA(NORMAL_CLOSURE, "Success")},
- {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, ""}};
- stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(std::move(stream));
- deleting_ = EVENT_ON_FAIL_CHANNEL;
-
- CreateChannelAndConnectSuccessfully();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, FailChannelDueToPongAfterCloseNull) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
- static const InitFrame frames[] = {
- {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED,
- CLOSE_DATA(NORMAL_CLOSURE, "Success")},
- {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, nullptr}};
- stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(std::move(stream));
- deleting_ = EVENT_ON_FAIL_CHANNEL;
-
- CreateChannelAndConnectSuccessfully();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, FailChannelDueToUnknownOpCode) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
- static const InitFrame frames[] = {{FINAL_FRAME, 0x7, NOT_MASKED, ""}};
- stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(std::move(stream));
- deleting_ = EVENT_ON_FAIL_CHANNEL;
-
- CreateChannelAndConnectSuccessfully();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, FailChannelDueToUnknownOpCodeNull) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
- static const InitFrame frames[] = {{FINAL_FRAME, 0x7, NOT_MASKED, nullptr}};
- stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(std::move(stream));
- deleting_ = EVENT_ON_FAIL_CHANNEL;
-
- CreateChannelAndConnectSuccessfully();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
-TEST_F(WebSocketChannelDeletingTest, FailChannelDueInvalidCloseReason) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
- static const InitFrame frames[] = {
- {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
- NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "\xFF")}};
- stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
- set_stream(std::move(stream));
- deleting_ = EVENT_ON_FAIL_CHANNEL;
-
- CreateChannelAndConnectSuccessfully();
- EXPECT_EQ(nullptr, channel_.get());
-}
-
TEST_F(WebSocketChannelEventInterfaceTest, ConnectSuccessReported) {
// false means success.
EXPECT_CALL(*event_interface_, OnAddChannelResponse("", ""));
@@ -1403,8 +988,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ExtensionsPassed) {
// which case they will be available as soon as ReadFrames() is called the first
// time.
TEST_F(WebSocketChannelEventInterfaceTest, DataLeftFromHandshake) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
@@ -1424,8 +1008,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, DataLeftFromHandshake) {
// A remote server could accept the handshake, but then immediately send a
// Close frame.
TEST_F(WebSocketChannelEventInterfaceTest, CloseAfterHandshake) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
NOT_MASKED, CLOSE_DATA(SERVER_ERROR, "Internal Server Error")}};
@@ -1450,8 +1033,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, CloseAfterHandshake) {
// A remote server could close the connection immediately after sending the
// handshake response (most likely a bug in the server).
TEST_F(WebSocketChannelEventInterfaceTest, ConnectionCloseAfterHandshake) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC,
ERR_CONNECTION_CLOSED);
set_stream(std::move(stream));
@@ -1467,8 +1049,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ConnectionCloseAfterHandshake) {
}
TEST_F(WebSocketChannelEventInterfaceTest, NormalAsyncRead) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
// We use this checkpoint object to verify that the callback isn't called
@@ -1496,8 +1077,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, NormalAsyncRead) {
// Extra data can arrive while a read is being processed, resulting in the next
// read completing synchronously.
TEST_F(WebSocketChannelEventInterfaceTest, AsyncThenSyncRead) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames1[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}};
static const InitFrame frames2[] = {
@@ -1524,8 +1104,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, AsyncThenSyncRead) {
// Data frames are delivered the same regardless of how many reads they arrive
// as.
TEST_F(WebSocketChannelEventInterfaceTest, FragmentedMessage) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
// Here we have one message which arrived in five frames split across three
// reads. It may have been reframed on arrival, but this class doesn't care
// about that.
@@ -1576,8 +1155,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, FragmentedMessage) {
// A message can consist of one frame with null payload.
TEST_F(WebSocketChannelEventInterfaceTest, NullMessage) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, nullptr}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
@@ -1592,8 +1170,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, NullMessage) {
// Connection closed by the remote host without a closing handshake.
TEST_F(WebSocketChannelEventInterfaceTest, AsyncAbnormalClosure) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC,
ERR_CONNECTION_CLOSED);
set_stream(std::move(stream));
@@ -1611,8 +1188,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, AsyncAbnormalClosure) {
// A connection reset should produce the same event as an unexpected closure.
TEST_F(WebSocketChannelEventInterfaceTest, ConnectionReset) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC,
ERR_CONNECTION_RESET);
set_stream(std::move(stream));
@@ -1630,8 +1206,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ConnectionReset) {
// RFC6455 5.1 "A client MUST close a connection if it detects a masked frame."
TEST_F(WebSocketChannelEventInterfaceTest, MaskedFramesAreRejected) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"}};
@@ -1654,8 +1229,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, MaskedFramesAreRejected) {
// RFC6455 5.2 "If an unknown opcode is received, the receiving endpoint MUST
// _Fail the WebSocket Connection_."
TEST_F(WebSocketChannelEventInterfaceTest, UnknownOpCodeIsRejected) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {{FINAL_FRAME, 4, NOT_MASKED, "HELLO"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
@@ -1675,8 +1249,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, UnknownOpCodeIsRejected) {
// RFC6455 5.4 "Control frames ... MAY be injected in the middle of a
// fragmented message."
TEST_F(WebSocketChannelEventInterfaceTest, ControlFrameInDataMessage) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
// We have one message of type Text split into two frames. In the middle is a
// control message of type Pong.
static const InitFrame frames1[] = {
@@ -1711,8 +1284,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ControlFrameInDataMessage) {
// It seems redundant to repeat the entirety of the above test, so just test a
// Pong with null data.
TEST_F(WebSocketChannelEventInterfaceTest, PongWithNullData) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, nullptr}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
@@ -1727,8 +1299,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, PongWithNullData) {
// If a frame has an invalid header, then the connection is closed and
// subsequent frames must not trigger events.
TEST_F(WebSocketChannelEventInterfaceTest, FrameAfterInvalidFrame) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"},
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, " WORLD"}};
@@ -1907,8 +1478,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, OnDropChannelCalledOnce) {
// When the remote server sends a Close frame with an empty payload,
// WebSocketChannel should report code 1005, kWebSocketErrorNoStatusReceived.
TEST_F(WebSocketChannelEventInterfaceTest, CloseWithNoPayloadGivesStatus1005) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, ""}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
@@ -1927,8 +1497,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, CloseWithNoPayloadGivesStatus1005) {
// A version of the above test with null payload.
TEST_F(WebSocketChannelEventInterfaceTest,
CloseWithNullPayloadGivesStatus1005) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, nullptr}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
@@ -1947,8 +1516,7 @@ TEST_F(WebSocketChannelEventInterfaceTest,
// If ReadFrames() returns ERR_WS_PROTOCOL_ERROR, then the connection must be
// failed.
TEST_F(WebSocketChannelEventInterfaceTest, SyncProtocolErrorGivesStatus1002) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC,
ERR_WS_PROTOCOL_ERROR);
set_stream(std::move(stream));
@@ -1962,8 +1530,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, SyncProtocolErrorGivesStatus1002) {
// Async version of above test.
TEST_F(WebSocketChannelEventInterfaceTest, AsyncProtocolErrorGivesStatus1002) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC,
ERR_WS_PROTOCOL_ERROR);
set_stream(std::move(stream));
@@ -1986,9 +1553,8 @@ TEST_F(WebSocketChannelEventInterfaceTest, StartHandshakeRequest) {
CreateChannelAndConnectSuccessfully();
- std::unique_ptr<WebSocketHandshakeRequestInfo> request_info(
- new WebSocketHandshakeRequestInfo(GURL("ws://www.example.com/"),
- base::Time()));
+ auto request_info = std::make_unique<WebSocketHandshakeRequestInfo>(
+ GURL("ws://www.example.com/"), base::Time());
connect_data_.argument_saver.connect_delegate->OnStartOpeningHandshake(
std::move(request_info));
@@ -2005,11 +1571,9 @@ TEST_F(WebSocketChannelEventInterfaceTest, FinishHandshakeRequest) {
CreateChannelAndConnectSuccessfully();
- scoped_refptr<HttpResponseHeaders> response_headers(
- new HttpResponseHeaders(""));
- std::unique_ptr<WebSocketHandshakeResponseInfo> response_info(
- new WebSocketHandshakeResponseInfo(GURL("ws://www.example.com/"), 200,
- "OK", response_headers, base::Time()));
+ auto response_headers = base::MakeRefCounted<HttpResponseHeaders>("");
+ auto response_info = std::make_unique<WebSocketHandshakeResponseInfo>(
+ GURL("ws://www.example.com/"), 200, "OK", response_headers, base::Time());
connect_data_.argument_saver.connect_delegate->OnFinishOpeningHandshake(
std::move(response_info));
base::RunLoop().RunUntilIdle();
@@ -2028,13 +1592,11 @@ TEST_F(WebSocketChannelEventInterfaceTest, FailJustAfterHandshake) {
WebSocketStream::ConnectDelegate* connect_delegate =
connect_data_.argument_saver.connect_delegate.get();
GURL url("ws://www.example.com/");
- std::unique_ptr<WebSocketHandshakeRequestInfo> request_info(
- new WebSocketHandshakeRequestInfo(url, base::Time()));
- scoped_refptr<HttpResponseHeaders> response_headers(
- new HttpResponseHeaders(""));
- std::unique_ptr<WebSocketHandshakeResponseInfo> response_info(
- new WebSocketHandshakeResponseInfo(url, 200, "OK", response_headers,
- base::Time()));
+ auto request_info =
+ std::make_unique<WebSocketHandshakeRequestInfo>(url, base::Time());
+ auto response_headers = base::MakeRefCounted<HttpResponseHeaders>("");
+ auto response_info = std::make_unique<WebSocketHandshakeResponseInfo>(
+ url, 200, "OK", response_headers, base::Time());
connect_delegate->OnStartOpeningHandshake(std::move(request_info));
connect_delegate->OnFinishOpeningHandshake(std::move(response_info));
@@ -2045,8 +1607,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, FailJustAfterHandshake) {
// Any frame after close is invalid. This test uses a Text frame. See also
// test "PingAfterCloseIfRejected".
TEST_F(WebSocketChannelEventInterfaceTest, DataAfterCloseIsRejected) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED,
CLOSE_DATA(NORMAL_CLOSURE, "OK")},
@@ -2069,8 +1630,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, DataAfterCloseIsRejected) {
// A Close frame with a one-byte payload elicits a specific console error
// message.
TEST_F(WebSocketChannelEventInterfaceTest, OneByteClosePayloadMessage) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, "\x03"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
@@ -2088,8 +1648,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, OneByteClosePayloadMessage) {
// A Close frame with a reserved status code also elicits a specific console
// error message.
TEST_F(WebSocketChannelEventInterfaceTest, ClosePayloadReservedStatusMessage) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
NOT_MASKED, CLOSE_DATA(ABNORMAL_CLOSURE, "Not valid on wire")}};
@@ -2108,8 +1667,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ClosePayloadReservedStatusMessage) {
// A Close frame with invalid UTF-8 also elicits a specific console error
// message.
TEST_F(WebSocketChannelEventInterfaceTest, ClosePayloadInvalidReason) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "\xFF")}};
@@ -2128,8 +1686,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ClosePayloadInvalidReason) {
// The reserved bits must all be clear on received frames. Extensions should
// clear the bits when they are set correctly before passing on the frame.
TEST_F(WebSocketChannelEventInterfaceTest, ReservedBitsMustNotBeSet) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText,
NOT_MASKED, "sakana"}};
@@ -2155,8 +1712,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, ReservedBitsMustNotBeSet) {
// response to the client Close message is received.
TEST_F(WebSocketChannelEventInterfaceTest,
ClientInitiatedClosingHandshakeTimesOut) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC,
ERR_IO_PENDING);
set_stream(std::move(stream));
@@ -2171,7 +1727,7 @@ TEST_F(WebSocketChannelEventInterfaceTest,
EXPECT_CALL(checkpoint, Call(1));
EXPECT_CALL(*event_interface_,
OnDropChannel(false, kWebSocketErrorAbnormalClosure, _))
- .WillOnce(InvokeClosureReturnDeleted(completion.closure()));
+ .WillOnce(InvokeClosure(completion.closure()));
}
CreateChannelAndConnectSuccessfully();
// OneShotTimer is not very friendly to testing; there is no apparent way to
@@ -2191,8 +1747,7 @@ TEST_F(WebSocketChannelEventInterfaceTest,
// message is received but the connection isn't closed by the remote host.
TEST_F(WebSocketChannelEventInterfaceTest,
ServerInitiatedClosingHandshakeTimesOut) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose,
NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}};
@@ -2208,7 +1763,7 @@ TEST_F(WebSocketChannelEventInterfaceTest,
EXPECT_CALL(*event_interface_, OnClosingHandshake());
EXPECT_CALL(*event_interface_,
OnDropChannel(false, kWebSocketErrorAbnormalClosure, _))
- .WillOnce(InvokeClosureReturnDeleted(completion.closure()));
+ .WillOnce(InvokeClosure(completion.closure()));
}
CreateChannelAndConnectSuccessfully();
channel_->SetClosingHandshakeTimeoutForTesting(
@@ -2339,8 +1894,7 @@ TEST_F(WebSocketChannelStreamTest, ReadFramesNotCalledUntilQuotaAvailable) {
// A message that needs to be split into frames to fit within quota should
// maintain correct semantics.
TEST_F(WebSocketChannelFlowControlTest, SingleFrameMessageSplitSync) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
@@ -2370,8 +1924,7 @@ TEST_F(WebSocketChannelFlowControlTest, SingleFrameMessageSplitSync) {
// The code path for async messages is slightly different, so test it
// separately.
TEST_F(WebSocketChannelFlowControlTest, SingleFrameMessageSplitAsync) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames);
@@ -2412,8 +1965,7 @@ TEST_F(WebSocketChannelFlowControlTest, SingleFrameMessageSplitAsync) {
// necessary. The complexity/performance tradeoffs here need further
// examination.
TEST_F(WebSocketChannelFlowControlTest, MultipleFrameSplit) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText,
NOT_MASKED, "FIRST FRAME IS 25 BYTES. "},
@@ -2455,8 +2007,7 @@ TEST_F(WebSocketChannelFlowControlTest, MultipleFrameSplit) {
// An empty message handled when we are out of quota must not be delivered
// out-of-order with respect to other messages.
TEST_F(WebSocketChannelFlowControlTest, EmptyMessageNoQuota) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED,
"FIRST MESSAGE"},
@@ -2490,8 +2041,7 @@ TEST_F(WebSocketChannelFlowControlTest, EmptyMessageNoQuota) {
// A close frame should not overtake data frames.
TEST_F(WebSocketChannelFlowControlTest, CloseFrameShouldNotOvertakeDataFrames) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED,
"FIRST "},
@@ -2543,8 +2093,7 @@ TEST_F(WebSocketChannelFlowControlTest, CloseFrameShouldNotOvertakeDataFrames) {
// SendFlowControl calls should not trigger multiple close respond frames.
TEST_F(WebSocketChannelFlowControlTest, DoNotSendMultipleCloseRespondFrames) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static constexpr InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED,
"FIRST SECOND"},
@@ -2970,17 +2519,16 @@ TEST_F(WebSocketChannelStreamTest, WrittenBinaryFramesAre8BitClean) {
// Test the read path for 8-bit cleanliness as well.
TEST_F(WebSocketChannelEventInterfaceTest, ReadBinaryFramesAre8BitClean) {
- std::unique_ptr<WebSocketFrame> frame(
- new WebSocketFrame(WebSocketFrameHeader::kOpCodeBinary));
+ auto frame =
+ std::make_unique<WebSocketFrame>(WebSocketFrameHeader::kOpCodeBinary);
WebSocketFrameHeader& frame_header = frame->header;
frame_header.final = true;
frame_header.payload_length = kBinaryBlobSize;
- frame->data = new IOBuffer(kBinaryBlobSize);
+ frame->data = base::MakeRefCounted<IOBuffer>(kBinaryBlobSize);
memcpy(frame->data->data(), kBinaryBlob, kBinaryBlobSize);
std::vector<std::unique_ptr<WebSocketFrame>> frames;
frames.push_back(std::move(frame));
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
stream->PrepareRawReadFrames(ReadableFakeWebSocketStream::SYNC, OK,
std::move(frames));
set_stream(std::move(stream));
@@ -3094,8 +2642,7 @@ TEST_F(WebSocketChannelSendUtf8Test, ValidateMultipleTextMessages) {
// UTF-8 validation is enforced on received Text frames.
TEST_F(WebSocketChannelEventInterfaceTest, ReceivedInvalidUtf8) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "\xff"}};
stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames);
@@ -3283,8 +2830,7 @@ TEST_F(WebSocketChannelReceiveUtf8Test, ValidateMultipleReceived) {
// A new data message cannot start in the middle of another data message.
TEST_F(WebSocketChannelEventInterfaceTest, BogusContinuation) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeBinary,
NOT_MASKED, "frame1"},
@@ -3308,8 +2854,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, BogusContinuation) {
// A new message cannot start with a Continuation frame.
TEST_F(WebSocketChannelEventInterfaceTest, MessageStartingWithContinuation) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation,
NOT_MASKED, "continuation"}};
@@ -3327,8 +2872,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, MessageStartingWithContinuation) {
// A frame passed to the renderer must be either non-empty or have the final bit
// set.
TEST_F(WebSocketChannelEventInterfaceTest, DataFramesNonEmptyOrFinal) {
- std::unique_ptr<ReadableFakeWebSocketStream> stream(
- new ReadableFakeWebSocketStream);
+ auto stream = std::make_unique<ReadableFakeWebSocketStream>();
static const InitFrame frames[] = {
{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, ""},
{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation,
@@ -3353,8 +2897,7 @@ TEST_F(WebSocketChannelEventInterfaceTest, OnSSLCertificateErrorCalled) {
connect_data_.socket_url = wss_url;
const SSLInfo ssl_info;
const bool fatal = true;
- std::unique_ptr<WebSocketEventInterface::SSLErrorCallbacks> fake_callbacks(
- new FakeSSLErrorCallbacks);
+ auto fake_callbacks = std::make_unique<FakeSSLErrorCallbacks>();
EXPECT_CALL(*event_interface_,
OnSSLCertificateErrorCalled(NotNull(), wss_url, _, fatal));
diff --git a/chromium/net/websockets/websocket_deflate_stream.cc b/chromium/net/websockets/websocket_deflate_stream.cc
index 6e21237ef08..dd048a85c6c 100644
--- a/chromium/net/websockets/websocket_deflate_stream.cc
+++ b/chromium/net/websockets/websocket_deflate_stream.cc
@@ -7,14 +7,13 @@
#include <stdint.h>
#include <algorithm>
-#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/logging.h"
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
@@ -218,7 +217,7 @@ int WebSocketDeflateStream::AppendCompressedFrame(
<< "deflater_.GetOutput() returns an error.";
return ERR_WS_PROTOCOL_ERROR;
}
- std::unique_ptr<WebSocketFrame> compressed(new WebSocketFrame(opcode));
+ auto compressed = std::make_unique<WebSocketFrame>(opcode);
compressed->header.CopyFrom(header);
compressed->header.opcode = opcode;
compressed->header.final = header.final;
@@ -269,7 +268,7 @@ int WebSocketDeflateStream::AppendPossiblyCompressedMessage(
frames->clear();
return OK;
}
- std::unique_ptr<WebSocketFrame> compressed(new WebSocketFrame(opcode));
+ auto compressed = std::make_unique<WebSocketFrame>(opcode);
compressed->header.CopyFrom((*frames)[0]->header);
compressed->header.opcode = opcode;
compressed->header.final = true;
@@ -343,8 +342,8 @@ int WebSocketDeflateStream::Inflate(
while (inflater_.CurrentOutputSize() >= kChunkSize ||
frame->header.final) {
size_t size = std::min(kChunkSize, inflater_.CurrentOutputSize());
- std::unique_ptr<WebSocketFrame> inflated(
- new WebSocketFrame(WebSocketFrameHeader::kOpCodeText));
+ auto inflated =
+ std::make_unique<WebSocketFrame>(WebSocketFrameHeader::kOpCodeText);
scoped_refptr<IOBufferWithSize> data = inflater_.GetOutput(size);
bool is_final = !inflater_.CurrentOutputSize() && frame->header.final;
if (!data.get()) {
diff --git a/chromium/net/websockets/websocket_deflate_stream_fuzzer.cc b/chromium/net/websockets/websocket_deflate_stream_fuzzer.cc
index c0b45f6f21e..8c766c1cfc5 100644
--- a/chromium/net/websockets/websocket_deflate_stream_fuzzer.cc
+++ b/chromium/net/websockets/websocket_deflate_stream_fuzzer.cc
@@ -9,6 +9,7 @@
#include <vector>
#include "base/logging.h"
+#include "base/memory/scoped_refptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/test/fuzzed_data_provider.h"
@@ -82,7 +83,7 @@ class WebSocketFuzzedStream final : public WebSocketStream {
uint64_t payload_length =
fuzzed_data_provider_->ConsumeUint32InRange(0, 64);
std::string payload = fuzzed_data_provider_->ConsumeBytes(payload_length);
- frame->data = new StringIOBuffer(payload);
+ frame->data = base::MakeRefCounted<StringIOBuffer>(payload);
frame->header.payload_length = payload.size();
return frame;
}
diff --git a/chromium/net/websockets/websocket_deflate_stream_test.cc b/chromium/net/websockets/websocket_deflate_stream_test.cc
index 15a08ae3576..b76e5ecc7b7 100644
--- a/chromium/net/websockets/websocket_deflate_stream_test.cc
+++ b/chromium/net/websockets/websocket_deflate_stream_test.cc
@@ -15,7 +15,8 @@
#include "base/bind.h"
#include "base/containers/circular_deque.h"
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
+#include "base/memory/ptr_util.h"
+#include "base/memory/scoped_refptr.h"
#include "base/test/mock_callback.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
@@ -54,7 +55,7 @@ const size_t kChunkSize = 4 * 1024;
const int kWindowBits = 15;
scoped_refptr<IOBuffer> ToIOBuffer(const std::string& s) {
- scoped_refptr<IOBuffer> buffer = new IOBuffer(s.size());
+ auto buffer = base::MakeRefCounted<IOBuffer>(s.size());
memcpy(buffer->data(), s.data(), s.size());
return buffer;
}
@@ -88,7 +89,7 @@ void AppendTo(std::vector<std::unique_ptr<WebSocketFrame>>* frames,
WebSocketFrameHeader::OpCode opcode,
FrameFlag flag,
const std::string& data) {
- std::unique_ptr<WebSocketFrame> frame(new WebSocketFrame(opcode));
+ auto frame = std::make_unique<WebSocketFrame>(opcode);
frame->header.final = (flag & kFinal);
frame->header.reserved1 = (flag & kReserved1);
frame->data = ToIOBuffer(data);
@@ -99,7 +100,7 @@ void AppendTo(std::vector<std::unique_ptr<WebSocketFrame>>* frames,
void AppendTo(std::vector<std::unique_ptr<WebSocketFrame>>* frames,
WebSocketFrameHeader::OpCode opcode,
FrameFlag flag) {
- std::unique_ptr<WebSocketFrame> frame(new WebSocketFrame(opcode));
+ auto frame = std::make_unique<WebSocketFrame>(opcode);
frame->header.final = (flag & kFinal);
frame->header.reserved1 = (flag & kReserved1);
frames->push_back(std::move(frame));
@@ -245,9 +246,9 @@ class WebSocketDeflateStreamTest : public ::testing::Test {
parameters.SetClientMaxWindowBits(window_bits);
mock_stream_ = new testing::StrictMock<MockWebSocketStream>;
predictor_ = new WebSocketDeflatePredictorMock;
- deflate_stream_.reset(new WebSocketDeflateStream(
- std::unique_ptr<WebSocketStream>(mock_stream_), parameters,
- std::unique_ptr<WebSocketDeflatePredictor>(predictor_)));
+ deflate_stream_ = std::make_unique<WebSocketDeflateStream>(
+ base::WrapUnique(mock_stream_), parameters,
+ base::WrapUnique(predictor_));
}
std::unique_ptr<WebSocketDeflateStream> deflate_stream_;
diff --git a/chromium/net/websockets/websocket_deflater.cc b/chromium/net/websockets/websocket_deflater.cc
index 78e5b5264e6..27b33994f61 100644
--- a/chromium/net/websockets/websocket_deflater.cc
+++ b/chromium/net/websockets/websocket_deflater.cc
@@ -27,7 +27,7 @@ WebSocketDeflater::~WebSocketDeflater() {
bool WebSocketDeflater::Initialize(int window_bits) {
DCHECK(!stream_);
- stream_.reset(new z_stream);
+ stream_ = std::make_unique<z_stream>();
DCHECK_LE(8, window_bits);
DCHECK_GE(15, window_bits);
@@ -123,7 +123,7 @@ scoped_refptr<IOBufferWithSize> WebSocketDeflater::GetOutput(size_t size) {
base::circular_deque<char>::iterator begin = buffer_.begin();
base::circular_deque<char>::iterator end = begin + length_to_copy;
- scoped_refptr<IOBufferWithSize> result = new IOBufferWithSize(length_to_copy);
+ auto result = base::MakeRefCounted<IOBufferWithSize>(length_to_copy);
std::copy(begin, end, result->data());
buffer_.erase(begin, end);
return result;
diff --git a/chromium/net/websockets/websocket_deflater.h b/chromium/net/websockets/websocket_deflater.h
index 369fff0de5d..3aa6f246530 100644
--- a/chromium/net/websockets/websocket_deflater.h
+++ b/chromium/net/websockets/websocket_deflater.h
@@ -12,7 +12,7 @@
#include "base/containers/circular_deque.h"
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
#include "net/base/net_export.h"
extern "C" struct z_stream_s;
diff --git a/chromium/net/websockets/websocket_deflater_test.cc b/chromium/net/websockets/websocket_deflater_test.cc
index ae0133c6424..fd06bda889d 100644
--- a/chromium/net/websockets/websocket_deflater_test.cc
+++ b/chromium/net/websockets/websocket_deflater_test.cc
@@ -6,7 +6,6 @@
#include <string>
-#include "base/memory/ref_counted.h"
#include "net/base/io_buffer.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/net/websockets/websocket_end_to_end_test.cc b/chromium/net/websockets/websocket_end_to_end_test.cc
index 13f9cf67b81..872168b10f6 100644
--- a/chromium/net/websockets/websocket_end_to_end_test.cc
+++ b/chromium/net/websockets/websocket_end_to_end_test.cc
@@ -19,6 +19,7 @@
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_piece.h"
@@ -26,7 +27,7 @@
#include "build/build_config.h"
#include "net/base/auth.h"
#include "net/base/proxy_delegate.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "net/test/test_data_directory.h"
@@ -72,31 +73,31 @@ class ConnectTestingEventInterface : public WebSocketEventInterface {
// Implementation of WebSocketEventInterface.
void OnCreateURLRequest(URLRequest* request) override {}
- ChannelState OnAddChannelResponse(const std::string& selected_subprotocol,
- const std::string& extensions) override;
+ void OnAddChannelResponse(const std::string& selected_subprotocol,
+ const std::string& extensions) override;
- ChannelState OnDataFrame(bool fin,
- WebSocketMessageType type,
- scoped_refptr<IOBuffer> data,
- size_t data_size) override;
+ void OnDataFrame(bool fin,
+ WebSocketMessageType type,
+ scoped_refptr<IOBuffer> data,
+ size_t data_size) override;
- ChannelState OnFlowControl(int64_t quota) override;
+ void OnFlowControl(int64_t quota) override;
- ChannelState OnClosingHandshake() override;
+ void OnClosingHandshake() override;
- ChannelState OnDropChannel(bool was_clean,
- uint16_t code,
- const std::string& reason) override;
+ void OnDropChannel(bool was_clean,
+ uint16_t code,
+ const std::string& reason) override;
- ChannelState OnFailChannel(const std::string& message) override;
+ void OnFailChannel(const std::string& message) override;
- ChannelState OnStartOpeningHandshake(
+ void OnStartOpeningHandshake(
std::unique_ptr<WebSocketHandshakeRequestInfo> request) override;
- ChannelState OnFinishOpeningHandshake(
+ void OnFinishOpeningHandshake(
std::unique_ptr<WebSocketHandshakeResponseInfo> response) override;
- ChannelState OnSSLCertificateError(
+ void OnSSLCertificateError(
std::unique_ptr<SSLErrorCallbacks> ssl_error_callbacks,
const GURL& url,
const SSLInfo& ssl_info,
@@ -134,60 +135,40 @@ std::string ConnectTestingEventInterface::extensions() const {
return extensions_;
}
-// Make the function definitions below less verbose.
-typedef ConnectTestingEventInterface::ChannelState ChannelState;
-
-ChannelState ConnectTestingEventInterface::OnAddChannelResponse(
+void ConnectTestingEventInterface::OnAddChannelResponse(
const std::string& selected_subprotocol,
const std::string& extensions) {
selected_subprotocol_ = selected_subprotocol;
extensions_ = extensions;
QuitNestedEventLoop();
- return CHANNEL_ALIVE;
}
-ChannelState ConnectTestingEventInterface::OnDataFrame(
- bool fin,
- WebSocketMessageType type,
- scoped_refptr<IOBuffer> data,
- size_t data_size) {
- return CHANNEL_ALIVE;
-}
+void ConnectTestingEventInterface::OnDataFrame(bool fin,
+ WebSocketMessageType type,
+ scoped_refptr<IOBuffer> data,
+ size_t data_size) {}
-ChannelState ConnectTestingEventInterface::OnFlowControl(int64_t quota) {
- return CHANNEL_ALIVE;
-}
+void ConnectTestingEventInterface::OnFlowControl(int64_t quota) {}
-ChannelState ConnectTestingEventInterface::OnClosingHandshake() {
- return CHANNEL_ALIVE;
-}
+void ConnectTestingEventInterface::OnClosingHandshake() {}
-ChannelState ConnectTestingEventInterface::OnDropChannel(
- bool was_clean,
- uint16_t code,
- const std::string& reason) {
- return CHANNEL_DELETED;
-}
+void ConnectTestingEventInterface::OnDropChannel(bool was_clean,
+ uint16_t code,
+ const std::string& reason) {}
-ChannelState ConnectTestingEventInterface::OnFailChannel(
- const std::string& message) {
+void ConnectTestingEventInterface::OnFailChannel(const std::string& message) {
failed_ = true;
failure_message_ = message;
QuitNestedEventLoop();
- return CHANNEL_DELETED;
}
-ChannelState ConnectTestingEventInterface::OnStartOpeningHandshake(
- std::unique_ptr<WebSocketHandshakeRequestInfo> request) {
- return CHANNEL_ALIVE;
-}
+void ConnectTestingEventInterface::OnStartOpeningHandshake(
+ std::unique_ptr<WebSocketHandshakeRequestInfo> request) {}
-ChannelState ConnectTestingEventInterface::OnFinishOpeningHandshake(
- std::unique_ptr<WebSocketHandshakeResponseInfo> response) {
- return CHANNEL_ALIVE;
-}
+void ConnectTestingEventInterface::OnFinishOpeningHandshake(
+ std::unique_ptr<WebSocketHandshakeResponseInfo> response) {}
-ChannelState ConnectTestingEventInterface::OnSSLCertificateError(
+void ConnectTestingEventInterface::OnSSLCertificateError(
std::unique_ptr<SSLErrorCallbacks> ssl_error_callbacks,
const GURL& url,
const SSLInfo& ssl_info,
@@ -196,7 +177,6 @@ ChannelState ConnectTestingEventInterface::OnSSLCertificateError(
FROM_HERE, base::Bind(&SSLErrorCallbacks::CancelSSLRequest,
base::Owned(ssl_error_callbacks.release()),
ERR_SSL_PROTOCOL_ERROR, &ssl_info));
- return CHANNEL_ALIVE;
}
void ConnectTestingEventInterface::QuitNestedEventLoop() {
@@ -239,7 +219,7 @@ class WebSocketEndToEndTest : public ::testing::Test {
protected:
WebSocketEndToEndTest()
: event_interface_(),
- proxy_delegate_(new TestProxyDelegateWithProxyInfo),
+ proxy_delegate_(std::make_unique<TestProxyDelegateWithProxyInfo>()),
context_(true),
channel_(),
initialised_context_(false) {}
@@ -262,8 +242,8 @@ class WebSocketEndToEndTest : public ::testing::Test {
url::Origin origin = url::Origin::Create(GURL("http://localhost"));
GURL site_for_cookies("http://localhost/");
event_interface_ = new ConnectTestingEventInterface;
- channel_.reset(
- new WebSocketChannel(base::WrapUnique(event_interface_), &context_));
+ channel_ = std::make_unique<WebSocketChannel>(
+ base::WrapUnique(event_interface_), &context_);
channel_->SendAddChannelRequest(GURL(socket_url), sub_protocols_, origin,
site_for_cookies, "");
event_interface_->WaitForResponse();
@@ -302,7 +282,8 @@ TEST_F(WebSocketEndToEndTest, DISABLED_HttpsProxyUnauthedFails) {
std::string proxy_config =
"https=" + proxy_server.host_port_pair().ToString();
std::unique_ptr<ProxyResolutionService> proxy_resolution_service(
- ProxyResolutionService::CreateFixed(proxy_config));
+ ProxyResolutionService::CreateFixed(proxy_config,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
ASSERT_TRUE(proxy_resolution_service);
context_.set_proxy_resolution_service(proxy_resolution_service.get());
EXPECT_FALSE(ConnectAndWait(ws_server.GetURL(kEchoServer)));
@@ -332,7 +313,8 @@ TEST_F(WebSocketEndToEndTest, MAYBE_HttpsWssProxyUnauthedFails) {
std::string proxy_config =
"https=" + proxy_server.host_port_pair().ToString();
std::unique_ptr<ProxyResolutionService> proxy_resolution_service(
- ProxyResolutionService::CreateFixed(proxy_config));
+ ProxyResolutionService::CreateFixed(proxy_config,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
ASSERT_TRUE(proxy_resolution_service);
context_.set_proxy_resolution_service(proxy_resolution_service.get());
EXPECT_FALSE(ConnectAndWait(wss_server.GetURL(kEchoServer)));
@@ -354,7 +336,8 @@ TEST_F(WebSocketEndToEndTest, MAYBE_HttpsProxyUsed) {
proxy_server.host_port_pair().ToString() + ";" +
"http=" + proxy_server.host_port_pair().ToString();
std::unique_ptr<ProxyResolutionService> proxy_resolution_service(
- ProxyResolutionService::CreateFixed(proxy_config));
+ ProxyResolutionService::CreateFixed(proxy_config,
+ TRAFFIC_ANNOTATION_FOR_TESTS));
context_.set_proxy_resolution_service(proxy_resolution_service.get());
InitialiseContext();
diff --git a/chromium/net/websockets/websocket_event_interface.h b/chromium/net/websockets/websocket_event_interface.h
index db24207f16a..112637644ea 100644
--- a/chromium/net/websockets/websocket_event_interface.h
+++ b/chromium/net/websockets/websocket_event_interface.h
@@ -13,7 +13,7 @@
#include "base/compiler_specific.h" // for WARN_UNUSED_RESULT
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
#include "net/base/net_export.h"
class GURL;
@@ -32,14 +32,6 @@ class NET_EXPORT WebSocketEventInterface {
public:
typedef int WebSocketMessageType;
- // Any event can cause the Channel to be deleted. The Channel needs to avoid
- // doing further processing in this case. It does not need to do cleanup, as
- // cleanup will already have been done as a result of the deletion.
- enum ChannelState {
- CHANNEL_ALIVE,
- CHANNEL_DELETED
- };
-
virtual ~WebSocketEventInterface() {}
// Called when a URLRequest is created for handshaking.
@@ -47,27 +39,26 @@ class NET_EXPORT WebSocketEventInterface {
// Called in response to an AddChannelRequest. This means that a response has
// been received from the remote server.
- virtual ChannelState OnAddChannelResponse(
- const std::string& selected_subprotocol,
- const std::string& extensions) WARN_UNUSED_RESULT = 0;
+ virtual void OnAddChannelResponse(const std::string& selected_subprotocol,
+ const std::string& extensions) = 0;
// Called when a data frame has been received from the remote host and needs
// to be forwarded to the renderer process.
- virtual ChannelState OnDataFrame(bool fin,
- WebSocketMessageType type,
- scoped_refptr<IOBuffer> buffer,
- size_t buffer_size) WARN_UNUSED_RESULT = 0;
+ virtual void OnDataFrame(bool fin,
+ WebSocketMessageType type,
+ scoped_refptr<IOBuffer> buffer,
+ size_t buffer_size) = 0;
// Called to provide more send quota for this channel to the renderer
// process. Currently the quota units are always bytes of message body
// data. In future it might depend on the type of multiplexing in use.
- virtual ChannelState OnFlowControl(int64_t quota) WARN_UNUSED_RESULT = 0;
+ virtual void OnFlowControl(int64_t quota) = 0;
// Called when the remote server has Started the WebSocket Closing
// Handshake. The client should not attempt to send any more messages after
// receiving this message. It will be followed by OnDropChannel() when the
// closing handshake is complete.
- virtual ChannelState OnClosingHandshake() WARN_UNUSED_RESULT = 0;
+ virtual void OnClosingHandshake() = 0;
// Called when the channel has been dropped, either due to a network close, a
// network error, or a protocol error. This may or may not be preceeded by a
@@ -82,32 +73,26 @@ class NET_EXPORT WebSocketEventInterface {
// The channel should not be used again after OnDropChannel() has been
// called.
//
- // This method returns a ChannelState for consistency, but all implementations
- // must delete the Channel and return CHANNEL_DELETED.
- virtual ChannelState OnDropChannel(bool was_clean,
- uint16_t code,
- const std::string& reason)
- WARN_UNUSED_RESULT = 0;
+ // This function deletes the Channel.
+ virtual void OnDropChannel(bool was_clean,
+ uint16_t code,
+ const std::string& reason) = 0;
// Called when the browser fails the channel, as specified in the spec.
//
// The channel should not be used again after OnFailChannel() has been
// called.
//
- // This method returns a ChannelState for consistency, but all implementations
- // must delete the Channel and return CHANNEL_DELETED.
- virtual ChannelState OnFailChannel(const std::string& message)
- WARN_UNUSED_RESULT = 0;
+ // This function deletes the Channel.
+ virtual void OnFailChannel(const std::string& message) = 0;
// Called when the browser starts the WebSocket Opening Handshake.
- virtual ChannelState OnStartOpeningHandshake(
- std::unique_ptr<WebSocketHandshakeRequestInfo> request)
- WARN_UNUSED_RESULT = 0;
+ virtual void OnStartOpeningHandshake(
+ std::unique_ptr<WebSocketHandshakeRequestInfo> request) = 0;
// Called when the browser finishes the WebSocket Opening Handshake.
- virtual ChannelState OnFinishOpeningHandshake(
- std::unique_ptr<WebSocketHandshakeResponseInfo> response)
- WARN_UNUSED_RESULT = 0;
+ virtual void OnFinishOpeningHandshake(
+ std::unique_ptr<WebSocketHandshakeResponseInfo> response) = 0;
// Callbacks to be used in response to a call to OnSSLCertificateError. Very
// similar to content::SSLErrorHandler::Delegate (which we can't use directly
@@ -129,11 +114,11 @@ class NET_EXPORT WebSocketEventInterface {
// this method will delegate to content::SSLManager::OnSSLCertificateError to
// make the actual decision. The callbacks must not be called after the
// WebSocketChannel has been destroyed.
- virtual ChannelState OnSSLCertificateError(
+ virtual void OnSSLCertificateError(
std::unique_ptr<SSLErrorCallbacks> ssl_error_callbacks,
const GURL& url,
const SSLInfo& ssl_info,
- bool fatal) WARN_UNUSED_RESULT = 0;
+ bool fatal) = 0;
protected:
WebSocketEventInterface() {}
diff --git a/chromium/net/websockets/websocket_frame.cc b/chromium/net/websockets/websocket_frame.cc
index 9db28d65a65..7ec26943347 100644
--- a/chromium/net/websockets/websocket_frame.cc
+++ b/chromium/net/websockets/websocket_frame.cc
@@ -60,7 +60,7 @@ inline void MaskWebSocketFramePayloadByBytes(
} // namespace
std::unique_ptr<WebSocketFrameHeader> WebSocketFrameHeader::Clone() const {
- std::unique_ptr<WebSocketFrameHeader> ret(new WebSocketFrameHeader(opcode));
+ auto ret = std::make_unique<WebSocketFrameHeader>(opcode);
ret->CopyFrom(*this);
return ret;
}
diff --git a/chromium/net/websockets/websocket_frame.h b/chromium/net/websockets/websocket_frame.h
index 074c78753e5..c751fedfd56 100644
--- a/chromium/net/websockets/websocket_frame.h
+++ b/chromium/net/websockets/websocket_frame.h
@@ -11,7 +11,7 @@
#include <vector>
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
#include "net/base/net_export.h"
namespace net {
diff --git a/chromium/net/websockets/websocket_frame_parser.cc b/chromium/net/websockets/websocket_frame_parser.cc
index 1b06cca7abc..1c64e4506ca 100644
--- a/chromium/net/websockets/websocket_frame_parser.cc
+++ b/chromium/net/websockets/websocket_frame_parser.cc
@@ -6,13 +6,12 @@
#include <algorithm>
#include <limits>
-#include <memory>
#include <utility>
#include <vector>
#include "base/big_endian.h"
#include "base/logging.h"
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
#include "net/base/io_buffer.h"
#include "net/websockets/websocket_frame.h"
@@ -158,7 +157,7 @@ void WebSocketFrameParser::DecodeFrameHeader() {
std::fill(masking_key_.key, masking_key_.key + kMaskingKeyLength, '\0');
}
- current_frame_header_.reset(new WebSocketFrameHeader(opcode));
+ current_frame_header_ = std::make_unique<WebSocketFrameHeader>(opcode);
current_frame_header_->final = final;
current_frame_header_->reserved1 = reserved1;
current_frame_header_->reserved2 = reserved2;
@@ -177,13 +176,14 @@ std::unique_ptr<WebSocketFrameChunk> WebSocketFrameParser::DecodeFramePayload(
std::min(static_cast<uint64_t>(buffer_.size() - current_read_pos_),
current_frame_header_->payload_length - frame_offset_));
- std::unique_ptr<WebSocketFrameChunk> frame_chunk(new WebSocketFrameChunk);
+ auto frame_chunk = std::make_unique<WebSocketFrameChunk>();
if (first_chunk) {
frame_chunk->header = current_frame_header_->Clone();
}
frame_chunk->final_chunk = false;
if (next_size) {
- frame_chunk->data = new IOBufferWithSize(static_cast<int>(next_size));
+ frame_chunk->data =
+ base::MakeRefCounted<IOBufferWithSize>(static_cast<int>(next_size));
char* io_data = frame_chunk->data->data();
memcpy(io_data, &buffer_.front() + current_read_pos_, next_size);
if (current_frame_header_->masked) {
diff --git a/chromium/net/websockets/websocket_frame_parser.h b/chromium/net/websockets/websocket_frame_parser.h
index e43f051f31a..8f0287d00bd 100644
--- a/chromium/net/websockets/websocket_frame_parser.h
+++ b/chromium/net/websockets/websocket_frame_parser.h
@@ -12,7 +12,6 @@
#include <vector>
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
#include "net/websockets/websocket_errors.h"
#include "net/websockets/websocket_frame.h"
diff --git a/chromium/net/websockets/websocket_handshake_constants.cc b/chromium/net/websockets/websocket_handshake_constants.cc
index ce9bb62b818..4bd4bd119d9 100644
--- a/chromium/net/websockets/websocket_handshake_constants.cc
+++ b/chromium/net/websockets/websocket_handshake_constants.cc
@@ -22,8 +22,6 @@ const char kSupportedVersion[] = "13";
const char kUpgrade[] = "Upgrade";
const char kWebSocketGuid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
-const char kSecWebSocketProtocolLowercase[] = "sec-websocket-protocol";
-const char kSecWebSocketExtensionsLowercase[] = "sec-websocket-extensions";
const char kWebSocketLowercase[] = "websocket";
} // namespace websockets
diff --git a/chromium/net/websockets/websocket_handshake_constants.h b/chromium/net/websockets/websocket_handshake_constants.h
index 8fb5fc592fc..3794d3ffafe 100644
--- a/chromium/net/websockets/websocket_handshake_constants.h
+++ b/chromium/net/websockets/websocket_handshake_constants.h
@@ -56,14 +56,6 @@ extern const char kUpgrade[];
// RFC6455.
extern const char NET_EXPORT kWebSocketGuid[];
-// Some parts of the code require lowercase versions of the header names in
-// order to do case-insensitive comparisons, or because of HTTP/2.
-// "sec-websocket-protocol"
-extern const char kSecWebSocketProtocolLowercase[];
-
-// "sec-websocket-extensions"
-extern const char kSecWebSocketExtensionsLowercase[];
-
// "websocket", as used in the "Upgrade:" header. This is always lowercase
// (except in obsolete versions of the protocol).
extern const char kWebSocketLowercase[];
diff --git a/chromium/net/websockets/websocket_handshake_response_info.cc b/chromium/net/websockets/websocket_handshake_response_info.cc
index 5a276e55ba7..1fafd17d8d2 100644
--- a/chromium/net/websockets/websocket_handshake_response_info.cc
+++ b/chromium/net/websockets/websocket_handshake_response_info.cc
@@ -6,7 +6,6 @@
#include <string>
-#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "net/http/http_response_headers.h"
#include "url/gurl.h"
diff --git a/chromium/net/websockets/websocket_handshake_response_info.h b/chromium/net/websockets/websocket_handshake_response_info.h
index 42a2662d021..e3450366211 100644
--- a/chromium/net/websockets/websocket_handshake_response_info.h
+++ b/chromium/net/websockets/websocket_handshake_response_info.h
@@ -8,7 +8,7 @@
#include <string>
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
#include "url/gurl.h"
diff --git a/chromium/net/websockets/websocket_handshake_stream_base.cc b/chromium/net/websockets/websocket_handshake_stream_base.cc
new file mode 100644
index 00000000000..11d00c69c42
--- /dev/null
+++ b/chromium/net/websockets/websocket_handshake_stream_base.cc
@@ -0,0 +1,154 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/websockets/websocket_handshake_stream_base.h"
+
+#include <unordered_set>
+
+#include "base/metrics/histogram_macros.h"
+#include "base/strings/string_util.h"
+#include "net/http/http_request_headers.h"
+#include "net/http/http_response_headers.h"
+#include "net/websockets/websocket_extension.h"
+#include "net/websockets/websocket_extension_parser.h"
+#include "net/websockets/websocket_handshake_constants.h"
+
+namespace net {
+
+// static
+std::string WebSocketHandshakeStreamBase::MultipleHeaderValuesMessage(
+ const std::string& header_name) {
+ return std::string("'") + header_name +
+ "' header must not appear more than once in a response";
+}
+
+// static
+void WebSocketHandshakeStreamBase::AddVectorHeaderIfNonEmpty(
+ const char* name,
+ const std::vector<std::string>& value,
+ HttpRequestHeaders* headers) {
+ if (value.empty())
+ return;
+ headers->SetHeader(name, base::JoinString(value, ", "));
+}
+
+// static
+bool WebSocketHandshakeStreamBase::ValidateSubProtocol(
+ const HttpResponseHeaders* headers,
+ const std::vector<std::string>& requested_sub_protocols,
+ std::string* sub_protocol,
+ std::string* failure_message) {
+ size_t iter = 0;
+ std::string value;
+ std::unordered_set<std::string> requested_set(requested_sub_protocols.begin(),
+ requested_sub_protocols.end());
+ int count = 0;
+ bool has_multiple_protocols = false;
+ bool has_invalid_protocol = false;
+
+ while (!has_invalid_protocol || !has_multiple_protocols) {
+ std::string temp_value;
+ if (!headers->EnumerateHeader(&iter, websockets::kSecWebSocketProtocol,
+ &temp_value))
+ break;
+ value = temp_value;
+ if (requested_set.count(value) == 0)
+ has_invalid_protocol = true;
+ if (++count > 1)
+ has_multiple_protocols = true;
+ }
+
+ if (has_multiple_protocols) {
+ *failure_message =
+ MultipleHeaderValuesMessage(websockets::kSecWebSocketProtocol);
+ return false;
+ } else if (count > 0 && requested_sub_protocols.size() == 0) {
+ *failure_message = std::string(
+ "Response must not include 'Sec-WebSocket-Protocol' "
+ "header if not present in request: ") +
+ value;
+ return false;
+ } else if (has_invalid_protocol) {
+ *failure_message = "'Sec-WebSocket-Protocol' header value '" + value +
+ "' in response does not match any of sent values";
+ return false;
+ } else if (requested_sub_protocols.size() > 0 && count == 0) {
+ *failure_message =
+ "Sent non-empty 'Sec-WebSocket-Protocol' header "
+ "but no response was received";
+ return false;
+ }
+ *sub_protocol = value;
+ return true;
+}
+
+// static
+bool WebSocketHandshakeStreamBase::ValidateExtensions(
+ const HttpResponseHeaders* headers,
+ std::string* accepted_extensions_descriptor,
+ std::string* failure_message,
+ WebSocketExtensionParams* params) {
+ size_t iter = 0;
+ std::string header_value;
+ std::vector<std::string> header_values;
+ // TODO(ricea): If adding support for additional extensions, generalise this
+ // code.
+ bool seen_permessage_deflate = false;
+ while (headers->EnumerateHeader(&iter, websockets::kSecWebSocketExtensions,
+ &header_value)) {
+ WebSocketExtensionParser parser;
+ if (!parser.Parse(header_value)) {
+ // TODO(yhirano) Set appropriate failure message.
+ *failure_message =
+ "'Sec-WebSocket-Extensions' header value is "
+ "rejected by the parser: " +
+ header_value;
+ return false;
+ }
+
+ const std::vector<WebSocketExtension>& extensions = parser.extensions();
+ for (const auto& extension : extensions) {
+ if (extension.name() == "permessage-deflate") {
+ if (seen_permessage_deflate) {
+ *failure_message = "Received duplicate permessage-deflate response";
+ return false;
+ }
+ seen_permessage_deflate = true;
+ auto& deflate_parameters = params->deflate_parameters;
+ if (!deflate_parameters.Initialize(extension, failure_message) ||
+ !deflate_parameters.IsValidAsResponse(failure_message)) {
+ *failure_message = "Error in permessage-deflate: " + *failure_message;
+ return false;
+ }
+ // Note that we don't have to check the request-response compatibility
+ // here because we send a request compatible with any valid responses.
+ // TODO(yhirano): Place a DCHECK here.
+
+ header_values.push_back(header_value);
+ } else {
+ *failure_message = "Found an unsupported extension '" +
+ extension.name() +
+ "' in 'Sec-WebSocket-Extensions' header";
+ return false;
+ }
+ }
+ }
+ *accepted_extensions_descriptor = base::JoinString(header_values, ", ");
+ params->deflate_enabled = seen_permessage_deflate;
+ return true;
+}
+
+void WebSocketHandshakeStreamBase::RecordHandshakeResult(
+ HandshakeResult result) {
+ UMA_HISTOGRAM_ENUMERATION("Net.WebSocket.HandshakeResult2", result,
+ HandshakeResult::NUM_HANDSHAKE_RESULT_TYPES);
+}
+
+void WebSocketHandshakeStreamBase::RecordDeflateMode(
+ WebSocketDeflateParameters::ContextTakeOverMode deflate_mode) {
+ UMA_HISTOGRAM_ENUMERATION("Net.WebSocket.DeflateMode", deflate_mode,
+ WebSocketDeflater::NUM_CONTEXT_TAKEOVER_MODE_TYPES);
+}
+
+} // namespace net
diff --git a/chromium/net/websockets/websocket_handshake_stream_base.h b/chromium/net/websockets/websocket_handshake_stream_base.h
index feb12a3816e..44da6a9f698 100644
--- a/chromium/net/websockets/websocket_handshake_stream_base.h
+++ b/chromium/net/websockets/websocket_handshake_stream_base.h
@@ -11,19 +11,23 @@
#include <memory>
#include <string>
+#include <vector>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/supports_user_data.h"
#include "net/base/net_export.h"
#include "net/http/http_stream.h"
-#include "net/url_request/websocket_handshake_userdata_key.h"
+#include "net/websockets/websocket_deflate_parameters.h"
#include "net/websockets/websocket_stream.h"
namespace net {
class ClientSocketHandle;
class SpdySession;
+class HttpRequestHeaders;
+class HttpResponseHeaders;
+class WebSocketEndpointLockManager;
// WebSocketHandshakeStreamBase is the base class of
// WebSocketBasicHandshakeStream. net/http code uses this interface to handle
@@ -31,16 +35,61 @@ class SpdySession;
// HttpStreamBase.
class NET_EXPORT WebSocketHandshakeStreamBase : public HttpStream {
public:
+ // These entries must match histogram Net.WebSocket.HandshakeResult2.
+ // Do not change or reuse values.
+ enum class HandshakeResult {
+ // Handshake not completed via Upgrade over HTTP/1 connection.
+ INCOMPLETE = 0,
+ // Server responded to Upgrade request with invalid status.
+ INVALID_STATUS = 1,
+ // Server responded to Upgrade request with empty response.
+ EMPTY_RESPONSE = 2,
+ // Server responded to Upgrade request with 101 status but there was some
+ // other network error.
+ FAILED_SWITCHING_PROTOCOLS = 3,
+ // Server responded to Upgrade request with invalid Upgrade header.
+ FAILED_UPGRADE = 4,
+ // Server responded to Upgrade request with invalid Sec-WebSocket-Accept
+ // header.
+ FAILED_ACCEPT = 5,
+ // Server responded to Upgrade request with invalid Connection header.
+ FAILED_CONNECTION = 6,
+ // Server responded to Upgrade request with invalid Sec-WebSocket-Protocol
+ // header.
+ FAILED_SUBPROTO = 7,
+ // Server responded to Upgrade request with invalid Sec-WebSocket-Extensions
+ // header.
+ FAILED_EXTENSIONS = 8,
+ // Upgrade request failed due to other network error.
+ FAILED = 9,
+ // Connected via Upgrade over HTTP/1 connection.
+ CONNECTED = 10,
+ // Handshake not completed over an HTTP/2 connection.
+ HTTP2_INCOMPLETE = 11,
+ // Server responded to WebSocket request over an HTTP/2 connection with
+ // invalid status code.
+ HTTP2_INVALID_STATUS = 12,
+ // Server responded to WebSocket request over an HTTP/2 connection with
+ // invalid sec-websocket-protocol header.
+ HTTP2_FAILED_SUBPROTO = 13,
+ // Server responded to WebSocket request over an HTTP/2 connection with
+ // invalid sec-websocket-extensions header.
+ HTTP2_FAILED_EXTENSIONS = 14,
+ // WebSocket request over an HTTP/2 connection failed with some other error.
+ HTTP2_FAILED = 15,
+ // Connected over an HTTP/2 connection.
+ HTTP2_CONNECTED = 16,
+ NUM_HANDSHAKE_RESULT_TYPES = 17
+ };
+
+ WebSocketHandshakeStreamBase() = default;
+ ~WebSocketHandshakeStreamBase() override = default;
+
// An object that stores data needed for the creation of a
// WebSocketBasicHandshakeStream object. A new CreateHelper is used for each
// WebSocket connection.
class NET_EXPORT_PRIVATE CreateHelper : public base::SupportsUserData::Data {
public:
- // Returns a key to use to lookup this object in a URLRequest object. It is
- // different from any other key that is supplied to
- // URLRequest::SetUserData().
- static const void* DataKey() { return kWebSocketHandshakeUserDataKey; }
-
~CreateHelper() override {}
// Create a WebSocketBasicHandshakeStream. This is called after the
@@ -49,7 +98,8 @@ class NET_EXPORT WebSocketHandshakeStreamBase : public HttpStream {
// HTTP authentication is needed.
virtual std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
std::unique_ptr<ClientSocketHandle> connection,
- bool using_proxy) = 0;
+ bool using_proxy,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager) = 0;
// Create a WebSocketHttp2HandshakeStream. This is called after the
// underlying HTTP/2 connection has been established but before the stream
@@ -58,10 +108,6 @@ class NET_EXPORT WebSocketHandshakeStreamBase : public HttpStream {
base::WeakPtr<SpdySession> session) = 0;
};
- // This has to have an inline implementation so that the net/url_request/
- // tests do not fail on iOS.
- ~WebSocketHandshakeStreamBase() override {}
-
// After the handshake has completed, this method creates a WebSocketStream
// (of the appropriate type) from the WebSocketHandshakeStreamBase object.
// The WebSocketHandshakeStreamBase object is unusable after Upgrade() has
@@ -70,9 +116,35 @@ class NET_EXPORT WebSocketHandshakeStreamBase : public HttpStream {
void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
+ static std::string MultipleHeaderValuesMessage(
+ const std::string& header_name);
+
protected:
- // As with the destructor, this must be inline.
- WebSocketHandshakeStreamBase() {}
+ // TODO(ricea): If more extensions are added, replace this with a more general
+ // mechanism.
+ struct WebSocketExtensionParams {
+ bool deflate_enabled = false;
+ WebSocketDeflateParameters deflate_parameters;
+ };
+
+ static void AddVectorHeaderIfNonEmpty(const char* name,
+ const std::vector<std::string>& value,
+ HttpRequestHeaders* headers);
+
+ static bool ValidateSubProtocol(
+ const HttpResponseHeaders* headers,
+ const std::vector<std::string>& requested_sub_protocols,
+ std::string* sub_protocol,
+ std::string* failure_message);
+
+ static bool ValidateExtensions(const HttpResponseHeaders* headers,
+ std::string* accepted_extensions_descriptor,
+ std::string* failure_message,
+ WebSocketExtensionParams* params);
+
+ void RecordHandshakeResult(HandshakeResult result);
+ void RecordDeflateMode(
+ WebSocketDeflateParameters::ContextTakeOverMode deflate_mode);
private:
DISALLOW_COPY_AND_ASSIGN(WebSocketHandshakeStreamBase);
diff --git a/chromium/net/websockets/websocket_handshake_stream_create_helper.cc b/chromium/net/websockets/websocket_handshake_stream_create_helper.cc
index 6616894283f..23718bc67f0 100644
--- a/chromium/net/websockets/websocket_handshake_stream_create_helper.cc
+++ b/chromium/net/websockets/websocket_handshake_stream_create_helper.cc
@@ -4,7 +4,6 @@
#include "net/websockets/websocket_handshake_stream_create_helper.h"
-#include <memory>
#include <utility>
#include "base/logging.h"
@@ -30,7 +29,8 @@ WebSocketHandshakeStreamCreateHelper::~WebSocketHandshakeStreamCreateHelper() =
std::unique_ptr<WebSocketHandshakeStreamBase>
WebSocketHandshakeStreamCreateHelper::CreateBasicStream(
std::unique_ptr<ClientSocketHandle> connection,
- bool using_proxy) {
+ bool using_proxy,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager) {
DCHECK(request_) << "set_request() must be called";
// The list of supported extensions and parameters is hard-coded.
@@ -40,7 +40,8 @@ WebSocketHandshakeStreamCreateHelper::CreateBasicStream(
1, "permessage-deflate; client_max_window_bits");
auto stream = std::make_unique<WebSocketBasicHandshakeStream>(
std::move(connection), connect_delegate_, using_proxy,
- requested_subprotocols_, extensions, request_);
+ requested_subprotocols_, extensions, request_,
+ websocket_endpoint_lock_manager);
OnBasicStreamCreated(stream.get());
request_->OnHandshakeStreamCreated(stream.get());
return std::move(stream);
diff --git a/chromium/net/websockets/websocket_handshake_stream_create_helper.h b/chromium/net/websockets/websocket_handshake_stream_create_helper.h
index c21d351dd76..8a0799609fc 100644
--- a/chromium/net/websockets/websocket_handshake_stream_create_helper.h
+++ b/chromium/net/websockets/websocket_handshake_stream_create_helper.h
@@ -19,6 +19,7 @@ namespace net {
class WebSocketStreamRequest;
class SpdySession;
class WebSocketBasicHandshakeStream;
+class WebSocketEndpointLockManager;
// Implementation of WebSocketHandshakeStreamBase::CreateHelper. This class is
// used in the implementation of WebSocketStream::CreateAndConnectStream() and
@@ -41,7 +42,8 @@ class NET_EXPORT_PRIVATE WebSocketHandshakeStreamCreateHelper
// Creates a WebSocketBasicHandshakeStream over a TCP/IP or TLS socket.
std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
std::unique_ptr<ClientSocketHandle> connection,
- bool using_proxy) override;
+ bool using_proxy,
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager) override;
// Creates a WebSocketHttp2HandshakeStream over an HTTP/2 connection.
std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp2Stream(
diff --git a/chromium/net/websockets/websocket_handshake_stream_create_helper_test.cc b/chromium/net/websockets/websocket_handshake_stream_create_helper_test.cc
index 7c45da2ef79..c4fa5048381 100644
--- a/chromium/net/websockets/websocket_handshake_stream_create_helper_test.cc
+++ b/chromium/net/websockets/websocket_handshake_stream_create_helper_test.cc
@@ -9,6 +9,7 @@
#include <vector>
#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
#include "net/base/completion_callback.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_errors.h"
@@ -22,6 +23,7 @@
#include "net/socket/client_socket_handle.h"
#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
+#include "net/socket/websocket_endpoint_lock_manager.h"
#include "net/spdy/chromium/spdy_session.h"
#include "net/spdy/chromium/spdy_session_key.h"
#include "net/spdy/chromium/spdy_test_util_common.h"
@@ -51,17 +53,6 @@ namespace {
enum HandshakeStreamType { BASIC_HANDSHAKE_STREAM, HTTP2_HANDSHAKE_STREAM };
-std::string WebSocketExtraHeadersToString(WebSocketExtraHeaders headers) {
- std::string answer;
- for (const auto& header : headers) {
- answer.append(header.first);
- answer.append(": ");
- answer.append(header.second);
- answer.append("\r\n");
- }
- return answer;
-}
-
// This class encapsulates the details of creating a mock ClientSocketHandle.
class MockClientSocketHandleFactory {
public:
@@ -166,7 +157,8 @@ class WebSocketHandshakeStreamCreateHelperTest
WebSocketExtraHeadersToString(extra_response_headers)));
std::unique_ptr<WebSocketHandshakeStreamBase> handshake =
- create_helper.CreateBasicStream(std::move(socket_handle), false);
+ create_helper.CreateBasicStream(std::move(socket_handle), false,
+ &websocket_endpoint_lock_manager_);
// If in future the implementation type returned by CreateBasicStream()
// changes, this static_cast will be wrong. However, in that case the
@@ -196,7 +188,7 @@ class WebSocketHandshakeStreamCreateHelperTest
case HTTP2_HANDSHAKE_STREAM: {
SpdyTestUtil spdy_util;
SpdyHeaderBlock request_header_block = WebSocketHttp2Request(
- kPath, "www.example.org:443", kOrigin, extra_request_headers);
+ kPath, "www.example.org", kOrigin, extra_request_headers);
SpdySerializedFrame request_headers(spdy_util.ConstructSpdyHeaders(
1, std::move(request_header_block), DEFAULT_PRIORITY, false));
MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
@@ -214,7 +206,7 @@ class WebSocketHandshakeStreamCreateHelperTest
SSLSocketDataProvider ssl(ASYNC, OK);
ssl.ssl_info.cert =
- ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
+ ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
SpdySessionDependencies session_deps;
session_deps.socket_factory->AddSocketDataProvider(&data);
@@ -261,6 +253,7 @@ class WebSocketHandshakeStreamCreateHelperTest
MockClientSocketHandleFactory socket_handle_factory_;
TestConnectDelegate connect_delegate_;
StrictMock<MockWebSocketStreamRequest> stream_request_;
+ WebSocketEndpointLockManager websocket_endpoint_lock_manager_;
};
INSTANTIATE_TEST_CASE_P(,
diff --git a/chromium/net/websockets/websocket_http2_handshake_stream.cc b/chromium/net/websockets/websocket_http2_handshake_stream.cc
index 987f38bc28e..c7c535247dc 100644
--- a/chromium/net/websockets/websocket_http2_handshake_stream.cc
+++ b/chromium/net/websockets/websocket_http2_handshake_stream.cc
@@ -5,13 +5,10 @@
#include "net/websockets/websocket_http2_handshake_stream.h"
#include <cstddef>
-#include <unordered_set>
#include <utility>
#include "base/bind.h"
#include "base/logging.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "net/http/http_request_headers.h"
@@ -26,141 +23,17 @@
#include "net/websockets/websocket_deflate_predictor_impl.h"
#include "net/websockets/websocket_deflate_stream.h"
#include "net/websockets/websocket_deflater.h"
-#include "net/websockets/websocket_extension_parser.h"
#include "net/websockets/websocket_handshake_constants.h"
#include "net/websockets/websocket_handshake_request_info.h"
namespace net {
-// TODO(ricea): If more extensions are added, replace this with a more general
-// mechanism.
-struct WebSocketExtensionParams {
- bool deflate_enabled = false;
- WebSocketDeflateParameters deflate_parameters;
-};
-
namespace {
-void AddVectorHeaderIfNonEmpty(const char* name,
- const std::vector<std::string>& value,
- HttpRequestHeaders* headers) {
- if (value.empty())
- return;
- headers->SetHeader(name, base::JoinString(value, ", "));
-}
-
-std::string MultipleHeaderValuesMessage(const std::string& header_name) {
- return std::string("'") + header_name +
- "' header must not appear more than once in a response";
-}
-
bool ValidateStatus(const HttpResponseHeaders* headers) {
return headers->GetStatusLine() == "HTTP/1.1 200";
}
-bool ValidateSubProtocol(
- const HttpResponseHeaders* headers,
- const std::vector<std::string>& requested_sub_protocols,
- std::string* sub_protocol,
- std::string* failure_message) {
- size_t iter = 0;
- std::string value;
- std::unordered_set<std::string> requested_set(requested_sub_protocols.begin(),
- requested_sub_protocols.end());
- int count = 0;
- bool has_multiple_protocols = false;
- bool has_invalid_protocol = false;
-
- while (!has_invalid_protocol || !has_multiple_protocols) {
- std::string temp_value;
- if (!headers->EnumerateHeader(
- &iter, websockets::kSecWebSocketProtocolLowercase, &temp_value))
- break;
- value = temp_value;
- if (requested_set.count(value) == 0)
- has_invalid_protocol = true;
- if (++count > 1)
- has_multiple_protocols = true;
- }
-
- if (has_multiple_protocols) {
- *failure_message =
- MultipleHeaderValuesMessage(websockets::kSecWebSocketProtocolLowercase);
- return false;
- } else if (count > 0 && requested_sub_protocols.size() == 0) {
- *failure_message = std::string(
- "Response must not include 'Sec-WebSocket-Protocol' "
- "header if not present in request: ") +
- value;
- return false;
- } else if (has_invalid_protocol) {
- *failure_message = "'Sec-WebSocket-Protocol' header value '" + value +
- "' in response does not match any of sent values";
- return false;
- } else if (requested_sub_protocols.size() > 0 && count == 0) {
- *failure_message =
- "Sent non-empty 'Sec-WebSocket-Protocol' header "
- "but no response was received";
- return false;
- }
- *sub_protocol = value;
- return true;
-}
-
-bool ValidateExtensions(const HttpResponseHeaders* headers,
- std::string* accepted_extensions_descriptor,
- std::string* failure_message,
- WebSocketExtensionParams* params) {
- size_t iter = 0;
- std::string header_value;
- std::vector<std::string> header_values;
- // TODO(ricea): If adding support for additional extensions, generalise this
- // code.
- bool seen_permessage_deflate = false;
- while (headers->EnumerateHeader(
- &iter, websockets::kSecWebSocketExtensionsLowercase, &header_value)) {
- WebSocketExtensionParser parser;
- if (!parser.Parse(header_value)) {
- // TODO(yhirano) Set appropriate failure message.
- *failure_message =
- "'Sec-WebSocket-Extensions' header value is "
- "rejected by the parser: " +
- header_value;
- return false;
- }
-
- const std::vector<WebSocketExtension>& extensions = parser.extensions();
- for (const auto& extension : extensions) {
- if (extension.name() == "permessage-deflate") {
- if (seen_permessage_deflate) {
- *failure_message = "Received duplicate permessage-deflate response";
- return false;
- }
- seen_permessage_deflate = true;
- auto& deflate_parameters = params->deflate_parameters;
- if (!deflate_parameters.Initialize(extension, failure_message) ||
- !deflate_parameters.IsValidAsResponse(failure_message)) {
- *failure_message = "Error in permessage-deflate: " + *failure_message;
- return false;
- }
- // Note that we don't have to check the request-response compatibility
- // here because we send a request compatible with any valid responses.
- // TODO(yhirano): Place a DCHECK here.
-
- header_values.push_back(header_value);
- } else {
- *failure_message = "Found an unsupported extension '" +
- extension.name() +
- "' in 'Sec-WebSocket-Extensions' header";
- return false;
- }
- }
- }
- *accepted_extensions_descriptor = base::JoinString(header_values, ", ");
- params->deflate_enabled = seen_permessage_deflate;
- return true;
-}
-
} // namespace
WebSocketHttp2HandshakeStream::WebSocketHttp2HandshakeStream(
@@ -169,7 +42,8 @@ WebSocketHttp2HandshakeStream::WebSocketHttp2HandshakeStream(
std::vector<std::string> requested_sub_protocols,
std::vector<std::string> requested_extensions,
WebSocketStreamRequest* request)
- : session_(session),
+ : result_(HandshakeResult::HTTP2_INCOMPLETE),
+ session_(session),
connect_delegate_(connect_delegate),
http_response_info_(nullptr),
requested_sub_protocols_(requested_sub_protocols),
@@ -185,6 +59,7 @@ WebSocketHttp2HandshakeStream::WebSocketHttp2HandshakeStream(
WebSocketHttp2HandshakeStream::~WebSocketHttp2HandshakeStream() {
spdy_stream_request_.reset();
+ RecordHandshakeResult(result_);
}
int WebSocketHttp2HandshakeStream::InitializeStream(
@@ -193,6 +68,7 @@ int WebSocketHttp2HandshakeStream::InitializeStream(
RequestPriority priority,
const NetLogWithSource& net_log,
CompletionOnceCallback callback) {
+ DCHECK(request_info->traffic_annotation.is_valid());
request_info_ = request_info;
priority_ = priority;
net_log_ = net_log;
@@ -242,13 +118,12 @@ int WebSocketHttp2HandshakeStream::SendRequest(
callback_ = std::move(callback);
spdy_stream_request_ = std::make_unique<SpdyStreamRequest>();
- // TODO(https://crbug.com/656607): Add proper annotation here.
int rv = spdy_stream_request_->StartRequest(
SPDY_BIDIRECTIONAL_STREAM, session_, request_info_->url, priority_,
request_info_->socket_tag, net_log_,
base::BindOnce(&WebSocketHttp2HandshakeStream::StartRequestCallback,
base::Unretained(this)),
- NO_TRAFFIC_ANNOTATION_BUG_656607);
+ NetworkTrafficAnnotationTag(request_info_->traffic_annotation));
if (rv == OK) {
StartRequestCallback(rv);
return ERR_IO_PENDING;
@@ -345,8 +220,7 @@ Error WebSocketHttp2HandshakeStream::GetTokenBindingSignature(
crypto::ECPrivateKey* key,
TokenBindingType tb_type,
std::vector<uint8_t>* out) {
- NOTREACHED();
- return ERR_NOT_IMPLEMENTED;
+ return stream_->GetTokenBindingSignature(key, tb_type, out);
}
void WebSocketHttp2HandshakeStream::Drain(HttpNetworkSession* session) {
@@ -375,10 +249,8 @@ std::unique_ptr<WebSocketStream> WebSocketHttp2HandshakeStream::Upgrade() {
if (!extension_params_->deflate_enabled)
return basic_stream;
- UMA_HISTOGRAM_ENUMERATION(
- "Net.WebSocket.DeflateMode",
- extension_params_->deflate_parameters.client_context_take_over_mode(),
- WebSocketDeflater::NUM_CONTEXT_TAKEOVER_MODE_TYPES);
+ RecordDeflateMode(
+ extension_params_->deflate_parameters.client_context_take_over_mode());
return std::make_unique<WebSocketDeflateStream>(
std::move(basic_stream), extension_params_->deflate_parameters,
@@ -427,6 +299,11 @@ void WebSocketHttp2HandshakeStream::OnClose(int status) {
stream_adapter_.reset();
+ // If response headers have already been received,
+ // then ValidateResponse() sets |result_|.
+ if (!response_headers_complete_)
+ result_ = HandshakeResult::HTTP2_FAILED;
+
OnFailure(std::string("Stream closed with error: ") + ErrorToString(status));
if (callback_)
@@ -472,6 +349,7 @@ int WebSocketHttp2HandshakeStream::ValidateResponse() {
"Error during WebSocket handshake: Unexpected response code: %d",
headers->response_code()));
OnFinishOpeningHandshake();
+ result_ = HandshakeResult::HTTP2_INVALID_STATUS;
return ERR_INVALID_RESPONSE;
}
}
@@ -480,11 +358,16 @@ int WebSocketHttp2HandshakeStream::ValidateUpgradeResponse(
const HttpResponseHeaders* headers) {
extension_params_ = std::make_unique<WebSocketExtensionParams>();
std::string failure_message;
- if (ValidateStatus(headers) &&
- ValidateSubProtocol(headers, requested_sub_protocols_, &sub_protocol_,
- &failure_message) &&
- ValidateExtensions(headers, &extensions_, &failure_message,
- extension_params_.get())) {
+ if (!ValidateStatus(headers)) {
+ result_ = HandshakeResult::HTTP2_INVALID_STATUS;
+ } else if (!ValidateSubProtocol(headers, requested_sub_protocols_,
+ &sub_protocol_, &failure_message)) {
+ result_ = HandshakeResult::HTTP2_FAILED_SUBPROTO;
+ } else if (!ValidateExtensions(headers, &extensions_, &failure_message,
+ extension_params_.get())) {
+ result_ = HandshakeResult::HTTP2_FAILED_EXTENSIONS;
+ } else {
+ result_ = HandshakeResult::HTTP2_CONNECTED;
return OK;
}
OnFailure("Error during WebSocket handshake: " + failure_message);
diff --git a/chromium/net/websockets/websocket_http2_handshake_stream.h b/chromium/net/websockets/websocket_http2_handshake_stream.h
index 7036e4b6773..b31db32a83e 100644
--- a/chromium/net/websockets/websocket_http2_handshake_stream.h
+++ b/chromium/net/websockets/websocket_http2_handshake_stream.h
@@ -124,6 +124,8 @@ class NET_EXPORT_PRIVATE WebSocketHttp2HandshakeStream
void OnFailure(const std::string& message);
+ HandshakeResult result_;
+
// The connection to open the Websocket stream on.
base::WeakPtr<SpdySession> session_;
diff --git a/chromium/net/websockets/websocket_inflater.cc b/chromium/net/websockets/websocket_inflater.cc
index 892f506ad18..7f04781acf8 100644
--- a/chromium/net/websockets/websocket_inflater.cc
+++ b/chromium/net/websockets/websocket_inflater.cc
@@ -46,7 +46,7 @@ WebSocketInflater::WebSocketInflater(size_t input_queue_capacity,
bool WebSocketInflater::Initialize(int window_bits) {
DCHECK_LE(8, window_bits);
DCHECK_GE(15, window_bits);
- stream_.reset(new z_stream);
+ stream_ = std::make_unique<z_stream>();
memset(stream_.get(), 0, sizeof(*stream_));
int result = inflateInit2(stream_.get(), -window_bits);
if (result != Z_OK) {
@@ -86,8 +86,7 @@ bool WebSocketInflater::Finish() {
}
scoped_refptr<IOBufferWithSize> WebSocketInflater::GetOutput(size_t size) {
- scoped_refptr<ShrinkableIOBufferWithSize> buffer =
- new ShrinkableIOBufferWithSize(size);
+ auto buffer = base::MakeRefCounted<ShrinkableIOBufferWithSize>(size);
size_t num_bytes_copied = 0;
while (num_bytes_copied < size && output_buffer_.Size() > 0) {
@@ -244,7 +243,7 @@ void WebSocketInflater::InputQueue::Push(const char* data, size_t size) {
while (num_copied_bytes < size) {
DCHECK(IsEmpty() || tail_of_last_buffer_ == capacity_);
- buffers_.push_back(new IOBufferWithSize(capacity_));
+ buffers_.push_back(base::MakeRefCounted<IOBufferWithSize>(capacity_));
tail_of_last_buffer_ = 0;
num_copied_bytes +=
PushToLastBuffer(&data[num_copied_bytes], size - num_copied_bytes);
diff --git a/chromium/net/websockets/websocket_inflater.h b/chromium/net/websockets/websocket_inflater.h
index c861a10092c..e92fea3890a 100644
--- a/chromium/net/websockets/websocket_inflater.h
+++ b/chromium/net/websockets/websocket_inflater.h
@@ -13,7 +13,7 @@
#include "base/containers/circular_deque.h"
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
#include "net/base/net_export.h"
extern "C" struct z_stream_s;
diff --git a/chromium/net/websockets/websocket_inflater_test.cc b/chromium/net/websockets/websocket_inflater_test.cc
index 2fd90f4b989..5e09ff718c7 100644
--- a/chromium/net/websockets/websocket_inflater_test.cc
+++ b/chromium/net/websockets/websocket_inflater_test.cc
@@ -8,7 +8,6 @@
#include <string>
#include <vector>
-#include "base/memory/ref_counted.h"
#include "net/base/io_buffer.h"
#include "net/websockets/websocket_deflater.h"
#include "net/websockets/websocket_test_util.h"
diff --git a/chromium/net/websockets/websocket_stream.cc b/chromium/net/websockets/websocket_stream.cc
index f22756c881c..ad98c833eed 100644
--- a/chromium/net/websockets/websocket_stream.cc
+++ b/chromium/net/websockets/websocket_stream.cc
@@ -8,18 +8,19 @@
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/load_flags.h"
#include "net/base/url_util.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
+#include "net/http/http_response_info.h"
#include "net/http/http_status_code.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/redirect_info.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
+#include "net/url_request/websocket_handshake_userdata_key.h"
#include "net/websockets/websocket_errors.h"
#include "net/websockets/websocket_event_interface.h"
#include "net/websockets/websocket_handshake_constants.h"
@@ -70,19 +71,8 @@ class WebSocketStreamRequestImpl;
class Delegate : public URLRequest::Delegate {
public:
- enum HandshakeResult {
- INCOMPLETE,
- CONNECTED,
- FAILED,
- NUM_HANDSHAKE_RESULT_TYPES,
- };
-
- explicit Delegate(WebSocketStreamRequestImpl* owner)
- : owner_(owner), result_(INCOMPLETE) {}
- ~Delegate() override {
- UMA_HISTOGRAM_ENUMERATION(
- "Net.WebSocket.HandshakeResult", result_, NUM_HANDSHAKE_RESULT_TYPES);
- }
+ explicit Delegate(WebSocketStreamRequestImpl* owner) : owner_(owner) {}
+ ~Delegate() override = default;
// Implementation of URLRequest::Delegate methods.
void OnReceivedRedirect(URLRequest* request,
@@ -105,7 +95,6 @@ class Delegate : public URLRequest::Delegate {
private:
WebSocketStreamRequestImpl* owner_;
- HandshakeResult result_;
};
class WebSocketStreamRequestImpl : public WebSocketStreamRequest {
@@ -118,7 +107,7 @@ class WebSocketStreamRequestImpl : public WebSocketStreamRequest {
const std::string& additional_headers,
std::unique_ptr<WebSocketStream::ConnectDelegate> connect_delegate,
std::unique_ptr<WebSocketHandshakeStreamCreateHelper> create_helper)
- : delegate_(new Delegate(this)),
+ : delegate_(std::make_unique<Delegate>(this)),
url_request_(context->CreateRequest(url,
DEFAULT_PRIORITY,
delegate_.get(),
@@ -139,9 +128,8 @@ class WebSocketStreamRequestImpl : public WebSocketStreamRequest {
url_request_->set_initiator(origin);
url_request_->set_site_for_cookies(site_for_cookies);
- url_request_->SetUserData(
- WebSocketHandshakeStreamBase::CreateHelper::DataKey(),
- std::move(create_helper));
+ url_request_->SetUserData(kWebSocketHandshakeUserDataKey,
+ std::move(create_helper));
url_request_->SetLoadFlags(LOAD_DISABLE_CACHE | LOAD_BYPASS_CACHE);
connect_delegate_->OnCreateRequest(url_request_.get());
}
@@ -329,27 +317,35 @@ void Delegate::OnResponseStarted(URLRequest* request, int net_error) {
}
const int response_code = request->GetResponseCode();
DVLOG(3) << "OnResponseStarted (response code " << response_code << ")";
+
+ if (request->response_info().connection_info ==
+ HttpResponseInfo::CONNECTION_INFO_HTTP2) {
+ if (response_code == HTTP_OK) {
+ owner_->PerformUpgrade();
+ return;
+ }
+
+ owner_->ReportFailure(net_error);
+ return;
+ }
+
switch (response_code) {
case HTTP_SWITCHING_PROTOCOLS:
- result_ = CONNECTED;
owner_->PerformUpgrade();
return;
case HTTP_UNAUTHORIZED:
- result_ = FAILED;
owner_->OnFinishOpeningHandshake();
owner_->ReportFailureWithMessage(
"HTTP Authentication failed; no valid credentials available");
return;
case HTTP_PROXY_AUTHENTICATION_REQUIRED:
- result_ = FAILED;
owner_->OnFinishOpeningHandshake();
owner_->ReportFailureWithMessage("Proxy authentication failed");
return;
default:
- result_ = FAILED;
owner_->ReportFailure(net_error);
}
}
@@ -375,9 +371,7 @@ void Delegate::OnSSLCertificateError(URLRequest* request,
const SSLInfo& ssl_info,
bool fatal) {
owner_->connect_delegate()->OnSSLCertificateError(
- std::unique_ptr<WebSocketEventInterface::SSLErrorCallbacks>(
- new SSLErrorCallbacks(request)),
- ssl_info, fatal);
+ std::make_unique<SSLErrorCallbacks>(request), ssl_info, fatal);
}
void Delegate::OnReadCompleted(URLRequest* request, int bytes_read) {
@@ -402,12 +396,11 @@ std::unique_ptr<WebSocketStreamRequest> WebSocketStream::CreateAndConnectStream(
URLRequestContext* url_request_context,
const NetLogWithSource& net_log,
std::unique_ptr<ConnectDelegate> connect_delegate) {
- std::unique_ptr<WebSocketStreamRequestImpl> request(
- new WebSocketStreamRequestImpl(socket_url, url_request_context, origin,
- site_for_cookies, additional_headers,
- std::move(connect_delegate),
- std::move(create_helper)));
- request->Start(std::unique_ptr<base::Timer>(new base::Timer(false, false)));
+ auto request = std::make_unique<WebSocketStreamRequestImpl>(
+ socket_url, url_request_context, origin, site_for_cookies,
+ additional_headers, std::move(connect_delegate),
+ std::move(create_helper));
+ request->Start(std::make_unique<base::Timer>(false, false));
return std::move(request);
}
@@ -422,11 +415,10 @@ WebSocketStream::CreateAndConnectStreamForTesting(
const NetLogWithSource& net_log,
std::unique_ptr<WebSocketStream::ConnectDelegate> connect_delegate,
std::unique_ptr<base::Timer> timer) {
- std::unique_ptr<WebSocketStreamRequestImpl> request(
- new WebSocketStreamRequestImpl(socket_url, url_request_context, origin,
- site_for_cookies, additional_headers,
- std::move(connect_delegate),
- std::move(create_helper)));
+ auto request = std::make_unique<WebSocketStreamRequestImpl>(
+ socket_url, url_request_context, origin, site_for_cookies,
+ additional_headers, std::move(connect_delegate),
+ std::move(create_helper));
request->Start(std::move(timer));
return std::move(request);
}
diff --git a/chromium/net/websockets/websocket_stream.h b/chromium/net/websockets/websocket_stream.h
index ff898cc454a..d315e5ae293 100644
--- a/chromium/net/websockets/websocket_stream.h
+++ b/chromium/net/websockets/websocket_stream.h
@@ -11,7 +11,7 @@
#include "base/callback_forward.h"
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
#include "base/time/time.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
diff --git a/chromium/net/websockets/websocket_stream_cookie_test.cc b/chromium/net/websockets/websocket_stream_cookie_test.cc
index 12f1a44f771..ae94d5ee4cd 100644
--- a/chromium/net/websockets/websocket_stream_cookie_test.cc
+++ b/chromium/net/websockets/websocket_stream_cookie_test.cc
@@ -125,7 +125,8 @@ class WebSocketStreamServerSetCookieTest
TEST_P(WebSocketStreamClientUseCookieTest, ClientUseCookie) {
// For wss tests.
- ssl_data_.push_back(std::make_unique<SSLSocketDataProvider>(ASYNC, OK));
+ url_request_context_host_.AddSSLSocketDataProvider(
+ std::make_unique<SSLSocketDataProvider>(ASYNC, OK));
CookieStore* store =
url_request_context_host_.GetURLRequestContext()->cookie_store();
@@ -161,7 +162,8 @@ TEST_P(WebSocketStreamClientUseCookieTest, ClientUseCookie) {
TEST_P(WebSocketStreamServerSetCookieTest, ServerSetCookie) {
// For wss tests.
- ssl_data_.push_back(std::make_unique<SSLSocketDataProvider>(ASYNC, OK));
+ url_request_context_host_.AddSSLSocketDataProvider(
+ std::make_unique<SSLSocketDataProvider>(ASYNC, OK));
const GURL url(GetParam().url);
const GURL cookie_url(GetParam().cookie_url);
diff --git a/chromium/net/websockets/websocket_stream_create_test_base.cc b/chromium/net/websockets/websocket_stream_create_test_base.cc
index 4d51551ba15..70983744f54 100644
--- a/chromium/net/websockets/websocket_stream_create_test_base.cc
+++ b/chromium/net/websockets/websocket_stream_create_test_base.cc
@@ -87,22 +87,16 @@ void WebSocketStreamCreateTestBase::CreateAndConnectStream(
const GURL& site_for_cookies,
const std::string& additional_headers,
std::unique_ptr<base::Timer> timer) {
- for (size_t i = 0; i < ssl_data_.size(); ++i) {
- url_request_context_host_.AddSSLSocketDataProvider(std::move(ssl_data_[i]));
- }
- ssl_data_.clear();
- std::unique_ptr<WebSocketStream::ConnectDelegate> connect_delegate(
- new TestConnectDelegate(this, connect_run_loop_.QuitClosure()));
- WebSocketStream::ConnectDelegate* delegate = connect_delegate.get();
+ auto connect_delegate = std::make_unique<TestConnectDelegate>(
+ this, connect_run_loop_.QuitClosure());
auto create_helper =
- std::make_unique<TestWebSocketHandshakeStreamCreateHelper>(delegate,
- sub_protocols);
+ std::make_unique<TestWebSocketHandshakeStreamCreateHelper>(
+ connect_delegate.get(), sub_protocols);
stream_request_ = WebSocketStream::CreateAndConnectStreamForTesting(
socket_url, std::move(create_helper), origin, site_for_cookies,
additional_headers, url_request_context_host_.GetURLRequestContext(),
NetLogWithSource(), std::move(connect_delegate),
- timer ? std::move(timer)
- : std::unique_ptr<base::Timer>(new base::Timer(false, false)));
+ timer ? std::move(timer) : std::make_unique<base::Timer>(false, false));
}
std::vector<HeaderKeyValuePair>
diff --git a/chromium/net/websockets/websocket_stream_create_test_base.h b/chromium/net/websockets/websocket_stream_create_test_base.h
index aab93c7641d..4992d49a0ba 100644
--- a/chromium/net/websockets/websocket_stream_create_test_base.h
+++ b/chromium/net/websockets/websocket_stream_create_test_base.h
@@ -75,12 +75,8 @@ class WebSocketStreamCreateTestBase {
ssl_error_callbacks_;
SSLInfo ssl_info_;
bool ssl_fatal_;
- std::vector<std::unique_ptr<SSLSocketDataProvider>> ssl_data_;
URLRequest* url_request_;
- // This temporarily sets WebSocketEndpointLockManager unlock delay to zero
- // during tests.
- ScopedWebSocketEndpointZeroUnlockDelay zero_unlock_delay_;
base::RunLoop connect_run_loop_;
private:
diff --git a/chromium/net/websockets/websocket_stream_test.cc b/chromium/net/websockets/websocket_stream_test.cc
index def32a215dc..0ac9793061b 100644
--- a/chromium/net/websockets/websocket_stream_test.cc
+++ b/chromium/net/websockets/websocket_stream_test.cc
@@ -11,20 +11,23 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/memory/ptr_util.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_samples.h"
#include "base/metrics/statistics_recorder.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
+#include "base/test/histogram_tester.h"
#include "base/timer/mock_timer.h"
#include "base/timer/timer.h"
#include "net/base/net_errors.h"
+#include "net/base/url_util.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/socket_test_util.h"
+#include "net/spdy/chromium/spdy_test_util_common.h"
+#include "net/spdy/core/spdy_protocol.h"
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
@@ -38,11 +41,16 @@
#include "url/gurl.h"
#include "url/origin.h"
-using net::test::IsOk;
+using ::net::test::IsError;
+using ::net::test::IsOk;
+using ::testing::TestWithParam;
+using ::testing::Values;
namespace net {
namespace {
+enum HandshakeStreamType { BASIC_HANDSHAKE_STREAM, HTTP2_HANDSHAKE_STREAM };
+
// Simple builder for a SequencedSocketData object to save repetitive code.
// It always sets the connect data to MockConnect(SYNCHRONOUS, OK), so it cannot
// be used in tests where the connect fails. In practice, those tests never have
@@ -53,8 +61,8 @@ template <size_t reads_count, size_t writes_count>
std::unique_ptr<SequencedSocketData> BuildSocketData(
MockRead (&reads)[reads_count],
MockWrite (&writes)[writes_count]) {
- std::unique_ptr<SequencedSocketData> socket_data(
- new SequencedSocketData(reads, reads_count, writes, writes_count));
+ auto socket_data = std::make_unique<SequencedSocketData>(
+ reads, reads_count, writes, writes_count);
socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
return socket_data;
}
@@ -72,25 +80,24 @@ class MockWeakTimer : public base::MockTimer,
: MockTimer(retain_user_task, is_repeating) {}
};
-static url::Origin LocalhostOrigin() {
- return url::Origin::Create(GURL("http://localhost/"));
-}
-
-static GURL LocalhostUrl() {
- return GURL("http://localhost/foobar");
-}
+const char kOrigin[] = "http://www.example.org";
-static url::Origin GoogleOrigin() {
- return url::Origin::Create(GURL("http://google.com/"));
+static url::Origin Origin() {
+ return url::Origin::Create(GURL(kOrigin));
}
-static GURL GoogleUrl() {
- return GURL("http://google.com/foobar");
+static GURL SiteForCookies() {
+ return GURL("http://www.example.org/foobar");
}
-class WebSocketStreamCreateTest : public ::testing::Test,
+class WebSocketStreamCreateTest : public TestWithParam<HandshakeStreamType>,
public WebSocketStreamCreateTestBase {
- public:
+ protected:
+ WebSocketStreamCreateTest()
+ : stream_type_(GetParam()),
+ http2_response_status_("200"),
+ reset_websocket_http2_stream_(false),
+ sequence_number_(0) {}
~WebSocketStreamCreateTest() override {
// Permit any endpoint locks to be released.
stream_request_.reset();
@@ -98,84 +105,315 @@ class WebSocketStreamCreateTest : public ::testing::Test,
base::RunLoop().RunUntilIdle();
}
+ void AddSSLData() {
+ auto ssl_data = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
+ ssl_data->ssl_info.cert =
+ ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
+ if (stream_type_ == HTTP2_HANDSHAKE_STREAM)
+ ssl_data->next_proto = kProtoHTTP2;
+ ASSERT_TRUE(ssl_data->ssl_info.cert.get());
+ url_request_context_host_.AddSSLSocketDataProvider(std::move(ssl_data));
+ }
+
+ void SetTimer(std::unique_ptr<base::Timer> timer) {
+ timer_ = std::move(timer);
+ }
+
+ void SetAdditionalResponseData(std::string additional_data) {
+ additional_data_ = std::move(additional_data);
+ }
+
+ void SetHttp2ResponseStatus(const char* const http2_response_status) {
+ http2_response_status_ = http2_response_status;
+ }
+
+ void SetResetWebSocketHttp2Stream(bool reset_websocket_http2_stream) {
+ reset_websocket_http2_stream_ = reset_websocket_http2_stream;
+ }
+
+ // Set up mock data and start websockets request, either for WebSocket
+ // upgraded from an HTTP/1 connection, or for a WebSocket request over HTTP/2.
+ void CreateAndConnectStandard(
+ base::StringPiece url,
+ const std::vector<std::string>& sub_protocols,
+ const WebSocketExtraHeaders& send_additional_request_headers,
+ const WebSocketExtraHeaders& extra_request_headers,
+ const WebSocketExtraHeaders& extra_response_headers) {
+ const GURL socket_url(url);
+ const std::string socket_host = GetHostAndOptionalPort(socket_url);
+ const std::string socket_path = socket_url.path();
+
+ if (stream_type_ == BASIC_HANDSHAKE_STREAM) {
+ url_request_context_host_.SetExpectations(
+ WebSocketStandardRequest(
+ socket_path, socket_host, Origin(),
+ WebSocketExtraHeadersToString(send_additional_request_headers),
+ WebSocketExtraHeadersToString(extra_request_headers)),
+ WebSocketStandardResponse(
+ WebSocketExtraHeadersToString(extra_response_headers)) +
+ additional_data_);
+ CreateAndConnectStream(
+ socket_url, sub_protocols, Origin(), SiteForCookies(),
+ WebSocketExtraHeadersToString(send_additional_request_headers),
+ std::move(timer_));
+ return;
+ }
+
+ DCHECK_EQ(stream_type_, HTTP2_HANDSHAKE_STREAM);
+
+ // TODO(bnc): Find a way to clear
+ // spdy_session_pool.enable_sending_initial_data_ to avoid sending
+ // connection preface, initial settings, and window update.
+
+ // HTTP/2 connection preface.
+ frames_.push_back(
+ SpdySerializedFrame(const_cast<char*>(kHttp2ConnectionHeaderPrefix),
+ kHttp2ConnectionHeaderPrefixSize,
+ /* owns_buffer = */ false));
+ AddWrite(&frames_.back());
+
+ // Server advertises WebSockets over HTTP/2 support.
+ SettingsMap read_settings;
+ read_settings[SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
+ frames_.push_back(spdy_util_.ConstructSpdySettings(read_settings));
+ AddRead(&frames_.back());
+
+ // Initial SETTINGS frame.
+ SettingsMap write_settings;
+ write_settings[SETTINGS_HEADER_TABLE_SIZE] = kSpdyMaxHeaderTableSize;
+ write_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
+ kSpdyMaxConcurrentPushedStreams;
+ write_settings[SETTINGS_INITIAL_WINDOW_SIZE] = 6 * 1024 * 1024;
+ frames_.push_back(spdy_util_.ConstructSpdySettings(write_settings));
+ AddWrite(&frames_.back());
+
+ // Initial window update frame.
+ frames_.push_back(spdy_util_.ConstructSpdyWindowUpdate(0, 0x00ef0001));
+ AddWrite(&frames_.back());
+
+ // SETTINGS ACK sent as a response to server's SETTINGS frame.
+ frames_.push_back(spdy_util_.ConstructSpdySettingsAck());
+ AddWrite(&frames_.back());
+
+ // First request. This is necessary, because a WebSockets request currently
+ // does not open a new HTTP/2 connection, it only uses an existing one.
+ const char* const kExtraRequestHeaders[] = {
+ "user-agent", "", "accept-encoding", "gzip, deflate",
+ "accept-language", "en-us,fr"};
+ frames_.push_back(spdy_util_.ConstructSpdyGet(
+ kExtraRequestHeaders, arraysize(kExtraRequestHeaders) / 2, 1,
+ DEFAULT_PRIORITY));
+ AddWrite(&frames_.back());
+
+ // SETTINGS ACK frame sent by the server in response to the client's
+ // initial SETTINGS frame.
+ frames_.push_back(spdy_util_.ConstructSpdySettingsAck());
+ AddRead(&frames_.back());
+
+ // Response headers to first request.
+ frames_.push_back(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
+ AddRead(&frames_.back());
+
+ // Response body to first request.
+ frames_.push_back(spdy_util_.ConstructSpdyDataFrame(1, true));
+ AddRead(&frames_.back());
+
+ // First request is closed.
+ spdy_util_.UpdateWithStreamDestruction(1);
+
+ // WebSocket request.
+ SpdyHeaderBlock request_headers = WebSocketHttp2Request(
+ socket_path, socket_host, kOrigin, extra_request_headers);
+ frames_.push_back(spdy_util_.ConstructSpdyHeaders(
+ 3, std::move(request_headers), DEFAULT_PRIORITY, false));
+ AddWrite(&frames_.back());
+
+ if (reset_websocket_http2_stream_) {
+ frames_.push_back(
+ spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
+ AddRead(&frames_.back());
+ } else {
+ // Response to WebSocket request.
+ std::vector<std::string> extra_response_header_keys;
+ std::vector<const char*> extra_response_headers_vector;
+ for (const auto& extra_header : extra_response_headers) {
+ // Save a lowercase copy of the header key.
+ extra_response_header_keys.push_back(
+ base::ToLowerASCII(extra_header.first));
+ // Save a pointer to this lowercase copy.
+ extra_response_headers_vector.push_back(
+ extra_response_header_keys.back().c_str());
+ // Save a pointer to the original header value provided by the caller.
+ extra_response_headers_vector.push_back(extra_header.second.c_str());
+ }
+ frames_.push_back(spdy_util_.ConstructSpdyReplyError(
+ http2_response_status_, extra_response_headers_vector.data(),
+ extra_response_headers_vector.size() / 2, 3));
+ AddRead(&frames_.back());
+
+ // WebSocket data received.
+ if (!additional_data_.empty()) {
+ frames_.push_back(
+ spdy_util_.ConstructSpdyDataFrame(3, additional_data_, true));
+ AddRead(&frames_.back());
+ }
+
+ // Client cancels HTTP/2 stream when request is destroyed.
+ frames_.push_back(
+ spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
+ AddWrite(&frames_.back());
+ }
+
+ // EOF.
+ reads_.push_back(MockRead(ASYNC, 0, sequence_number_++));
+
+ auto socket_data = std::make_unique<SequencedSocketData>(
+ reads_.data(), reads_.size(), writes_.data(), writes_.size());
+ socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
+ url_request_context_host_.AddRawExpectations(std::move(socket_data));
+
+ // Send first request. This makes sure server's
+ // SETTINGS_ENABLE_CONNECT_PROTOCOL advertisement is read.
+ TestURLRequestContext* context =
+ url_request_context_host_.GetURLRequestContext();
+ TestDelegate delegate;
+ std::unique_ptr<URLRequest> request = context->CreateRequest(
+ GURL("https://www.example.org/"), DEFAULT_PRIORITY, &delegate,
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ request->Start();
+ EXPECT_TRUE(request->is_pending());
+ base::RunLoop().Run();
+ EXPECT_FALSE(request->is_pending());
+
+ CreateAndConnectStream(
+ socket_url, sub_protocols, Origin(), SiteForCookies(),
+ WebSocketExtraHeadersToString(send_additional_request_headers),
+ std::move(timer_));
+ }
+
+ // Like CreateAndConnectStandard(), but allow for arbitrary response body.
+ // Only for HTTP/1-based WebSockets.
void CreateAndConnectCustomResponse(
- const std::string& socket_url,
- const std::string& socket_host,
- const std::string& socket_path,
+ base::StringPiece url,
const std::vector<std::string>& sub_protocols,
- const url::Origin& origin,
- const GURL& site_for_cookies,
- const std::string& send_additional_request_headers,
- const std::string& extra_request_headers,
- const std::string& response_body,
- std::unique_ptr<base::Timer> timer = std::unique_ptr<base::Timer>()) {
+ const WebSocketExtraHeaders& send_additional_request_headers,
+ const WebSocketExtraHeaders& extra_request_headers,
+ const std::string& response_body) {
+ ASSERT_EQ(BASIC_HANDSHAKE_STREAM, stream_type_);
+
+ const GURL socket_url(url);
+ const std::string socket_host = GetHostAndOptionalPort(socket_url);
+ const std::string socket_path = socket_url.path();
+
url_request_context_host_.SetExpectations(
- WebSocketStandardRequest(socket_path, socket_host, origin,
- send_additional_request_headers,
- extra_request_headers),
+ WebSocketStandardRequest(
+ socket_path, socket_host, Origin(),
+ WebSocketExtraHeadersToString(send_additional_request_headers),
+ WebSocketExtraHeadersToString(extra_request_headers)),
response_body);
- CreateAndConnectStream(GURL(socket_url), sub_protocols, origin,
- site_for_cookies, send_additional_request_headers,
- std::move(timer));
+ CreateAndConnectStream(
+ socket_url, sub_protocols, Origin(), SiteForCookies(),
+ WebSocketExtraHeadersToString(send_additional_request_headers),
+ nullptr);
}
- // |extra_request_headers| and |extra_response_headers| must end in "\r\n" or
- // errors like "Unable to perform synchronous IO while stopped" will occur.
- void CreateAndConnectStandard(
- const std::string& socket_url,
- const std::string& socket_host,
- const std::string& socket_path,
+ // Like CreateAndConnectStandard(), but take extra response headers as a
+ // string. This can save space in case of a very large response.
+ // Only for HTTP/1-based WebSockets.
+ void CreateAndConnectStringResponse(
+ base::StringPiece url,
const std::vector<std::string>& sub_protocols,
- const url::Origin& origin,
- const GURL& site_for_cookies,
- const std::string& send_additional_request_headers,
- const std::string& extra_request_headers,
- const std::string& extra_response_headers,
- std::unique_ptr<base::Timer> timer = std::unique_ptr<base::Timer>()) {
- CreateAndConnectCustomResponse(
- socket_url, socket_host, socket_path, sub_protocols, origin,
- site_for_cookies, send_additional_request_headers,
- extra_request_headers,
- WebSocketStandardResponse(extra_response_headers), std::move(timer));
+ const std::string& extra_response_headers) {
+ ASSERT_EQ(BASIC_HANDSHAKE_STREAM, stream_type_);
+
+ const GURL socket_url(url);
+ const std::string socket_host = GetHostAndOptionalPort(socket_url);
+ const std::string socket_path = socket_url.path();
+
+ url_request_context_host_.SetExpectations(
+ WebSocketStandardRequest(socket_path, socket_host, Origin(), "", ""),
+ WebSocketStandardResponse(extra_response_headers));
+ CreateAndConnectStream(socket_url, sub_protocols, Origin(),
+ SiteForCookies(), "", nullptr);
}
+ // Like CreateAndConnectStandard(), but take raw mock data.
void CreateAndConnectRawExpectations(
- const std::string& socket_url,
+ base::StringPiece url,
const std::vector<std::string>& sub_protocols,
- const url::Origin& origin,
- const GURL& site_for_cookies,
const std::string& send_additional_request_headers,
- std::unique_ptr<SequencedSocketData> socket_data,
- std::unique_ptr<base::Timer> timer = std::unique_ptr<base::Timer>()) {
- AddRawExpectations(std::move(socket_data));
- CreateAndConnectStream(GURL(socket_url), sub_protocols, origin,
- site_for_cookies, send_additional_request_headers,
- std::move(timer));
- }
+ std::unique_ptr<SequencedSocketData> socket_data) {
+ ASSERT_EQ(BASIC_HANDSHAKE_STREAM, stream_type_);
- // Add additional raw expectations for sockets created before the final one.
- void AddRawExpectations(std::unique_ptr<SequencedSocketData> socket_data) {
url_request_context_host_.AddRawExpectations(std::move(socket_data));
+ CreateAndConnectStream(GURL(url), sub_protocols, Origin(), SiteForCookies(),
+ send_additional_request_headers, std::move(timer_));
+ }
+
+ private:
+ void AddWrite(const SpdySerializedFrame* frame) {
+ writes_.push_back(
+ MockWrite(ASYNC, frame->data(), frame->size(), sequence_number_++));
}
+
+ void AddRead(const SpdySerializedFrame* frame) {
+ reads_.push_back(
+ MockRead(ASYNC, frame->data(), frame->size(), sequence_number_++));
+ }
+
+ protected:
+ const HandshakeStreamType stream_type_;
+
+ private:
+ std::unique_ptr<base::Timer> timer_;
+ std::string additional_data_;
+ const char* http2_response_status_;
+ bool reset_websocket_http2_stream_;
+ SpdyTestUtil spdy_util_;
+ NetLogWithSource log_;
+
+ int sequence_number_;
+
+ // Store mock HTTP/2 data.
+ std::vector<SpdySerializedFrame> frames_;
+
+ // Store MockRead and MockWrite objects that have pointers to above data.
+ std::vector<MockRead> reads_;
+ std::vector<MockWrite> writes_;
};
+INSTANTIATE_TEST_CASE_P(,
+ WebSocketStreamCreateTest,
+ Values(BASIC_HANDSHAKE_STREAM));
+
+using WebSocketMultiProtocolStreamCreateTest = WebSocketStreamCreateTest;
+
+INSTANTIATE_TEST_CASE_P(,
+ WebSocketMultiProtocolStreamCreateTest,
+ Values(BASIC_HANDSHAKE_STREAM, HTTP2_HANDSHAKE_STREAM));
+
// There are enough tests of the Sec-WebSocket-Extensions header that they
// deserve their own test fixture.
-class WebSocketStreamCreateExtensionTest : public WebSocketStreamCreateTest {
- public:
+class WebSocketStreamCreateExtensionTest
+ : public WebSocketMultiProtocolStreamCreateTest {
+ protected:
// Performs a standard connect, with the value of the Sec-WebSocket-Extensions
// header in the response set to |extensions_header_value|. Runs the event
// loop to allow the connect to complete.
void CreateAndConnectWithExtensions(
const std::string& extensions_header_value) {
+ AddSSLData();
CreateAndConnectStandard(
- "ws://localhost/testing_path", "localhost", "/testing_path",
- NoSubProtocols(), LocalhostOrigin(), LocalhostUrl(), "", "",
- "Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n");
+ "wss://www.example.org/testing_path", NoSubProtocols(), {}, {},
+ {{"Sec-WebSocket-Extensions", extensions_header_value}});
WaitUntilConnectDone();
}
};
+INSTANTIATE_TEST_CASE_P(,
+ WebSocketStreamCreateExtensionTest,
+ Values(BASIC_HANDSHAKE_STREAM, HTTP2_HANDSHAKE_STREAM));
+
// Common code to construct expectations for authentication tests that receive
// the auth challenge on one connection and then create a second connection to
// send the authenticated request on.
@@ -186,7 +424,7 @@ class CommonAuthTestHelper {
std::unique_ptr<SequencedSocketData> BuildSocketData1(
const std::string& response) {
request1_ =
- WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), "", "");
+ WebSocketStandardRequest("/", "www.example.org", Origin(), "", "");
writes1_[0] = MockWrite(SYNCHRONOUS, 0, request1_.c_str());
response1_ = response;
reads1_[0] = MockRead(SYNCHRONOUS, 1, response1_.c_str());
@@ -226,17 +464,18 @@ class WebSocketStreamCreateBasicAuthTest : public WebSocketStreamCreateTest {
void CreateAndConnectAuthHandshake(const std::string& url,
const std::string& base64_user_pass,
const std::string& response2) {
- AddRawExpectations(helper_.BuildSocketData1(kUnauthorizedResponse));
+ url_request_context_host_.AddRawExpectations(
+ helper_.BuildSocketData1(kUnauthorizedResponse));
static const char request2format[] =
"GET / HTTP/1.1\r\n"
- "Host: localhost\r\n"
+ "Host: www.example.org\r\n"
"Connection: Upgrade\r\n"
"Pragma: no-cache\r\n"
"Cache-Control: no-cache\r\n"
"Authorization: Basic %s\r\n"
"Upgrade: websocket\r\n"
- "Origin: http://localhost\r\n"
+ "Origin: http://www.example.org\r\n"
"Sec-WebSocket-Version: 13\r\n"
"User-Agent:\r\n"
"Accept-Encoding: gzip, deflate\r\n"
@@ -248,7 +487,7 @@ class WebSocketStreamCreateBasicAuthTest : public WebSocketStreamCreateTest {
const std::string request =
base::StringPrintf(request2format, base64_user_pass.c_str());
CreateAndConnectRawExpectations(
- url, NoSubProtocols(), LocalhostOrigin(), LocalhostUrl(), "",
+ url, NoSubProtocols(), "",
helper_.BuildSocketData2(request, response2));
}
@@ -257,6 +496,10 @@ class WebSocketStreamCreateBasicAuthTest : public WebSocketStreamCreateTest {
CommonAuthTestHelper helper_;
};
+INSTANTIATE_TEST_CASE_P(,
+ WebSocketStreamCreateBasicAuthTest,
+ Values(BASIC_HANDSHAKE_STREAM));
+
class WebSocketStreamCreateDigestAuthTest : public WebSocketStreamCreateTest {
protected:
static const char kUnauthorizedResponse[];
@@ -265,6 +508,10 @@ class WebSocketStreamCreateDigestAuthTest : public WebSocketStreamCreateTest {
CommonAuthTestHelper helper_;
};
+INSTANTIATE_TEST_CASE_P(,
+ WebSocketStreamCreateDigestAuthTest,
+ Values(BASIC_HANDSHAKE_STREAM));
+
const char WebSocketStreamCreateBasicAuthTest::kUnauthorizedResponse[] =
"HTTP/1.1 401 Unauthorized\r\n"
"Content-Length: 0\r\n"
@@ -283,7 +530,7 @@ const char WebSocketStreamCreateDigestAuthTest::kUnauthorizedResponse[] =
const char WebSocketStreamCreateDigestAuthTest::kAuthorizedRequest[] =
"GET / HTTP/1.1\r\n"
- "Host: localhost\r\n"
+ "Host: www.example.org\r\n"
"Connection: Upgrade\r\n"
"Pragma: no-cache\r\n"
"Cache-Control: no-cache\r\n"
@@ -291,7 +538,7 @@ const char WebSocketStreamCreateDigestAuthTest::kAuthorizedRequest[] =
"nonce=\"nonce-value\", uri=\"/\", "
"response=\"f72ff54ebde2f928860f806ec04acd1b\"\r\n"
"Upgrade: websocket\r\n"
- "Origin: http://localhost\r\n"
+ "Origin: http://www.example.org\r\n"
"Sec-WebSocket-Version: 13\r\n"
"User-Agent:\r\n"
"Accept-Encoding: gzip, deflate\r\n"
@@ -301,34 +548,14 @@ const char WebSocketStreamCreateDigestAuthTest::kAuthorizedRequest[] =
"client_max_window_bits\r\n"
"\r\n";
-class WebSocketStreamCreateUMATest : public ::testing::Test {
- public:
- // This enum should match with the enum in Delegate in websocket_stream.cc.
- enum HandshakeResult {
- INCOMPLETE,
- CONNECTED,
- FAILED,
- NUM_HANDSHAKE_RESULT_TYPES,
- };
-
- class StreamCreation : public WebSocketStreamCreateTest {
- void TestBody() override {}
- };
-
- std::unique_ptr<base::HistogramSamples> GetSamples(const std::string& name) {
- base::HistogramBase* histogram =
- base::StatisticsRecorder::FindHistogram(name);
- return histogram ? histogram->SnapshotSamples()
- : std::unique_ptr<base::HistogramSamples>();
- }
-};
-
// Confirm that the basic case works as expected.
-TEST_F(WebSocketStreamCreateTest, SimpleSuccess) {
+TEST_P(WebSocketMultiProtocolStreamCreateTest, SimpleSuccess) {
+ base::HistogramTester histogram_tester;
+
+ AddSSLData();
EXPECT_FALSE(url_request_);
- CreateAndConnectStandard("ws://localhost/", "localhost", "/",
- NoSubProtocols(), LocalhostOrigin(), LocalhostUrl(),
- "", "", "");
+ CreateAndConnectStandard("wss://www.example.org/", NoSubProtocols(), {}, {},
+ {});
EXPECT_FALSE(request_info_);
EXPECT_FALSE(response_info_);
EXPECT_TRUE(url_request_);
@@ -339,9 +566,24 @@ TEST_F(WebSocketStreamCreateTest, SimpleSuccess) {
EXPECT_TRUE(response_info_);
EXPECT_EQ(ERR_WS_UPGRADE,
url_request_context_host_.network_delegate().last_error());
+
+ auto samples = histogram_tester.GetHistogramSamplesSinceCreation(
+ "Net.WebSocket.HandshakeResult2");
+ EXPECT_EQ(1, samples->TotalCount());
+ if (stream_type_ == BASIC_HANDSHAKE_STREAM) {
+ EXPECT_EQ(1,
+ samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::CONNECTED)));
+ } else {
+ DCHECK_EQ(stream_type_, HTTP2_HANDSHAKE_STREAM);
+ EXPECT_EQ(
+ 1,
+ samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::HTTP2_CONNECTED)));
+ }
}
-TEST_F(WebSocketStreamCreateTest, HandshakeInfo) {
+TEST_P(WebSocketStreamCreateTest, HandshakeInfo) {
static const char kResponse[] =
"HTTP/1.1 101 Switching Protocols\r\n"
"Upgrade: websocket\r\n"
@@ -352,9 +594,8 @@ TEST_F(WebSocketStreamCreateTest, HandshakeInfo) {
"hoge: piyo\r\n"
"\r\n";
- CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
- NoSubProtocols(), LocalhostOrigin(),
- LocalhostUrl(), "", "", kResponse);
+ CreateAndConnectCustomResponse("ws://www.example.org/", NoSubProtocols(), {},
+ {}, kResponse);
EXPECT_FALSE(request_info_);
EXPECT_FALSE(response_info_);
WaitUntilConnectDone();
@@ -365,18 +606,18 @@ TEST_F(WebSocketStreamCreateTest, HandshakeInfo) {
RequestHeadersToVector(request_info_->headers);
// We examine the contents of request_info_ and response_info_
// mainly only in this test case.
- EXPECT_EQ(GURL("ws://localhost/"), request_info_->url);
- EXPECT_EQ(GURL("ws://localhost/"), response_info_->url);
+ EXPECT_EQ(GURL("ws://www.example.org/"), request_info_->url);
+ EXPECT_EQ(GURL("ws://www.example.org/"), response_info_->url);
EXPECT_EQ(101, response_info_->status_code);
EXPECT_EQ("Switching Protocols", response_info_->status_text);
ASSERT_EQ(12u, request_headers.size());
- EXPECT_EQ(HeaderKeyValuePair("Host", "localhost"), request_headers[0]);
+ EXPECT_EQ(HeaderKeyValuePair("Host", "www.example.org"), request_headers[0]);
EXPECT_EQ(HeaderKeyValuePair("Connection", "Upgrade"), request_headers[1]);
EXPECT_EQ(HeaderKeyValuePair("Pragma", "no-cache"), request_headers[2]);
EXPECT_EQ(HeaderKeyValuePair("Cache-Control", "no-cache"),
request_headers[3]);
EXPECT_EQ(HeaderKeyValuePair("Upgrade", "websocket"), request_headers[4]);
- EXPECT_EQ(HeaderKeyValuePair("Origin", "http://localhost"),
+ EXPECT_EQ(HeaderKeyValuePair("Origin", "http://www.example.org"),
request_headers[5]);
EXPECT_EQ(HeaderKeyValuePair("Sec-WebSocket-Version", "13"),
request_headers[6]);
@@ -405,13 +646,11 @@ TEST_F(WebSocketStreamCreateTest, HandshakeInfo) {
}
// Confirms that request headers are overriden/added after handshake
-TEST_F(WebSocketStreamCreateTest, HandshakeOverrideHeaders) {
- std::string additional_headers(
- "User-Agent: OveRrIde\r\n"
- "rAnDomHeader: foobar\r\n");
- CreateAndConnectStandard("ws://localhost/", "localhost", "/",
- NoSubProtocols(), LocalhostOrigin(), LocalhostUrl(),
- additional_headers, additional_headers, "");
+TEST_P(WebSocketStreamCreateTest, HandshakeOverrideHeaders) {
+ WebSocketExtraHeaders additional_headers(
+ {{"User-Agent", "OveRrIde"}, {"rAnDomHeader", "foobar"}});
+ CreateAndConnectStandard("ws://www.example.org/", NoSubProtocols(),
+ additional_headers, additional_headers, {});
EXPECT_FALSE(request_info_);
EXPECT_FALSE(response_info_);
WaitUntilConnectDone();
@@ -427,45 +666,34 @@ TEST_F(WebSocketStreamCreateTest, HandshakeOverrideHeaders) {
}
// Confirm that the stream isn't established until the message loop runs.
-TEST_F(WebSocketStreamCreateTest, NeedsToRunLoop) {
- CreateAndConnectStandard("ws://localhost/", "localhost", "/",
- NoSubProtocols(), LocalhostOrigin(), LocalhostUrl(),
- "", "", "");
+TEST_P(WebSocketStreamCreateTest, NeedsToRunLoop) {
+ CreateAndConnectStandard("ws://www.example.org/", NoSubProtocols(), {}, {},
+ {});
EXPECT_FALSE(has_failed());
EXPECT_FALSE(stream_);
}
// Check the path is used.
-TEST_F(WebSocketStreamCreateTest, PathIsUsed) {
- CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
- "/testing_path", NoSubProtocols(), LocalhostOrigin(),
- LocalhostUrl(), "", "", "");
- WaitUntilConnectDone();
- EXPECT_FALSE(has_failed());
- EXPECT_TRUE(stream_);
-}
-
-// Check that the origin is used.
-TEST_F(WebSocketStreamCreateTest, OriginIsUsed) {
- CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
- "/testing_path", NoSubProtocols(), GoogleOrigin(),
- GoogleUrl(), "", "", "");
+TEST_P(WebSocketMultiProtocolStreamCreateTest, PathIsUsed) {
+ AddSSLData();
+ CreateAndConnectStandard("wss://www.example.org/testing_path",
+ NoSubProtocols(), {}, {}, {});
WaitUntilConnectDone();
EXPECT_FALSE(has_failed());
EXPECT_TRUE(stream_);
}
// Check that sub-protocols are sent and parsed.
-TEST_F(WebSocketStreamCreateTest, SubProtocolIsUsed) {
+TEST_P(WebSocketMultiProtocolStreamCreateTest, SubProtocolIsUsed) {
+ AddSSLData();
std::vector<std::string> sub_protocols;
sub_protocols.push_back("chatv11.chromium.org");
sub_protocols.push_back("chatv20.chromium.org");
- CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
- "/testing_path", sub_protocols, GoogleOrigin(),
- GoogleUrl(), "",
- "Sec-WebSocket-Protocol: chatv11.chromium.org, "
- "chatv20.chromium.org\r\n",
- "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n");
+ CreateAndConnectStandard(
+ "wss://www.example.org/testing_path", sub_protocols, {},
+ {{"Sec-WebSocket-Protocol",
+ "chatv11.chromium.org, chatv20.chromium.org"}},
+ {{"Sec-WebSocket-Protocol", "chatv20.chromium.org"}});
WaitUntilConnectDone();
EXPECT_TRUE(stream_);
EXPECT_FALSE(has_failed());
@@ -473,11 +701,13 @@ TEST_F(WebSocketStreamCreateTest, SubProtocolIsUsed) {
}
// Unsolicited sub-protocols are rejected.
-TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) {
- CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
- "/testing_path", NoSubProtocols(), GoogleOrigin(),
- GoogleUrl(), "", "",
- "Sec-WebSocket-Protocol: chatv20.chromium.org\r\n");
+TEST_P(WebSocketMultiProtocolStreamCreateTest, UnsolicitedSubProtocol) {
+ base::HistogramTester histogram_tester;
+
+ AddSSLData();
+ CreateAndConnectStandard(
+ "wss://www.example.org/testing_path", NoSubProtocols(), {}, {},
+ {{"Sec-WebSocket-Protocol", "chatv20.chromium.org"}});
WaitUntilConnectDone();
EXPECT_FALSE(stream_);
EXPECT_TRUE(has_failed());
@@ -487,16 +717,33 @@ TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) {
failure_message());
EXPECT_EQ(ERR_INVALID_RESPONSE,
url_request_context_host_.network_delegate().last_error());
+
+ stream_request_.reset();
+
+ auto samples = histogram_tester.GetHistogramSamplesSinceCreation(
+ "Net.WebSocket.HandshakeResult2");
+ EXPECT_EQ(1, samples->TotalCount());
+ if (stream_type_ == BASIC_HANDSHAKE_STREAM) {
+ EXPECT_EQ(
+ 1,
+ samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::FAILED_SUBPROTO)));
+ } else {
+ DCHECK_EQ(stream_type_, HTTP2_HANDSHAKE_STREAM);
+ EXPECT_EQ(1, samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::
+ HTTP2_FAILED_SUBPROTO)));
+ }
}
// Missing sub-protocol response is rejected.
-TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) {
+TEST_P(WebSocketMultiProtocolStreamCreateTest, UnacceptedSubProtocol) {
+ AddSSLData();
std::vector<std::string> sub_protocols;
sub_protocols.push_back("chat.example.com");
- CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
- "/testing_path", sub_protocols, LocalhostOrigin(),
- LocalhostUrl(), "",
- "Sec-WebSocket-Protocol: chat.example.com\r\n", "");
+ CreateAndConnectStandard("wss://www.example.org/testing_path", sub_protocols,
+ {}, {{"Sec-WebSocket-Protocol", "chat.example.com"}},
+ {});
WaitUntilConnectDone();
EXPECT_FALSE(stream_);
EXPECT_TRUE(has_failed());
@@ -507,37 +754,38 @@ TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) {
}
// Only one sub-protocol can be accepted.
-TEST_F(WebSocketStreamCreateTest, MultipleSubProtocolsInResponse) {
+TEST_P(WebSocketMultiProtocolStreamCreateTest, MultipleSubProtocolsInResponse) {
+ AddSSLData();
std::vector<std::string> sub_protocols;
sub_protocols.push_back("chatv11.chromium.org");
sub_protocols.push_back("chatv20.chromium.org");
- CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
- "/testing_path", sub_protocols, GoogleOrigin(),
- GoogleUrl(), "",
- "Sec-WebSocket-Protocol: chatv11.chromium.org, "
- "chatv20.chromium.org\r\n",
- "Sec-WebSocket-Protocol: chatv11.chromium.org, "
- "chatv20.chromium.org\r\n");
+ CreateAndConnectStandard("wss://www.example.org/testing_path", sub_protocols,
+ {},
+ {{"Sec-WebSocket-Protocol",
+ "chatv11.chromium.org, chatv20.chromium.org"}},
+ {{"Sec-WebSocket-Protocol",
+ "chatv11.chromium.org, chatv20.chromium.org"}});
WaitUntilConnectDone();
EXPECT_FALSE(stream_);
EXPECT_TRUE(has_failed());
- EXPECT_EQ("Error during WebSocket handshake: "
- "'Sec-WebSocket-Protocol' header must not appear "
- "more than once in a response",
- failure_message());
+ EXPECT_EQ(
+ "Error during WebSocket handshake: "
+ "'Sec-WebSocket-Protocol' header must not appear "
+ "more than once in a response",
+ failure_message());
}
// Unmatched sub-protocol should be rejected.
-TEST_F(WebSocketStreamCreateTest, UnmatchedSubProtocolInResponse) {
+TEST_P(WebSocketMultiProtocolStreamCreateTest, UnmatchedSubProtocolInResponse) {
+ AddSSLData();
std::vector<std::string> sub_protocols;
sub_protocols.push_back("chatv11.chromium.org");
sub_protocols.push_back("chatv20.chromium.org");
- CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
- "/testing_path", sub_protocols, GoogleOrigin(),
- GoogleUrl(), "",
- "Sec-WebSocket-Protocol: chatv11.chromium.org, "
- "chatv20.chromium.org\r\n",
- "Sec-WebSocket-Protocol: chatv21.chromium.org\r\n");
+ CreateAndConnectStandard(
+ "wss://www.example.org/testing_path", sub_protocols, {},
+ {{"Sec-WebSocket-Protocol",
+ "chatv11.chromium.org, chatv20.chromium.org"}},
+ {{"Sec-WebSocket-Protocol", "chatv21.chromium.org"}});
WaitUntilConnectDone();
EXPECT_FALSE(stream_);
EXPECT_TRUE(has_failed());
@@ -548,14 +796,14 @@ TEST_F(WebSocketStreamCreateTest, UnmatchedSubProtocolInResponse) {
}
// permessage-deflate extension basic success case.
-TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateSuccess) {
+TEST_P(WebSocketStreamCreateExtensionTest, PerMessageDeflateSuccess) {
CreateAndConnectWithExtensions("permessage-deflate");
EXPECT_TRUE(stream_);
EXPECT_FALSE(has_failed());
}
// permessage-deflate extensions success with all parameters.
-TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateParamsSuccess) {
+TEST_P(WebSocketStreamCreateExtensionTest, PerMessageDeflateParamsSuccess) {
CreateAndConnectWithExtensions(
"permessage-deflate; client_no_context_takeover; "
"server_max_window_bits=11; client_max_window_bits=13; "
@@ -566,29 +814,30 @@ TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateParamsSuccess) {
// Verify that incoming messages are actually decompressed with
// permessage-deflate enabled.
-TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) {
- CreateAndConnectCustomResponse(
- "ws://localhost/testing_path", "localhost", "/testing_path",
- NoSubProtocols(), LocalhostOrigin(), LocalhostUrl(), "", "",
- WebSocketStandardResponse(
- "Sec-WebSocket-Extensions: permessage-deflate\r\n") +
- std::string(
- "\xc1\x07" // WebSocket header (FIN + RSV1, Text payload 7 bytes)
- "\xf2\x48\xcd\xc9\xc9\x07\x00", // "Hello" DEFLATE compressed
- 9));
+TEST_P(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) {
+ AddSSLData();
+ SetAdditionalResponseData(std::string(
+ "\xc1\x07" // WebSocket header (FIN + RSV1, Text payload 7 bytes)
+ "\xf2\x48\xcd\xc9\xc9\x07\x00", // "Hello" DEFLATE compressed
+ 9));
+ CreateAndConnectStandard(
+ "wss://www.example.org/testing_path", NoSubProtocols(), {}, {},
+ {{"Sec-WebSocket-Extensions", "permessage-deflate"}});
WaitUntilConnectDone();
ASSERT_TRUE(stream_);
std::vector<std::unique_ptr<WebSocketFrame>> frames;
- CompletionCallback callback;
- ASSERT_THAT(stream_->ReadFrames(&frames, callback), IsOk());
+ TestCompletionCallback callback;
+ int rv = stream_->ReadFrames(&frames, callback.callback());
+ rv = callback.GetResult(rv);
+ ASSERT_THAT(rv, IsOk());
ASSERT_EQ(1U, frames.size());
ASSERT_EQ(5U, frames[0]->header.payload_length);
EXPECT_EQ("Hello", std::string(frames[0]->data->data(), 5));
}
// Unknown extension in the response is rejected
-TEST_F(WebSocketStreamCreateExtensionTest, UnknownExtension) {
+TEST_P(WebSocketStreamCreateExtensionTest, UnknownExtension) {
CreateAndConnectWithExtensions("x-unknown-extension");
EXPECT_FALSE(stream_);
EXPECT_TRUE(has_failed());
@@ -600,7 +849,7 @@ TEST_F(WebSocketStreamCreateExtensionTest, UnknownExtension) {
// Malformed extensions are rejected (this file does not cover all possible
// parse failures, as the parser is covered thoroughly by its own unit tests).
-TEST_F(WebSocketStreamCreateExtensionTest, MalformedExtension) {
+TEST_P(WebSocketStreamCreateExtensionTest, MalformedExtension) {
CreateAndConnectWithExtensions(";");
EXPECT_FALSE(stream_);
EXPECT_TRUE(has_failed());
@@ -611,7 +860,9 @@ TEST_F(WebSocketStreamCreateExtensionTest, MalformedExtension) {
}
// The permessage-deflate extension may only be specified once.
-TEST_F(WebSocketStreamCreateExtensionTest, OnlyOnePerMessageDeflateAllowed) {
+TEST_P(WebSocketStreamCreateExtensionTest, OnlyOnePerMessageDeflateAllowed) {
+ base::HistogramTester histogram_tester;
+
CreateAndConnectWithExtensions(
"permessage-deflate, permessage-deflate; client_max_window_bits=10");
EXPECT_FALSE(stream_);
@@ -620,10 +871,27 @@ TEST_F(WebSocketStreamCreateExtensionTest, OnlyOnePerMessageDeflateAllowed) {
"Error during WebSocket handshake: "
"Received duplicate permessage-deflate response",
failure_message());
+
+ stream_request_.reset();
+
+ auto samples = histogram_tester.GetHistogramSamplesSinceCreation(
+ "Net.WebSocket.HandshakeResult2");
+ EXPECT_EQ(1, samples->TotalCount());
+ if (stream_type_ == BASIC_HANDSHAKE_STREAM) {
+ EXPECT_EQ(
+ 1,
+ samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::FAILED_EXTENSIONS)));
+ } else {
+ DCHECK_EQ(stream_type_, HTTP2_HANDSHAKE_STREAM);
+ EXPECT_EQ(1, samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::
+ HTTP2_FAILED_EXTENSIONS)));
+ }
}
// client_max_window_bits must have an argument
-TEST_F(WebSocketStreamCreateExtensionTest, NoMaxWindowBitsArgument) {
+TEST_P(WebSocketStreamCreateExtensionTest, NoMaxWindowBitsArgument) {
CreateAndConnectWithExtensions("permessage-deflate; client_max_window_bits");
EXPECT_FALSE(stream_);
EXPECT_TRUE(has_failed());
@@ -641,11 +909,10 @@ TEST_F(WebSocketStreamCreateExtensionTest, NoMaxWindowBitsArgument) {
// socket is randomly masked.
// Additional Sec-WebSocket-Accept headers should be rejected.
-TEST_F(WebSocketStreamCreateTest, DoubleAccept) {
+TEST_P(WebSocketStreamCreateTest, DoubleAccept) {
CreateAndConnectStandard(
- "ws://localhost/", "localhost", "/", NoSubProtocols(), LocalhostOrigin(),
- LocalhostUrl(), "", "",
- "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n");
+ "ws://www.example.org/", NoSubProtocols(), {}, {},
+ {{"Sec-WebSocket-Accept", "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="}});
WaitUntilConnectDone();
EXPECT_FALSE(stream_);
EXPECT_TRUE(has_failed());
@@ -655,38 +922,76 @@ TEST_F(WebSocketStreamCreateTest, DoubleAccept) {
failure_message());
}
-// Response code 200 must be rejected.
-TEST_F(WebSocketStreamCreateTest, InvalidStatusCode) {
- static const char kInvalidStatusCodeResponse[] =
- "HTTP/1.1 200 OK\r\n"
- "Upgrade: websocket\r\n"
- "Connection: Upgrade\r\n"
- "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
- "\r\n";
- CreateAndConnectCustomResponse(
- "ws://localhost/", "localhost", "/", NoSubProtocols(), LocalhostOrigin(),
- LocalhostUrl(), "", "", kInvalidStatusCodeResponse);
+// When upgrading an HTTP/1 connection, response code 200 is invalid and must be
+// rejected. Response code 101 means success. On the other hand, when
+// requesting a WebSocket stream over HTTP/2, response code 101 is invalid and
+// must be rejected. Response code 200 means success.
+TEST_P(WebSocketMultiProtocolStreamCreateTest, InvalidStatusCode) {
+ base::HistogramTester histogram_tester;
+
+ AddSSLData();
+ if (stream_type_ == BASIC_HANDSHAKE_STREAM) {
+ static const char kInvalidStatusCodeResponse[] =
+ "HTTP/1.1 200 OK\r\n"
+ "Upgrade: websocket\r\n"
+ "Connection: Upgrade\r\n"
+ "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
+ "\r\n";
+ CreateAndConnectCustomResponse("wss://www.example.org/", NoSubProtocols(),
+ {}, {}, kInvalidStatusCodeResponse);
+ } else {
+ DCHECK_EQ(stream_type_, HTTP2_HANDSHAKE_STREAM);
+ SetHttp2ResponseStatus("101");
+ CreateAndConnectStandard("wss://www.example.org/", NoSubProtocols(), {}, {},
+ {});
+ }
+
WaitUntilConnectDone();
+ stream_request_.reset();
EXPECT_TRUE(has_failed());
- EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200",
- failure_message());
+ auto samples = histogram_tester.GetHistogramSamplesSinceCreation(
+ "Net.WebSocket.HandshakeResult2");
+ EXPECT_EQ(1, samples->TotalCount());
+
+ if (stream_type_ == BASIC_HANDSHAKE_STREAM) {
+ EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 200",
+ failure_message());
+ EXPECT_EQ(
+ 1, samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::INVALID_STATUS)));
+ } else {
+ DCHECK_EQ(stream_type_, HTTP2_HANDSHAKE_STREAM);
+ EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 101",
+ failure_message());
+ EXPECT_EQ(1, samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::
+ HTTP2_INVALID_STATUS)));
+ }
}
// Redirects are not followed (according to the WHATWG WebSocket API, which
// overrides RFC6455 for browser applications).
-TEST_F(WebSocketStreamCreateTest, RedirectsRejected) {
- static const char kRedirectResponse[] =
- "HTTP/1.1 302 Moved Temporarily\r\n"
- "Content-Type: text/html\r\n"
- "Content-Length: 34\r\n"
- "Connection: keep-alive\r\n"
- "Location: ws://localhost/other\r\n"
- "\r\n"
- "<title>Moved</title><h1>Moved</h1>";
- CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
- NoSubProtocols(), LocalhostOrigin(),
- LocalhostUrl(), "", "", kRedirectResponse);
+TEST_P(WebSocketMultiProtocolStreamCreateTest, RedirectsRejected) {
+ AddSSLData();
+ if (stream_type_ == BASIC_HANDSHAKE_STREAM) {
+ static const char kRedirectResponse[] =
+ "HTTP/1.1 302 Moved Temporarily\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 34\r\n"
+ "Connection: keep-alive\r\n"
+ "Location: wss://www.example.org/other\r\n"
+ "\r\n"
+ "<title>Moved</title><h1>Moved</h1>";
+ CreateAndConnectCustomResponse("wss://www.example.org/", NoSubProtocols(),
+ {}, {}, kRedirectResponse);
+ } else {
+ DCHECK_EQ(stream_type_, HTTP2_HANDSHAKE_STREAM);
+ SetHttp2ResponseStatus("302");
+ CreateAndConnectStandard("wss://www.example.org/", NoSubProtocols(), {}, {},
+ {});
+ }
WaitUntilConnectDone();
+
EXPECT_TRUE(has_failed());
EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 302",
failure_message());
@@ -696,7 +1001,7 @@ TEST_F(WebSocketStreamCreateTest, RedirectsRejected) {
// about any garbage in the middle of the headers. To make it give up, the junk
// has to be at the start of the response. Even then, it just gets treated as an
// HTTP/0.9 response.
-TEST_F(WebSocketStreamCreateTest, MalformedResponse) {
+TEST_P(WebSocketStreamCreateTest, MalformedResponse) {
static const char kMalformedResponse[] =
"220 mx.google.com ESMTP\r\n"
"HTTP/1.1 101 OK\r\n"
@@ -704,9 +1009,8 @@ TEST_F(WebSocketStreamCreateTest, MalformedResponse) {
"Connection: Upgrade\r\n"
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
"\r\n";
- CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
- NoSubProtocols(), LocalhostOrigin(),
- LocalhostUrl(), "", "", kMalformedResponse);
+ CreateAndConnectCustomResponse("ws://www.example.org/", NoSubProtocols(), {},
+ {}, kMalformedResponse);
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
EXPECT_EQ("Error during WebSocket handshake: Invalid status line",
@@ -714,26 +1018,35 @@ TEST_F(WebSocketStreamCreateTest, MalformedResponse) {
}
// Upgrade header must be present.
-TEST_F(WebSocketStreamCreateTest, MissingUpgradeHeader) {
+TEST_P(WebSocketStreamCreateTest, MissingUpgradeHeader) {
+ base::HistogramTester histogram_tester;
+
static const char kMissingUpgradeResponse[] =
"HTTP/1.1 101 Switching Protocols\r\n"
"Connection: Upgrade\r\n"
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
"\r\n";
- CreateAndConnectCustomResponse(
- "ws://localhost/", "localhost", "/", NoSubProtocols(), LocalhostOrigin(),
- LocalhostUrl(), "", "", kMissingUpgradeResponse);
+ CreateAndConnectCustomResponse("ws://www.example.org/", NoSubProtocols(), {},
+ {}, kMissingUpgradeResponse);
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
EXPECT_EQ("Error during WebSocket handshake: 'Upgrade' header is missing",
failure_message());
+
+ stream_request_.reset();
+
+ auto samples = histogram_tester.GetHistogramSamplesSinceCreation(
+ "Net.WebSocket.HandshakeResult2");
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(
+ 1, samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::FAILED_UPGRADE)));
}
// There must only be one upgrade header.
-TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) {
- CreateAndConnectStandard("ws://localhost/", "localhost", "/",
- NoSubProtocols(), LocalhostOrigin(), LocalhostUrl(),
- "", "", "Upgrade: HTTP/2.0\r\n");
+TEST_P(WebSocketStreamCreateTest, DoubleUpgradeHeader) {
+ CreateAndConnectStandard("ws://www.example.org/", NoSubProtocols(), {}, {},
+ {{"Upgrade", "HTTP/2.0"}});
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
EXPECT_EQ("Error during WebSocket handshake: "
@@ -742,16 +1055,15 @@ TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) {
}
// There must only be one correct upgrade header.
-TEST_F(WebSocketStreamCreateTest, IncorrectUpgradeHeader) {
+TEST_P(WebSocketStreamCreateTest, IncorrectUpgradeHeader) {
static const char kMissingUpgradeResponse[] =
"HTTP/1.1 101 Switching Protocols\r\n"
"Connection: Upgrade\r\n"
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
"Upgrade: hogefuga\r\n"
"\r\n";
- CreateAndConnectCustomResponse(
- "ws://localhost/", "localhost", "/", NoSubProtocols(), LocalhostOrigin(),
- LocalhostUrl(), "", "", kMissingUpgradeResponse);
+ CreateAndConnectCustomResponse("ws://www.example.org/", NoSubProtocols(), {},
+ {}, kMissingUpgradeResponse);
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
EXPECT_EQ("Error during WebSocket handshake: "
@@ -760,33 +1072,43 @@ TEST_F(WebSocketStreamCreateTest, IncorrectUpgradeHeader) {
}
// Connection header must be present.
-TEST_F(WebSocketStreamCreateTest, MissingConnectionHeader) {
+TEST_P(WebSocketStreamCreateTest, MissingConnectionHeader) {
+ base::HistogramTester histogram_tester;
+
static const char kMissingConnectionResponse[] =
"HTTP/1.1 101 Switching Protocols\r\n"
"Upgrade: websocket\r\n"
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
"\r\n";
- CreateAndConnectCustomResponse(
- "ws://localhost/", "localhost", "/", NoSubProtocols(), LocalhostOrigin(),
- LocalhostUrl(), "", "", kMissingConnectionResponse);
+ CreateAndConnectCustomResponse("ws://www.example.org/", NoSubProtocols(), {},
+ {}, kMissingConnectionResponse);
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
EXPECT_EQ("Error during WebSocket handshake: "
"'Connection' header is missing",
failure_message());
+
+ stream_request_.reset();
+
+ auto samples = histogram_tester.GetHistogramSamplesSinceCreation(
+ "Net.WebSocket.HandshakeResult2");
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(
+ 1,
+ samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::FAILED_CONNECTION)));
}
// Connection header must contain "Upgrade".
-TEST_F(WebSocketStreamCreateTest, IncorrectConnectionHeader) {
+TEST_P(WebSocketStreamCreateTest, IncorrectConnectionHeader) {
static const char kMissingConnectionResponse[] =
"HTTP/1.1 101 Switching Protocols\r\n"
"Upgrade: websocket\r\n"
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
"Connection: hogefuga\r\n"
"\r\n";
- CreateAndConnectCustomResponse(
- "ws://localhost/", "localhost", "/", NoSubProtocols(), LocalhostOrigin(),
- LocalhostUrl(), "", "", kMissingConnectionResponse);
+ CreateAndConnectCustomResponse("ws://www.example.org/", NoSubProtocols(), {},
+ {}, kMissingConnectionResponse);
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
EXPECT_EQ("Error during WebSocket handshake: "
@@ -795,49 +1117,57 @@ TEST_F(WebSocketStreamCreateTest, IncorrectConnectionHeader) {
}
// Connection header is permitted to contain other tokens.
-TEST_F(WebSocketStreamCreateTest, AdditionalTokenInConnectionHeader) {
+TEST_P(WebSocketStreamCreateTest, AdditionalTokenInConnectionHeader) {
static const char kAdditionalConnectionTokenResponse[] =
"HTTP/1.1 101 Switching Protocols\r\n"
"Upgrade: websocket\r\n"
"Connection: Upgrade, Keep-Alive\r\n"
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
"\r\n";
- CreateAndConnectCustomResponse(
- "ws://localhost/", "localhost", "/", NoSubProtocols(), LocalhostOrigin(),
- LocalhostUrl(), "", "", kAdditionalConnectionTokenResponse);
+ CreateAndConnectCustomResponse("ws://www.example.org/", NoSubProtocols(), {},
+ {}, kAdditionalConnectionTokenResponse);
WaitUntilConnectDone();
EXPECT_FALSE(has_failed());
EXPECT_TRUE(stream_);
}
// Sec-WebSocket-Accept header must be present.
-TEST_F(WebSocketStreamCreateTest, MissingSecWebSocketAccept) {
+TEST_P(WebSocketStreamCreateTest, MissingSecWebSocketAccept) {
+ base::HistogramTester histogram_tester;
+
static const char kMissingAcceptResponse[] =
"HTTP/1.1 101 Switching Protocols\r\n"
"Upgrade: websocket\r\n"
"Connection: Upgrade\r\n"
"\r\n";
- CreateAndConnectCustomResponse(
- "ws://localhost/", "localhost", "/", NoSubProtocols(), LocalhostOrigin(),
- LocalhostUrl(), "", "", kMissingAcceptResponse);
+ CreateAndConnectCustomResponse("ws://www.example.org/", NoSubProtocols(), {},
+ {}, kMissingAcceptResponse);
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
EXPECT_EQ("Error during WebSocket handshake: "
"'Sec-WebSocket-Accept' header is missing",
failure_message());
+
+ stream_request_.reset();
+
+ auto samples = histogram_tester.GetHistogramSamplesSinceCreation(
+ "Net.WebSocket.HandshakeResult2");
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(1,
+ samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::FAILED_ACCEPT)));
}
// Sec-WebSocket-Accept header must match the key that was sent.
-TEST_F(WebSocketStreamCreateTest, WrongSecWebSocketAccept) {
+TEST_P(WebSocketStreamCreateTest, WrongSecWebSocketAccept) {
static const char kIncorrectAcceptResponse[] =
"HTTP/1.1 101 Switching Protocols\r\n"
"Upgrade: websocket\r\n"
"Connection: Upgrade\r\n"
"Sec-WebSocket-Accept: x/byyPZ2tOFvJCGkkugcKvqhhPk=\r\n"
"\r\n";
- CreateAndConnectCustomResponse(
- "ws://localhost/", "localhost", "/", NoSubProtocols(), LocalhostOrigin(),
- LocalhostUrl(), "", "", kIncorrectAcceptResponse);
+ CreateAndConnectCustomResponse("ws://www.example.org/", NoSubProtocols(), {},
+ {}, kIncorrectAcceptResponse);
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
EXPECT_EQ("Error during WebSocket handshake: "
@@ -846,10 +1176,9 @@ TEST_F(WebSocketStreamCreateTest, WrongSecWebSocketAccept) {
}
// Cancellation works.
-TEST_F(WebSocketStreamCreateTest, Cancellation) {
- CreateAndConnectStandard("ws://localhost/", "localhost", "/",
- NoSubProtocols(), LocalhostOrigin(), LocalhostUrl(),
- "", "", "");
+TEST_P(WebSocketStreamCreateTest, Cancellation) {
+ CreateAndConnectStandard("ws://www.example.org/", NoSubProtocols(), {}, {},
+ {});
stream_request_.reset();
// WaitUntilConnectDone doesn't work in this case.
base::RunLoop().RunUntilIdle();
@@ -860,12 +1189,11 @@ TEST_F(WebSocketStreamCreateTest, Cancellation) {
}
// Connect failure must look just like negotiation failure.
-TEST_F(WebSocketStreamCreateTest, ConnectionFailure) {
+TEST_P(WebSocketStreamCreateTest, ConnectionFailure) {
std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData());
socket_data->set_connect_data(
MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
- CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), LocalhostUrl(), "",
+ CreateAndConnectRawExpectations("ws://www.example.org/", NoSubProtocols(), "",
std::move(socket_data));
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
@@ -876,12 +1204,11 @@ TEST_F(WebSocketStreamCreateTest, ConnectionFailure) {
}
// Connect timeout must look just like any other failure.
-TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) {
+TEST_P(WebSocketStreamCreateTest, ConnectionTimeout) {
std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData());
socket_data->set_connect_data(
MockConnect(ASYNC, ERR_CONNECTION_TIMED_OUT));
- CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), LocalhostUrl(), "",
+ CreateAndConnectRawExpectations("ws://www.example.org/", NoSubProtocols(), "",
std::move(socket_data));
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
@@ -890,14 +1217,14 @@ TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) {
}
// The server doesn't respond to the opening handshake.
-TEST_F(WebSocketStreamCreateTest, HandshakeTimeout) {
+TEST_P(WebSocketStreamCreateTest, HandshakeTimeout) {
std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData());
socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
- std::unique_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false));
+ auto timer = std::make_unique<MockWeakTimer>(false, false);
base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr();
- CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), LocalhostUrl(), "",
- std::move(socket_data), std::move(timer));
+ SetTimer(std::move(timer));
+ CreateAndConnectRawExpectations("ws://www.example.org/", NoSubProtocols(), "",
+ std::move(socket_data));
EXPECT_FALSE(has_failed());
ASSERT_TRUE(weak_timer.get());
EXPECT_TRUE(weak_timer->IsRunning());
@@ -912,13 +1239,13 @@ TEST_F(WebSocketStreamCreateTest, HandshakeTimeout) {
}
// When the connection establishes the timer should be stopped.
-TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnSuccess) {
- std::unique_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false));
+TEST_P(WebSocketStreamCreateTest, HandshakeTimerOnSuccess) {
+ auto timer = std::make_unique<MockWeakTimer>(false, false);
base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr();
- CreateAndConnectStandard("ws://localhost/", "localhost", "/",
- NoSubProtocols(), LocalhostOrigin(), LocalhostUrl(),
- "", "", "", std::move(timer));
+ SetTimer(std::move(timer));
+ CreateAndConnectStandard("ws://www.example.org/", NoSubProtocols(), {}, {},
+ {});
ASSERT_TRUE(weak_timer);
EXPECT_TRUE(weak_timer->IsRunning());
@@ -930,15 +1257,15 @@ TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnSuccess) {
}
// When the connection fails the timer should be stopped.
-TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnFailure) {
+TEST_P(WebSocketStreamCreateTest, HandshakeTimerOnFailure) {
std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData());
socket_data->set_connect_data(
MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED));
- std::unique_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false));
+ auto timer = std::make_unique<MockWeakTimer>(false, false);
base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr();
- CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), LocalhostUrl(), "",
- std::move(socket_data), std::move(timer));
+ SetTimer(std::move(timer));
+ CreateAndConnectRawExpectations("ws://www.example.org/", NoSubProtocols(), "",
+ std::move(socket_data));
ASSERT_TRUE(weak_timer.get());
EXPECT_TRUE(weak_timer->IsRunning());
@@ -951,11 +1278,10 @@ TEST_F(WebSocketStreamCreateTest, HandshakeTimerOnFailure) {
}
// Cancellation during connect works.
-TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) {
+TEST_P(WebSocketStreamCreateTest, CancellationDuringConnect) {
std::unique_ptr<SequencedSocketData> socket_data(BuildNullSocketData());
socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
- CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), LocalhostUrl(), "",
+ CreateAndConnectRawExpectations("ws://www.example.org/", NoSubProtocols(), "",
std::move(socket_data));
stream_request_.reset();
// WaitUntilConnectDone doesn't work in this case.
@@ -965,14 +1291,13 @@ TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) {
}
// Cancellation during write of the request headers works.
-TEST_F(WebSocketStreamCreateTest, CancellationDuringWrite) {
+TEST_P(WebSocketStreamCreateTest, CancellationDuringWrite) {
// First write never completes.
MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 0)};
SequencedSocketData* socket_data(
new SequencedSocketData(NULL, 0, writes, arraysize(writes)));
socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
- CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), LocalhostUrl(), "",
+ CreateAndConnectRawExpectations("ws://www.example.org/", NoSubProtocols(), "",
base::WrapUnique(socket_data));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(socket_data->AllWriteDataConsumed());
@@ -986,9 +1311,9 @@ TEST_F(WebSocketStreamCreateTest, CancellationDuringWrite) {
}
// Cancellation during read of the response headers works.
-TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) {
+TEST_P(WebSocketStreamCreateTest, CancellationDuringRead) {
std::string request =
- WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), "", "");
+ WebSocketStandardRequest("/", "www.example.org", Origin(), "", "");
MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())};
MockRead reads[] = {
MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1),
@@ -996,8 +1321,7 @@ TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) {
std::unique_ptr<SequencedSocketData> socket_data(
BuildSocketData(reads, writes));
SequencedSocketData* socket_data_raw_ptr = socket_data.get();
- CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), LocalhostUrl(), "",
+ CreateAndConnectRawExpectations("ws://www.example.org/", NoSubProtocols(), "",
std::move(socket_data));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(socket_data_raw_ptr->AllReadDataConsumed());
@@ -1013,34 +1337,44 @@ TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) {
// Over-size response headers (> 256KB) should not cause a crash. This is a
// regression test for crbug.com/339456. It is based on the layout test
// "cookie-flood.html".
-TEST_F(WebSocketStreamCreateTest, VeryLargeResponseHeaders) {
+TEST_P(WebSocketStreamCreateTest, VeryLargeResponseHeaders) {
+ base::HistogramTester histogram_tester;
+
std::string set_cookie_headers;
set_cookie_headers.reserve(24 * 20000);
for (int i = 0; i < 20000; ++i) {
set_cookie_headers += base::StringPrintf("Set-Cookie: ws-%d=1\r\n", i);
}
ASSERT_GT(set_cookie_headers.size(), 256U * 1024U);
- CreateAndConnectStandard("ws://localhost/", "localhost", "/",
- NoSubProtocols(), LocalhostOrigin(), LocalhostUrl(),
- "", "", set_cookie_headers);
+ CreateAndConnectStringResponse("ws://www.example.org/", NoSubProtocols(),
+ set_cookie_headers);
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
EXPECT_FALSE(response_info_);
+
+ stream_request_.reset();
+
+ auto samples = histogram_tester.GetHistogramSamplesSinceCreation(
+ "Net.WebSocket.HandshakeResult2");
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::FAILED)));
}
// If the remote host closes the connection without sending headers, we should
// log the console message "Connection closed before receiving a handshake
// response".
-TEST_F(WebSocketStreamCreateTest, NoResponse) {
+TEST_P(WebSocketStreamCreateTest, NoResponse) {
+ base::HistogramTester histogram_tester;
+
std::string request =
- WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), "", "");
+ WebSocketStandardRequest("/", "www.example.org", Origin(), "", "");
MockWrite writes[] = {MockWrite(ASYNC, request.data(), request.size(), 0)};
MockRead reads[] = {MockRead(ASYNC, 0, 1)};
std::unique_ptr<SequencedSocketData> socket_data(
BuildSocketData(reads, writes));
SequencedSocketData* socket_data_raw_ptr = socket_data.get();
- CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), LocalhostUrl(), "",
+ CreateAndConnectRawExpectations("ws://www.example.org/", NoSubProtocols(), "",
std::move(socket_data));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(socket_data_raw_ptr->AllReadDataConsumed());
@@ -1049,18 +1383,28 @@ TEST_F(WebSocketStreamCreateTest, NoResponse) {
EXPECT_FALSE(response_info_);
EXPECT_EQ("Connection closed before receiving a handshake response",
failure_message());
+
+ stream_request_.reset();
+
+ auto samples = histogram_tester.GetHistogramSamplesSinceCreation(
+ "Net.WebSocket.HandshakeResult2");
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(
+ 1, samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::EMPTY_RESPONSE)));
}
-TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateFailure) {
- ssl_data_.push_back(std::make_unique<SSLSocketDataProvider>(
- ASYNC, ERR_CERT_AUTHORITY_INVALID));
- ssl_data_[0]->ssl_info.cert =
+TEST_P(WebSocketStreamCreateTest, SelfSignedCertificateFailure) {
+ auto ssl_socket_data = std::make_unique<SSLSocketDataProvider>(
+ ASYNC, ERR_CERT_AUTHORITY_INVALID);
+ ssl_socket_data->ssl_info.cert =
ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der");
- ASSERT_TRUE(ssl_data_[0]->ssl_info.cert.get());
+ ASSERT_TRUE(ssl_socket_data->ssl_info.cert.get());
+ url_request_context_host_.AddSSLSocketDataProvider(
+ std::move(ssl_socket_data));
std::unique_ptr<SequencedSocketData> raw_socket_data(BuildNullSocketData());
- CreateAndConnectRawExpectations("wss://localhost/", NoSubProtocols(),
- LocalhostOrigin(), LocalhostUrl(), "",
- std::move(raw_socket_data));
+ CreateAndConnectRawExpectations("wss://www.example.org/", NoSubProtocols(),
+ "", std::move(raw_socket_data));
// WaitUntilConnectDone doesn't work in this case.
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(has_failed());
@@ -1071,19 +1415,19 @@ TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateFailure) {
EXPECT_TRUE(has_failed());
}
-TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) {
- std::unique_ptr<SSLSocketDataProvider> ssl_data(
- new SSLSocketDataProvider(ASYNC, ERR_CERT_AUTHORITY_INVALID));
- ssl_data->ssl_info.cert =
+TEST_P(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) {
+ auto ssl_socket_data = std::make_unique<SSLSocketDataProvider>(
+ ASYNC, ERR_CERT_AUTHORITY_INVALID);
+ ssl_socket_data->ssl_info.cert =
ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der");
- ASSERT_TRUE(ssl_data->ssl_info.cert.get());
- ssl_data_.push_back(std::move(ssl_data));
- ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK));
- ssl_data_.push_back(std::move(ssl_data));
+ ASSERT_TRUE(ssl_socket_data->ssl_info.cert.get());
+ url_request_context_host_.AddSSLSocketDataProvider(
+ std::move(ssl_socket_data));
+ url_request_context_host_.AddSSLSocketDataProvider(
+ std::make_unique<SSLSocketDataProvider>(ASYNC, OK));
url_request_context_host_.AddRawExpectations(BuildNullSocketData());
- CreateAndConnectStandard("wss://localhost/", "localhost", "/",
- NoSubProtocols(), LocalhostOrigin(), LocalhostUrl(),
- "", "", "");
+ CreateAndConnectStandard("wss://www.example.org/", NoSubProtocols(), {}, {},
+ {});
// WaitUntilConnectDone doesn't work in this case.
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(ssl_error_callbacks_);
@@ -1095,10 +1439,9 @@ TEST_F(WebSocketStreamCreateTest, SelfSignedCertificateSuccess) {
// If the server requests authorisation, but we have no credentials, the
// connection should fail cleanly.
-TEST_F(WebSocketStreamCreateBasicAuthTest, FailureNoCredentials) {
- CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
- NoSubProtocols(), LocalhostOrigin(),
- LocalhostUrl(), "", "", kUnauthorizedResponse);
+TEST_P(WebSocketStreamCreateBasicAuthTest, FailureNoCredentials) {
+ CreateAndConnectCustomResponse("ws://www.example.org/", NoSubProtocols(), {},
+ {}, kUnauthorizedResponse);
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
EXPECT_EQ("HTTP Authentication failed; no valid credentials available",
@@ -1106,9 +1449,8 @@ TEST_F(WebSocketStreamCreateBasicAuthTest, FailureNoCredentials) {
EXPECT_TRUE(response_info_);
}
-TEST_F(WebSocketStreamCreateBasicAuthTest, SuccessPasswordInUrl) {
- CreateAndConnectAuthHandshake("ws://foo:bar@localhost/",
- "Zm9vOmJhcg==",
+TEST_P(WebSocketStreamCreateBasicAuthTest, SuccessPasswordInUrl) {
+ CreateAndConnectAuthHandshake("ws://foo:bar@www.example.org/", "Zm9vOmJhcg==",
WebSocketStandardResponse(std::string()));
WaitUntilConnectDone();
EXPECT_FALSE(has_failed());
@@ -1117,9 +1459,9 @@ TEST_F(WebSocketStreamCreateBasicAuthTest, SuccessPasswordInUrl) {
EXPECT_EQ(101, response_info_->status_code);
}
-TEST_F(WebSocketStreamCreateBasicAuthTest, FailureIncorrectPasswordInUrl) {
- CreateAndConnectAuthHandshake(
- "ws://foo:baz@localhost/", "Zm9vOmJheg==", kUnauthorizedResponse);
+TEST_P(WebSocketStreamCreateBasicAuthTest, FailureIncorrectPasswordInUrl) {
+ CreateAndConnectAuthHandshake("ws://foo:baz@www.example.org/",
+ "Zm9vOmJheg==", kUnauthorizedResponse);
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
EXPECT_TRUE(response_info_);
@@ -1128,12 +1470,12 @@ TEST_F(WebSocketStreamCreateBasicAuthTest, FailureIncorrectPasswordInUrl) {
// Digest auth has the same connection semantics as Basic auth, so we can
// generally assume that whatever works for Basic auth will also work for
// Digest. There's just one test here, to confirm that it works at all.
-TEST_F(WebSocketStreamCreateDigestAuthTest, DigestPasswordInUrl) {
- AddRawExpectations(helper_.BuildSocketData1(kUnauthorizedResponse));
+TEST_P(WebSocketStreamCreateDigestAuthTest, DigestPasswordInUrl) {
+ url_request_context_host_.AddRawExpectations(
+ helper_.BuildSocketData1(kUnauthorizedResponse));
CreateAndConnectRawExpectations(
- "ws://FooBar:pass@localhost/", NoSubProtocols(), LocalhostOrigin(),
- LocalhostUrl(), "",
+ "ws://FooBar:pass@www.example.org/", NoSubProtocols(), "",
helper_.BuildSocketData2(kAuthorizedRequest,
WebSocketStandardResponse(std::string())));
WaitUntilConnectDone();
@@ -1143,78 +1485,75 @@ TEST_F(WebSocketStreamCreateDigestAuthTest, DigestPasswordInUrl) {
EXPECT_EQ(101, response_info_->status_code);
}
-TEST_F(WebSocketStreamCreateUMATest, Incomplete) {
- const std::string name("Net.WebSocket.HandshakeResult");
- std::unique_ptr<base::HistogramSamples> original(GetSamples(name));
+TEST_P(WebSocketMultiProtocolStreamCreateTest, Incomplete) {
+ base::HistogramTester histogram_tester;
+
+ AddSSLData();
+ if (stream_type_ == BASIC_HANDSHAKE_STREAM) {
+ std::string request =
+ WebSocketStandardRequest("/", "www.example.org", Origin(), "", "");
+ MockRead reads[] = {MockRead(ASYNC, ERR_IO_PENDING, 0)};
+ MockWrite writes[] = {MockWrite(ASYNC, 1, request.c_str())};
+ CreateAndConnectRawExpectations("wss://www.example.org/", NoSubProtocols(),
+ "", BuildSocketData(reads, writes));
+ base::RunLoop().RunUntilIdle();
+ stream_request_.reset();
- {
- StreamCreation creation;
- creation.CreateAndConnectStandard(
- "ws://localhost/", "localhost", "/", creation.NoSubProtocols(),
- LocalhostOrigin(), LocalhostUrl(), "", "", "");
- }
+ auto samples = histogram_tester.GetHistogramSamplesSinceCreation(
+ "Net.WebSocket.HandshakeResult2");
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(1,
+ samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::INCOMPLETE)));
+ } else {
+ DCHECK_EQ(stream_type_, HTTP2_HANDSHAKE_STREAM);
+ CreateAndConnectStandard("wss://www.example.org/", NoSubProtocols(), {}, {},
+ {});
+ stream_request_.reset();
- std::unique_ptr<base::HistogramSamples> samples(GetSamples(name));
- ASSERT_TRUE(samples);
- if (original) {
- samples->Subtract(*original); // Cancel the original values.
+ auto samples = histogram_tester.GetHistogramSamplesSinceCreation(
+ "Net.WebSocket.HandshakeResult2");
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(
+ 1,
+ samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::HTTP2_INCOMPLETE)));
}
- EXPECT_EQ(1, samples->GetCount(INCOMPLETE));
- EXPECT_EQ(0, samples->GetCount(CONNECTED));
- EXPECT_EQ(0, samples->GetCount(FAILED));
}
-TEST_F(WebSocketStreamCreateUMATest, Connected) {
- const std::string name("Net.WebSocket.HandshakeResult");
- std::unique_ptr<base::HistogramSamples> original(GetSamples(name));
+TEST_P(WebSocketMultiProtocolStreamCreateTest, Http2StreamReset) {
+ AddSSLData();
- {
- StreamCreation creation;
- creation.CreateAndConnectStandard(
- "ws://localhost/", "localhost", "/", creation.NoSubProtocols(),
- LocalhostOrigin(), LocalhostUrl(), "", "", "");
- creation.WaitUntilConnectDone();
- }
+ if (stream_type_ == BASIC_HANDSHAKE_STREAM) {
+ // This is a dummy transaction to avoid crash in ~TestURLRequestContext().
+ CreateAndConnectStandard("wss://www.example.org/", NoSubProtocols(), {}, {},
+ {});
+ } else {
+ DCHECK_EQ(stream_type_, HTTP2_HANDSHAKE_STREAM);
+ base::HistogramTester histogram_tester;
- std::unique_ptr<base::HistogramSamples> samples(GetSamples(name));
- ASSERT_TRUE(samples);
- if (original) {
- samples->Subtract(*original); // Cancel the original values.
- }
- EXPECT_EQ(0, samples->GetCount(INCOMPLETE));
- EXPECT_EQ(1, samples->GetCount(CONNECTED));
- EXPECT_EQ(0, samples->GetCount(FAILED));
-}
+ SetResetWebSocketHttp2Stream(true);
+ CreateAndConnectStandard("wss://www.example.org/", NoSubProtocols(), {}, {},
+ {});
+ base::RunLoop().RunUntilIdle();
+ stream_request_.reset();
-TEST_F(WebSocketStreamCreateUMATest, Failed) {
- const std::string name("Net.WebSocket.HandshakeResult");
- std::unique_ptr<base::HistogramSamples> original(GetSamples(name));
+ EXPECT_TRUE(has_failed());
+ EXPECT_EQ("Stream closed with error: net::ERR_SPDY_PROTOCOL_ERROR",
+ failure_message());
- {
- StreamCreation creation;
- static const char kInvalidStatusCodeResponse[] =
- "HTTP/1.1 200 OK\r\n"
- "Upgrade: websocket\r\n"
- "Connection: Upgrade\r\n"
- "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
- "\r\n";
- creation.CreateAndConnectCustomResponse(
- "ws://localhost/", "localhost", "/", creation.NoSubProtocols(),
- LocalhostOrigin(), LocalhostUrl(), "", "", kInvalidStatusCodeResponse);
- creation.WaitUntilConnectDone();
- }
-
- std::unique_ptr<base::HistogramSamples> samples(GetSamples(name));
- ASSERT_TRUE(samples);
- if (original) {
- samples->Subtract(*original); // Cancel the original values.
+ auto samples = histogram_tester.GetHistogramSamplesSinceCreation(
+ "Net.WebSocket.HandshakeResult2");
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(
+ 1, samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::HTTP2_FAILED)));
}
- EXPECT_EQ(1, samples->GetCount(INCOMPLETE));
- EXPECT_EQ(0, samples->GetCount(CONNECTED));
- EXPECT_EQ(0, samples->GetCount(FAILED));
}
-TEST_F(WebSocketStreamCreateTest, HandleErrConnectionClosed) {
+TEST_P(WebSocketStreamCreateTest, HandleErrConnectionClosed) {
+ base::HistogramTester histogram_tester;
+
static const char kTruncatedResponse[] =
"HTTP/1.1 101 Switching Protocols\r\n"
"Upgrade: websocket\r\n"
@@ -1223,7 +1562,7 @@ TEST_F(WebSocketStreamCreateTest, HandleErrConnectionClosed) {
"Cache-Control: no-sto";
std::string request =
- WebSocketStandardRequest("/", "localhost", LocalhostOrigin(), "", "");
+ WebSocketStandardRequest("/", "www.example.org", Origin(), "", "");
MockRead reads[] = {
MockRead(SYNCHRONOUS, 1, kTruncatedResponse),
MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 2),
@@ -1232,17 +1571,25 @@ TEST_F(WebSocketStreamCreateTest, HandleErrConnectionClosed) {
std::unique_ptr<SequencedSocketData> socket_data(
BuildSocketData(reads, writes));
socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
- CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), LocalhostUrl(), "",
+ CreateAndConnectRawExpectations("ws://www.example.org/", NoSubProtocols(), "",
std::move(socket_data));
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
+
+ stream_request_.reset();
+
+ auto samples = histogram_tester.GetHistogramSamplesSinceCreation(
+ "Net.WebSocket.HandshakeResult2");
+ EXPECT_EQ(1, samples->TotalCount());
+ EXPECT_EQ(1, samples->GetCount(static_cast<int>(
+ WebSocketHandshakeStreamBase::HandshakeResult::
+ FAILED_SWITCHING_PROTOCOLS)));
}
-TEST_F(WebSocketStreamCreateTest, HandleErrTunnelConnectionFailed) {
+TEST_P(WebSocketStreamCreateTest, HandleErrTunnelConnectionFailed) {
static const char kConnectRequest[] =
- "CONNECT localhost:80 HTTP/1.1\r\n"
- "Host: localhost:80\r\n"
+ "CONNECT www.example.org:80 HTTP/1.1\r\n"
+ "Host: www.example.org:80\r\n"
"Proxy-Connection: keep-alive\r\n"
"\r\n";
@@ -1259,8 +1606,7 @@ TEST_F(WebSocketStreamCreateTest, HandleErrTunnelConnectionFailed) {
std::unique_ptr<SequencedSocketData> socket_data(
BuildSocketData(reads, writes));
url_request_context_host_.SetProxyConfig("https=proxy:8000");
- CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(),
- LocalhostOrigin(), LocalhostUrl(), "",
+ CreateAndConnectRawExpectations("ws://www.example.org/", NoSubProtocols(), "",
std::move(socket_data));
WaitUntilConnectDone();
EXPECT_TRUE(has_failed());
diff --git a/chromium/net/websockets/websocket_test_util.cc b/chromium/net/websockets/websocket_test_util.cc
index 38499ed6802..ed8b9bedf0d 100644
--- a/chromium/net/websockets/websocket_test_util.cc
+++ b/chromium/net/websockets/websocket_test_util.cc
@@ -8,11 +8,14 @@
#include <algorithm>
#include <utility>
+#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
-#include "net/proxy_resolution/proxy_service.h"
+#include "net/http/http_network_session.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/socket/socket_test_util.h"
#include "net/spdy/core/spdy_protocol.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/websockets/websocket_basic_handshake_stream.h"
#include "url/origin.h"
@@ -36,6 +39,15 @@ uint32_t LinearCongruentialGenerator::Generate() {
return static_cast<uint32_t>(result >> 16);
}
+std::string WebSocketExtraHeadersToString(
+ const WebSocketExtraHeaders& headers) {
+ std::string answer;
+ for (const auto& header : headers) {
+ base::StrAppend(&answer, {header.first, ": ", header.second, "\r\n"});
+ }
+ return answer;
+}
+
std::string WebSocketStandardRequest(
const std::string& path,
const std::string& host,
@@ -139,8 +151,7 @@ struct WebSocketMockClientSocketFactoryMaker::Detail {
};
WebSocketMockClientSocketFactoryMaker::WebSocketMockClientSocketFactoryMaker()
- : detail_(new Detail) {
-}
+ : detail_(std::make_unique<Detail>()) {}
WebSocketMockClientSocketFactoryMaker::
~WebSocketMockClientSocketFactoryMaker() = default;
@@ -171,8 +182,8 @@ void WebSocketMockClientSocketFactoryMaker::SetExpectations(
kHttpStreamParserBufferSize),
sequence++));
}
- std::unique_ptr<SequencedSocketData> socket_data(new SequencedSocketData(
- detail_->reads.data(), detail_->reads.size(), &detail_->write, 1));
+ auto socket_data = std::make_unique<SequencedSocketData>(
+ detail_->reads.data(), detail_->reads.size(), &detail_->write, 1);
socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
AddRawExpectations(std::move(socket_data));
}
@@ -192,6 +203,12 @@ void WebSocketMockClientSocketFactoryMaker::AddSSLSocketDataProvider(
WebSocketTestURLRequestContextHost::WebSocketTestURLRequestContextHost()
: url_request_context_(true), url_request_context_initialized_(false) {
url_request_context_.set_client_socket_factory(maker_.factory());
+ auto params = std::make_unique<HttpNetworkSession::Params>();
+ params->enable_spdy_ping_based_connection_checking = false;
+ params->enable_quic = false;
+ params->enable_websocket_over_http2 = true;
+ params->disable_idle_sockets_close_on_memory_pressure = false;
+ url_request_context_.set_http_network_session_params(std::move(params));
}
WebSocketTestURLRequestContextHost::~WebSocketTestURLRequestContextHost() =
@@ -210,7 +227,8 @@ void WebSocketTestURLRequestContextHost::AddSSLSocketDataProvider(
void WebSocketTestURLRequestContextHost::SetProxyConfig(
const std::string& proxy_rules) {
DCHECK(!url_request_context_initialized_);
- proxy_resolution_service_ = ProxyResolutionService::CreateFixed(proxy_rules);
+ proxy_resolution_service_ = ProxyResolutionService::CreateFixed(
+ proxy_rules, TRAFFIC_ANNOTATION_FOR_TESTS);
url_request_context_.set_proxy_resolution_service(
proxy_resolution_service_.get());
}
diff --git a/chromium/net/websockets/websocket_test_util.h b/chromium/net/websockets/websocket_test_util.h
index a66262e035b..9e58406e559 100644
--- a/chromium/net/websockets/websocket_test_util.h
+++ b/chromium/net/websockets/websocket_test_util.h
@@ -45,6 +45,9 @@ class LinearCongruentialGenerator {
uint64_t current_;
};
+// Converts a vector of header key-value pairs into a single string.
+std::string WebSocketExtraHeadersToString(const WebSocketExtraHeaders& headers);
+
// Generates a standard WebSocket handshake request. The challenge key used is
// "dGhlIHNhbXBsZSBub25jZQ==". Each header in |extra_headers| must be terminated
// with "\r\n".